wallet refactoring.
This commit is contained in:
parent
8d0f432c7a
commit
2677b0eecd
@ -42,6 +42,7 @@ function Address(options) {
|
||||
this.keys = [];
|
||||
this.m = options.m || 1;
|
||||
this.n = options.n || 1;
|
||||
this.witness = options.witness || false;
|
||||
|
||||
if (this.n > 1)
|
||||
this.type = 'multisig';
|
||||
@ -60,10 +61,6 @@ function Address(options) {
|
||||
|
||||
utils.inherits(Address, EventEmitter);
|
||||
|
||||
Address.prototype.__defineGetter__('balance', function() {
|
||||
return this.getBalance();
|
||||
});
|
||||
|
||||
Address.prototype.getID = function getID() {
|
||||
return this.getKeyAddress();
|
||||
};
|
||||
@ -142,7 +139,7 @@ Address.prototype.getScript = function getScript() {
|
||||
redeem = bcoin.script.createMultisig(this.keys, this.m, this.n);
|
||||
redeem = bcoin.script.encode(redeem);
|
||||
|
||||
if (this.options.program) {
|
||||
if (this.witness) {
|
||||
if (redeem.length > 10000)
|
||||
throw new Error('Redeem script too large (10000 byte limit).');
|
||||
} else {
|
||||
@ -158,7 +155,7 @@ Address.prototype.getScript = function getScript() {
|
||||
Address.prototype.getProgram = function getProgram() {
|
||||
var program;
|
||||
|
||||
if (!this.options.program)
|
||||
if (!this.witness)
|
||||
return;
|
||||
|
||||
if (this._program)
|
||||
@ -169,7 +166,7 @@ Address.prototype.getProgram = function getProgram() {
|
||||
0, Address.hash160(this.getPublicKey()));
|
||||
} else if (this.type === 'multisig') {
|
||||
program = bcoin.script.createWitnessProgram(
|
||||
0, utils.sha256(this.getScript()));
|
||||
0, Address.sha256(this.getScript()));
|
||||
}
|
||||
|
||||
assert(program);
|
||||
@ -180,7 +177,7 @@ Address.prototype.getProgram = function getProgram() {
|
||||
};
|
||||
|
||||
Address.prototype.getProgramHash = function getProgramHash() {
|
||||
if (!this.options.program)
|
||||
if (!this.witness)
|
||||
return;
|
||||
|
||||
if (this._programHash)
|
||||
@ -192,7 +189,7 @@ Address.prototype.getProgramHash = function getProgramHash() {
|
||||
};
|
||||
|
||||
Address.prototype.getProgramAddress = function getProgramAddress() {
|
||||
if (!this.options.program)
|
||||
if (!this.witness)
|
||||
return;
|
||||
|
||||
if (this._programAddress)
|
||||
@ -238,7 +235,7 @@ Address.prototype.getScriptAddress = function getScriptAddress() {
|
||||
if (this._scriptAddress)
|
||||
return this._scriptAddress;
|
||||
|
||||
if (this.options.program)
|
||||
if (this.witness)
|
||||
this._scriptAddress = Address.compileHash(this.getScriptHash256(), 'witnessscripthash');
|
||||
else
|
||||
this._scriptAddress = Address.compileHash(this.getScriptHash160(), 'scripthash');
|
||||
@ -263,7 +260,7 @@ Address.prototype.getKeyAddress = function getKeyAddress() {
|
||||
if (this._address)
|
||||
return this._address;
|
||||
|
||||
if (this.options.program)
|
||||
if (this.witness)
|
||||
this._address = Address.compileHash(this.getKeyHash(), 'witnesspubkeyhash');
|
||||
else
|
||||
this._address = Address.compileHash(this.getKeyHash(), 'pubkeyhash');
|
||||
@ -294,7 +291,7 @@ Address.prototype._getAddressMap = function _getAddressMap() {
|
||||
if (this.type === 'multisig')
|
||||
this.addressMap[this.getScriptAddress()] = true;
|
||||
|
||||
if (this.options.program)
|
||||
if (this.witness)
|
||||
this.addressMap[this.getProgramAddress()] = true;
|
||||
|
||||
return this.addressMap;
|
||||
@ -660,6 +657,7 @@ Address.prototype.toJSON = function toJSON(passphrase) {
|
||||
address: this.getAddress(),
|
||||
key: key.toJSON(passphrase),
|
||||
type: this.type,
|
||||
witness: this.witness,
|
||||
redeem: this.redeem ? utils.toHex(this.redeem) : null,
|
||||
keys: this.keys.map(utils.toBase58),
|
||||
m: this.m,
|
||||
@ -684,6 +682,7 @@ Address.fromJSON = function fromJSON(json, passphrase) {
|
||||
path: json.path,
|
||||
key: bcoin.keypair.fromJSON(json.key, passphrase),
|
||||
type: json.type,
|
||||
witness: json.witness,
|
||||
redeem: json.redeem ? new Buffer(json.redeem, 'hex') : null,
|
||||
keys: json.keys.map(utils.fromBase58),
|
||||
m: json.m,
|
||||
|
||||
@ -259,64 +259,12 @@ Block.reward = function reward(height) {
|
||||
if (halvings >= 64)
|
||||
return new bn(0);
|
||||
|
||||
reward = new bn(50).mul(constants.coin);
|
||||
reward = new bn(5000000000);
|
||||
reward.iushrn(halvings);
|
||||
|
||||
return reward;
|
||||
};
|
||||
|
||||
Block.prototype._getReward = function _getReward() {
|
||||
var reward, base, fee, height;
|
||||
|
||||
if (this._reward)
|
||||
return this._reward;
|
||||
|
||||
base = Block.reward(this.height);
|
||||
|
||||
if (this.height === -1) {
|
||||
return this._reward = {
|
||||
fee: new bn(0),
|
||||
reward: base,
|
||||
base: base
|
||||
};
|
||||
}
|
||||
|
||||
reward = this.txs[0].outputs.reduce(function(total, output) {
|
||||
total.iadd(output.value);
|
||||
return total;
|
||||
}, new bn(0));
|
||||
|
||||
fee = reward.sub(base);
|
||||
|
||||
return this._reward = {
|
||||
fee: fee,
|
||||
reward: reward,
|
||||
base: base
|
||||
};
|
||||
};
|
||||
|
||||
Block.prototype.getBaseReward = function getBaseReward() {
|
||||
return this._getReward().base;
|
||||
};
|
||||
|
||||
Block.prototype.getReward = function getReward() {
|
||||
return this._getReward().reward;
|
||||
};
|
||||
|
||||
Block.prototype.getFee = function getFee() {
|
||||
return this._getReward().fee;
|
||||
};
|
||||
|
||||
Block.prototype.getCoinbase = function getCoinbase() {
|
||||
var tx;
|
||||
|
||||
tx = this.txs[0];
|
||||
if (!tx || !tx.isCoinbase())
|
||||
return;
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
Block.prototype.inspect = function inspect() {
|
||||
return {
|
||||
type: this.type,
|
||||
|
||||
@ -668,6 +668,11 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, flags, callbac
|
||||
tx = block.txs[i];
|
||||
hash = tx.hash('hex');
|
||||
|
||||
if (tx.getOutputValue().cmp(tx.getInputValue()) > 0) {
|
||||
utils.debug('TX is spending funds it does not have: %s', tx.rhash);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (j = 0; j < tx.inputs.length; j++) {
|
||||
input = tx.inputs[j];
|
||||
|
||||
@ -1853,18 +1858,12 @@ Chain.prototype.getSize = function getSize() {
|
||||
return this.db.getSize();
|
||||
};
|
||||
|
||||
// Legacy
|
||||
Chain.prototype.size = Chain.prototype.getSize;
|
||||
|
||||
Chain.prototype.getCurrentTarget = function getCurrentTarget() {
|
||||
if (!this.tip)
|
||||
return utils.toCompact(network.powLimit);
|
||||
return this.getTarget(this.tip);
|
||||
};
|
||||
|
||||
// Legacy
|
||||
Chain.prototype.currentTarget = Chain.prototype.getCurrentTarget;
|
||||
|
||||
Chain.prototype.getTarget = function getTarget(last, block) {
|
||||
var powLimit = utils.toCompact(network.powLimit);
|
||||
var ts, first, i;
|
||||
|
||||
@ -235,8 +235,8 @@ Input.prototype.inspect = function inspect() {
|
||||
height: -1,
|
||||
value: '0.0',
|
||||
script: '',
|
||||
hash: utils.toHex(constants.zeroHash),
|
||||
index: 0,
|
||||
hash: this.prevout.hash,
|
||||
index: this.prevout.index,
|
||||
spent: false,
|
||||
address: null
|
||||
};
|
||||
|
||||
@ -1233,7 +1233,7 @@ Pool.prototype.addWallet = function addWallet(wallet, callback) {
|
||||
// search, because search could add TS
|
||||
// to pending TXs, thus making them
|
||||
// confirmed.
|
||||
wallet.pending().forEach(function(tx) {
|
||||
wallet.getPending().forEach(function(tx) {
|
||||
self.sendTX(tx);
|
||||
});
|
||||
|
||||
|
||||
@ -411,11 +411,6 @@ TX.prototype.verify = function verify(index, force, flags) {
|
||||
if (this.isCoinbase())
|
||||
return true;
|
||||
|
||||
if (this.getOutputValue().cmp(this.getInputValue()) > 0) {
|
||||
utils.debug('TX is spending funds it does not have.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.inputs.every(function(input, i) {
|
||||
if (index != null && i !== index)
|
||||
return true;
|
||||
|
||||
@ -51,7 +51,7 @@ function Wallet(options) {
|
||||
this.labelMap = {};
|
||||
this.change = [];
|
||||
this.receive = [];
|
||||
this.program = options.program || false;
|
||||
this.witness = options.witness || false;
|
||||
|
||||
this.accountIndex = options.accountIndex || 0;
|
||||
this.receiveDepth = options.receiveDepth || 1;
|
||||
@ -357,7 +357,7 @@ Wallet.prototype.deriveAddress = function deriveAddress(change, index) {
|
||||
index: data.index,
|
||||
path: data.path,
|
||||
type: this.type,
|
||||
program: this.program,
|
||||
witness: this.witness,
|
||||
m: this.m,
|
||||
n: this.n,
|
||||
keys: [],
|
||||
@ -377,7 +377,7 @@ Wallet.prototype.deriveAddress = function deriveAddress(change, index) {
|
||||
if (this.type === 'multisig')
|
||||
this.addressMap[address.getScriptAddress()] = data.path;
|
||||
|
||||
if (this.program)
|
||||
if (this.witness)
|
||||
this.addressMap[address.getProgramAddress()] = data.path;
|
||||
|
||||
this.emit('add address', address);
|
||||
@ -821,12 +821,6 @@ Wallet.prototype.getBalance = function getBalance(address) {
|
||||
return this.tx.getBalance(address);
|
||||
};
|
||||
|
||||
// Legacy
|
||||
Wallet.prototype.all = Wallet.prototype.getAll;
|
||||
Wallet.prototype.unspent = Wallet.prototype.getUnspent;
|
||||
Wallet.prototype.pending = Wallet.prototype.getPending;
|
||||
Wallet.prototype.balance = Wallet.prototype.getBalance;
|
||||
|
||||
Wallet.prototype.__defineGetter__('script', function() {
|
||||
return this.getScript();
|
||||
});
|
||||
@ -835,10 +829,30 @@ Wallet.prototype.__defineGetter__('scriptHash', function() {
|
||||
return this.getScriptHash();
|
||||
});
|
||||
|
||||
Wallet.prototype.__defineGetter__('scriptHash160', function() {
|
||||
return this.getScriptHash160();
|
||||
});
|
||||
|
||||
Wallet.prototype.__defineGetter__('scriptHash256', function() {
|
||||
return this.getScriptHash256();
|
||||
});
|
||||
|
||||
Wallet.prototype.__defineGetter__('scriptAddress', function() {
|
||||
return this.getScriptAddress();
|
||||
});
|
||||
|
||||
// Wallet.prototype.__defineGetter__('program', function() {
|
||||
// return this.getProgram();
|
||||
// });
|
||||
|
||||
Wallet.prototype.__defineGetter__('programHash', function() {
|
||||
return this.getProgramHash();
|
||||
});
|
||||
|
||||
Wallet.prototype.__defineGetter__('programAddress', function() {
|
||||
return this.getProgramAddress();
|
||||
});
|
||||
|
||||
Wallet.prototype.__defineGetter__('privateKey', function() {
|
||||
return this.getPrivateKey();
|
||||
});
|
||||
@ -872,7 +886,7 @@ Wallet.prototype.toJSON = function toJSON(noPool) {
|
||||
type: this.type,
|
||||
m: this.m,
|
||||
n: this.n,
|
||||
program: this.program,
|
||||
witness: this.witness,
|
||||
derivation: this.derivation,
|
||||
copayBIP45: this.copayBIP45,
|
||||
accountIndex: this.accountIndex,
|
||||
@ -904,7 +918,7 @@ Wallet._fromJSON = function _fromJSON(json, passphrase) {
|
||||
type: json.type,
|
||||
m: json.m,
|
||||
n: json.n,
|
||||
program: json.program,
|
||||
witness: json.witness,
|
||||
derivation: json.derivation,
|
||||
copayBIP45: json.copayBIP45,
|
||||
accountIndex: json.accountIndex,
|
||||
|
||||
@ -38,13 +38,18 @@ describe('Wallet', function() {
|
||||
assert(!bcoin.address.validate('1KQ1wMNwXHUYj1nv2xzsRcKUH8gVFpTFUc'));
|
||||
});
|
||||
|
||||
function p2pkh(program, bullshitNesting) {
|
||||
function p2pkh(witness, bullshitNesting) {
|
||||
var flags = bcoin.protocol.constants.flags.STANDARD_VERIFY_FLAGS;
|
||||
|
||||
if (program)
|
||||
if (witness)
|
||||
flags |= bcoin.protocol.constants.flags.VERIFY_WITNESS;
|
||||
|
||||
var w = bcoin.wallet({ program: program });
|
||||
var w = bcoin.wallet({ witness: witness });
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.parse(w.getAddress()).type === 'witnesspubkeyhash');
|
||||
else
|
||||
assert(bcoin.address.parse(w.getAddress()).type === 'pubkeyhash');
|
||||
|
||||
// Input transcation
|
||||
var src = bcoin.mtx({
|
||||
@ -168,22 +173,22 @@ describe('Wallet', function() {
|
||||
w.addTX(fake);
|
||||
|
||||
w.addTX(t4);
|
||||
assert.equal(w.balance().toString(10), '22500');
|
||||
assert.equal(w.getBalance().toString(10), '22500');
|
||||
w.addTX(t1);
|
||||
assert.equal(w.balance().toString(10), '73000');
|
||||
assert.equal(w.getBalance().toString(10), '73000');
|
||||
w.addTX(t2);
|
||||
assert.equal(w.balance().toString(10), '47000');
|
||||
assert.equal(w.getBalance().toString(10), '47000');
|
||||
w.addTX(t3);
|
||||
assert.equal(w.balance().toString(10), '22000');
|
||||
assert.equal(w.getBalance().toString(10), '22000');
|
||||
w.addTX(f1);
|
||||
assert.equal(w.balance().toString(10), '11000');
|
||||
assert(w.all().some(function(tx) {
|
||||
assert.equal(w.getBalance().toString(10), '11000');
|
||||
assert(w.getAll().some(function(tx) {
|
||||
return tx.hash('hex') === f1.hash('hex');
|
||||
}));
|
||||
|
||||
var w2 = bcoin.wallet.fromJSON(w.toJSON());
|
||||
assert.equal(w2.balance().toString(10), '11000');
|
||||
assert(w2.all().some(function(tx) {
|
||||
assert.equal(w2.getBalance().toString(10), '11000');
|
||||
assert(w2.getAll().some(function(tx) {
|
||||
return tx.hash('hex') === f1.hash('hex');
|
||||
}));
|
||||
});
|
||||
@ -246,8 +251,8 @@ describe('Wallet', function() {
|
||||
var cost = tx.getOutputValue();
|
||||
var total = cost.add(new bn(constants.tx.minFee));
|
||||
|
||||
var unspent1 = w1.unspent();
|
||||
var unspent2 = w2.unspent();
|
||||
var unspent1 = w1.getUnspent();
|
||||
var unspent2 = w2.getUnspent();
|
||||
|
||||
// Add dummy output (for `left`) to calculate maximum TX size
|
||||
tx.addOutput(w1, new bn(0));
|
||||
@ -288,15 +293,15 @@ describe('Wallet', function() {
|
||||
cb();
|
||||
});
|
||||
|
||||
function multisig(program, bullshitNesting, cb) {
|
||||
function multisig(witness, bullshitNesting, cb) {
|
||||
var flags = bcoin.protocol.constants.flags.STANDARD_VERIFY_FLAGS;
|
||||
|
||||
if (program)
|
||||
if (witness)
|
||||
flags |= bcoin.protocol.constants.flags.VERIFY_WITNESS;
|
||||
|
||||
// Create 3 2-of-3 wallets with our pubkeys as "shared keys"
|
||||
var w1 = bcoin.wallet({
|
||||
program: program,
|
||||
witness: witness,
|
||||
derivation: 'bip44',
|
||||
type: 'multisig',
|
||||
m: 2,
|
||||
@ -304,7 +309,7 @@ describe('Wallet', function() {
|
||||
});
|
||||
|
||||
var w2 = bcoin.wallet({
|
||||
program: program,
|
||||
witness: witness,
|
||||
derivation: 'bip44',
|
||||
type: 'multisig',
|
||||
m: 2,
|
||||
@ -312,7 +317,7 @@ describe('Wallet', function() {
|
||||
});
|
||||
|
||||
var w3 = bcoin.wallet({
|
||||
program: program,
|
||||
witness: witness,
|
||||
derivation: 'bip44',
|
||||
type: 'multisig',
|
||||
m: 2,
|
||||
@ -332,6 +337,12 @@ describe('Wallet', function() {
|
||||
|
||||
// Our p2sh address
|
||||
var addr = w1.getAddress();
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.parse(addr).type === 'witnessscripthash');
|
||||
else
|
||||
assert(bcoin.address.parse(addr).type === 'scripthash');
|
||||
|
||||
assert.equal(w1.getAddress(), addr);
|
||||
assert.equal(w2.getAddress(), addr);
|
||||
assert.equal(w3.getAddress(), addr);
|
||||
@ -410,7 +421,7 @@ describe('Wallet', function() {
|
||||
assert.equal(w2.changeAddress.getAddress(), change);
|
||||
assert.equal(w3.changeAddress.getAddress(), change);
|
||||
|
||||
if (program)
|
||||
if (witness)
|
||||
send.inputs[0].witness[2] = new Buffer([]);
|
||||
else
|
||||
send.inputs[0].script[2] = 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user