From 6f4609792fd6dc85b46e438bcef0252f05f1728e Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 16 Jan 2016 23:48:18 -0800 Subject: [PATCH] regtest support. tx methods. --- lib/bcoin/chain.js | 2 +- lib/bcoin/pool.js | 12 ++++ lib/bcoin/protocol/network.js | 103 +++++++++++++++++++++++++++++++++- lib/bcoin/script.js | 2 +- lib/bcoin/tx.js | 51 +++++++++++++++++ 5 files changed, 165 insertions(+), 5 deletions(-) diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 0f90247c..5d2c3850 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -389,7 +389,7 @@ Chain.prototype.add = function add(block, peer) { // Do "contextual" verification on our block // now that we're certain its previous // block is in the chain. - if (0) + // if (0) if (!block.postVerify()) { throw new Error; code = Chain.codes.invalid; diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index 482504fb..69dda176 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -1373,6 +1373,18 @@ Pool.prototype.getTX = function getTX(hash, range, cb) { }; Pool.prototype.sendTX = function sendTX(tx) { + // This is to avoid getting banned by + // bitcoind nodes. Possibly check + // sigops. Call isStandard and/or + // isStandardInputs as well. + if (tx.full()) { + if (!tx.verify(null, true)) { + this.emit('debug', + 'Could not relay TX (%s). It does not verify.', + tx.rhash); + return; + } + } return this.broadcast(tx); }; diff --git a/lib/bcoin/protocol/network.js b/lib/bcoin/protocol/network.js index 9e264262..da44202b 100644 --- a/lib/bcoin/protocol/network.js +++ b/lib/bcoin/protocol/network.js @@ -13,7 +13,7 @@ var utils = bcoin.utils; */ var network = exports; -var main, testnet; +var main, testnet, regtest; network.set = function set(type) { var net = network[type]; @@ -115,7 +115,7 @@ main.preload = { { hash: utils.toHex(main.genesis._hash), version: main.genesis.version, - // prevBlock: utils.toHex(main.genesis.prevBlock), + prevBlock: utils.toHex(main.genesis.prevBlock), ts: main.genesis.ts, bits: main.genesis.bits, height: 0 @@ -230,7 +230,7 @@ testnet.preload = { { hash: utils.toHex(testnet.genesis._hash), version: testnet.genesis.version, - // prevBlock: utils.toHex(testnet.genesis.prevBlock), + prevBlock: utils.toHex(testnet.genesis.prevBlock), ts: testnet.genesis.ts, bits: testnet.genesis.bits, height: 0 @@ -262,3 +262,100 @@ testnet.block = { majorityRejectOutdated: 75, majorityWindow: 100 }; + +/** + * Regtest + */ + +regtest = network.regtest = {}; + +regtest.type = 'testnet'; + +regtest.prefixes = { + pubkey: 111, + pubkeyhash: 111, + multisig: 111, + scripthash: 196, + privkey: 239, + xpubkey: 0x043587cf, + xprivkey: 0x04358394 +}; + +regtest.seeds = [ + '127.0.0.1' +]; + +regtest.port = 18444; + +regtest._alertKey = bcoin.ecdsa.genKeyPair(); +regtest.alertKey = regtest._alertKey.getPublic(true, 'array'); + +regtest.checkpoints = {}; +regtest.checkpoints.tsLastCheckpoint = 0; +regtest.checkpoints.txsLastCheckpoint = 0; +regtest.checkpoints.txsPerDay = 300; +regtest.checkpoints.lastHeight = 0; + +regtest.halvingInterval = 150; + +regtest.genesis = { + version: 1, + _hash: utils.toArray( + '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206', + 'hex' + ).reverse(), + prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 ], + merkleRoot: utils.toArray( + '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b', + 'hex' + ).reverse(), + ts: 1296688602, + bits: 0x207fffff, + nonce: 2 +}; + +regtest.magic = 0xdab5bffa; + +regtest.preload = { + v: 2, + type: 'chain', + network: regtest.type, + entries: [ + { + hash: utils.toHex(regtest.genesis._hash), + version: regtest.genesis.version, + prevBlock: utils.toHex(regtest.genesis.prevBlock), + ts: regtest.genesis.ts, + bits: regtest.genesis.bits, + height: 0 + } + ] +}; + +try { + regtest._preload = require('./preload-regtest'); + utils.assert(regtest._preload.entries[0]); + regtest.preload = regtest._preload; + delete regtest._preload; +} catch (e) { + delete regtest._preload; +} + +regtest.powLimit = new bn( + '7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + 'hex' +); +regtest.powTargetTimespan = 14 * 24 * 60 * 60; // two weeks +regtest.powTargetSpacing = 10 * 60; +regtest.powDiffInterval = regtest.powTargetTimespan / regtest.powTargetSpacing | 0; +regtest.powAllowMinDifficultyBlocks = true; +regtest.powNoRetargeting = true; + +regtest.block = { + majorityEnforceUpgrade: 750, + majorityRejectOutdated: 950, + majorityWindow: 1000 +}; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index bbe19b90..7e2c84da 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -1142,7 +1142,7 @@ script.getInputData = function getInputData(s) { var sig, key, hash, raw, redeem, lock, hash, address, input, output; if (script.isPubkeyInput(s)) { - key = s[0]; + sig = s[0]; return { type: 'pubkey', side: 'input', diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index 1807cff1..bc385c44 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -450,6 +450,49 @@ TX.prototype.signInput = function signInput(index, key, type) { return signatures === m; }; +TX.prototype.prevOut = function outputScript(i) { + var input; + + if (typeof i !== 'number') + i = this.inputs.indexOf(i); + + input = this.inputs[i]; + + if (!input.out.tx) + return; + + return input.out.tx.outputs[input.out.index]; +}; + +TX.prototype.outputScript = function outputScript(i) { + var output = this.prevOut(i); + if (!output) + return; + return output.script; +}; + +bcoin.script.redeemScript = function redeemScript(s) { + if (!Array.isArray(s[s.length - 1])) + return; + + return bcoin.script.decode(s[s.length - 1]); +}; + +TX.prototype.redeemScript = function redeemScript(i) { + var input, prev; + + if (typeof i !== 'number') + i = this.inputs.indexOf(i); + + input = this.inputs[i]; + prev = this.outputScript(i); + + if (prev && bcoin.script.isScripthash(prev)) + return bcoin.script.redeemScript(input.script); + + return prev; +}; + TX.prototype.finalize = function finalize() { var i, input, s, len, j; for (i = 0; i < this.inputs.length; i++) { @@ -1072,6 +1115,14 @@ TX.prototype.funds = function funds(side) { return acc; }; +TX.prototype.full = function full() { + if (this.inputs.length === 0) + return false; + return this.inputs.every(function(input) { + return !!input.out.tx; + }); +}; + TX.prototype.fill = function fill(txs) { var inputs;