wallet: all async methods.

This commit is contained in:
Christopher Jeffrey 2017-10-17 12:20:24 -07:00
parent c6d7c43485
commit c16e85e485
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
7 changed files with 347 additions and 302 deletions

View File

@ -49,10 +49,6 @@ function Account(wdb, options) {
this.wdb = wdb;
this.network = wdb.network;
this.receive = null;
this.change = null;
this.nested = null;
this.wid = 0;
this.id = null;
this.name = null;
@ -242,27 +238,6 @@ Account.prototype.init = async function init(b) {
await this.initDepth(b);
};
/**
* Open the account (done after retrieval).
* @returns {Promise}
*/
Account.prototype.open = function open() {
if (!this.initialized)
return Promise.resolve();
if (this.receive)
return Promise.resolve();
this.receive = this.deriveReceive(this.receiveDepth - 1);
this.change = this.deriveChange(this.changeDepth - 1);
if (this.witness)
this.nested = this.deriveNested(this.nestedDepth - 1);
return Promise.resolve();
};
/**
* Add a public account key to the account (multisig).
* Does not update the database.
@ -600,10 +575,9 @@ Account.prototype.savePath = function savePath(b, path) {
Account.prototype.initDepth = async function initDepth(b) {
// Receive Address
this.receive = this.deriveReceive(0);
this.receiveDepth = 1;
await this.saveKey(b, this.receive);
await this.saveKey(b, this.deriveReceive(0));
// Lookahead
for (let i = 0; i < this.lookahead; i++) {
@ -612,10 +586,9 @@ Account.prototype.initDepth = async function initDepth(b) {
}
// Change Address
this.change = this.deriveChange(0);
this.changeDepth = 1;
await this.saveKey(b, this.change);
await this.saveKey(b, this.deriveChange(0));
// Lookahead
for (let i = 0; i < this.lookahead; i++) {
@ -625,10 +598,9 @@ Account.prototype.initDepth = async function initDepth(b) {
// Nested Address
if (this.witness) {
this.nested = this.deriveNested(0);
this.nestedDepth = 1;
await this.saveKey(b, this.nested);
await this.saveKey(b, this.deriveNested(0));
// Lookahead
for (let i = 0; i < this.lookahead; i++) {
@ -722,15 +694,11 @@ Account.prototype.setLookahead = async function setLookahead(b, lookahead) {
const diff = this.lookahead - lookahead;
this.receiveDepth += diff;
this.receive = this.deriveReceive(this.receiveDepth - 1);
this.changeDepth += diff;
this.change = this.deriveChange(this.changeDepth - 1);
if (this.witness) {
if (this.witness)
this.nestedDepth += diff;
this.nested = this.deriveNested(this.nestedDepth - 1);
}
this.lookahead = lookahead;
@ -774,51 +742,84 @@ Account.prototype.setLookahead = async function setLookahead(b, lookahead) {
};
/**
* Get current receive address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* Get current receive key.
* @returns {WalletKey}
*/
Account.prototype.getAddress = function getAddress(enc) {
return this.getReceive(enc);
Account.prototype.receiveKey = function receiveKey() {
if (!this.initialized)
return null;
return this.deriveReceive(this.receiveDepth - 1);
};
/**
* Get current change key.
* @returns {WalletKey}
*/
Account.prototype.changeKey = function changeKey() {
if (!this.initialized)
return null;
return this.deriveChange(this.changeDepth - 1);
};
/**
* Get current nested key.
* @returns {WalletKey}
*/
Account.prototype.nestedKey = function nestedKey() {
if (!this.initialized)
return null;
if (!this.witness)
return null;
return this.deriveNested(this.nestedDepth - 1);
};
/**
* Get current receive address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @returns {Address}
*/
Account.prototype.getReceive = function getReceive(enc) {
if (!this.receive)
Account.prototype.receiveAddress = function receiveAddress() {
const key = this.receiveKey();
if (!key)
return null;
return this.receive.getAddress(enc);
return key.getAddress();
};
/**
* Get current change address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @returns {Address}
*/
Account.prototype.getChange = function getChange(enc) {
if (!this.change)
Account.prototype.changeAddress = function changeAddress() {
const key = this.changeKey();
if (!key)
return null;
return this.change.getAddress(enc);
return key.getAddress();
};
/**
* Get current nested address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @returns {Address}
*/
Account.prototype.getNested = function getNested(enc) {
if (!this.nested)
Account.prototype.nestedAddress = function nestedAddress() {
const key = this.nestedKey();
if (!key)
return null;
return this.nested.getAddress(enc);
return key.getAddress();
};
/**
@ -842,16 +843,11 @@ Account.prototype.inspect = function inspect() {
changeDepth: this.changeDepth,
nestedDepth: this.nestedDepth,
lookahead: this.lookahead,
address: this.initialized
? this.receive.getAddress()
: null,
nestedAddress: this.initialized && this.nested
? this.nested.getAddress()
: null,
receiveAddress: this.receiveAddress(),
changeAddress: this.changeAddress(),
nestedAddress: this.nestedAddress(),
accountKey: this.accountKey.toBase58(),
keys: this.keys.map((key) => {
return key.toBase58();
})
keys: this.keys.map(key => key.toBase58())
};
};
@ -862,6 +858,10 @@ Account.prototype.inspect = function inspect() {
*/
Account.prototype.toJSON = function toJSON(minimal) {
const receive = this.receiveAddress();
const change = this.changeAddress();
const nested = this.nestedAddress();
return {
wid: minimal ? undefined : this.wid,
id: minimal ? undefined : this.id,
@ -877,19 +877,11 @@ Account.prototype.toJSON = function toJSON(minimal) {
changeDepth: this.changeDepth,
nestedDepth: this.nestedDepth,
lookahead: this.lookahead,
receiveAddress: this.receive
? this.receive.getAddress('string')
: null,
nestedAddress: this.nested
? this.nested.getAddress('string')
: null,
changeAddress: this.change
? this.change.getAddress('string')
: null,
receiveAddress: receive ? receive.toString() : null,
changeAddress: change ? change.toString() : null,
nestedAddress: nested ? nested.toString() : null,
accountKey: this.accountKey.toBase58(),
keys: this.keys.map((key) => {
return key.toBase58();
})
keys: this.keys.map(key => key.toBase58())
};
};

View File

@ -308,7 +308,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const passphrase = valid.str('passphrase');
const old = valid.str('old');
enforce(old || new_, 'Passphrase is required.');
enforce(passphrase, 'Passphrase is required.');
await req.wallet.setPassphrase(passphrase, old);
@ -715,7 +715,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const result = [];
for (const item of details)
result.push(item.toJSON());
result.push(item.toJSON(this.network));
res.send(200, result);
});
@ -732,7 +732,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const result = [];
for (const item of details)
result.push(item.toJSON());
result.push(item.toJSON(this.network));
res.send(200, result);
});
@ -754,7 +754,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const result = [];
for (const item of details)
result.push(item.toJSON());
result.push(item.toJSON(this.network));
res.send(200, result);
});
@ -769,7 +769,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
const result = [];
for (const item of details)
result.push(item.toJSON());
result.push(item.toJSON(this.network));
res.send(200, result);
});

View File

@ -19,7 +19,6 @@ const records = require('./records');
const layout = require('./layout').txdb;
const encoding = require('../utils/encoding');
const policy = require('../protocol/policy');
const Script = require('../script/script');
const TXRecord = records.TXRecord;
/**

View File

@ -13,7 +13,6 @@ const Network = require('../protocol/network');
const util = require('../utils/util');
const encoding = require('../utils/encoding');
const Lock = require('../utils/lock');
const MappedLock = require('../utils/mappedlock');
const digest = require('../crypto/digest');
const cleanse = require('../crypto/cleanse');
const BufferReader = require('../utils/reader');
@ -85,7 +84,6 @@ function Wallet(wdb, options) {
this.master = new MasterKey();
this.txdb = new TXDB(this.wdb);
this.account = null;
if (options)
this.fromOptions(options);
@ -198,8 +196,6 @@ Wallet.prototype.init = async function init(options) {
const account = await this._createAccount(options, passphrase);
assert(account);
this.account = account;
this.logger.info('Wallet initialized (%s).', this.id);
await this.txdb.open(this);
@ -218,8 +214,6 @@ Wallet.prototype.open = async function open() {
if (!account)
throw new Error('Default account not found.');
this.account = account;
this.logger.info('Wallet opened (%s).', this.id);
await this.txdb.open(this);
@ -723,11 +717,6 @@ Wallet.prototype.getAccountHashes = async function getAccountHashes(acct) {
*/
Wallet.prototype.getAccount = async function getAccount(acct) {
if (this.account) {
if (acct === 0 || acct === 'default')
return this.account;
}
const index = await this.getAccountIndex(acct);
if (index === -1)
@ -742,8 +731,6 @@ Wallet.prototype.getAccount = async function getAccount(acct) {
account.id = this.id;
account.watchOnly = this.watchOnly;
await account.open();
return account;
};
@ -1162,17 +1149,11 @@ Wallet.prototype._fund = async function _fund(mtx, options) {
if (this.watchOnly)
throw new Error('Cannot fund from watch-only wallet.');
let account;
if (options.account != null) {
account = await this.getAccount(options.account);
if (!account)
throw new Error('Account not found.');
} else {
account = this.account;
}
const acct = options.account || 0;
const change = await this.changeAddress(acct);
if (!account.initialized)
throw new Error('Account is not initialized.');
if (!change)
throw new Error('Account not found.');
let rate = options.rate;
if (rate == null)
@ -1193,7 +1174,7 @@ Wallet.prototype._fund = async function _fund(mtx, options) {
hardFee: options.hardFee,
subtractFee: options.subtractFee,
subtractIndex: options.subtractIndex,
changeAddress: account.change.getAddress(),
changeAddress: change,
height: this.wdb.state.height,
rate: rate,
maxFee: options.maxFee,
@ -2155,43 +2136,133 @@ Wallet.prototype.getLast = async function getLast(acct, limit) {
};
/**
* Get current receive address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* Get account key.
* @param {Number} [acct=0]
* @returns {HDPublicKey}
*/
Wallet.prototype.getAddress = function getAddress(enc) {
return this.account.getAddress(enc);
Wallet.prototype.accountKey = async function accountKey(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.accountKey;
};
/**
* Get current receive depth.
* @param {Number} [acct=0]
* @returns {Number}
*/
Wallet.prototype.receiveDepth = async function receiveDepth(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.receiveDepth;
};
/**
* Get current change depth.
* @param {Number} [acct=0]
* @returns {Number}
*/
Wallet.prototype.changeDepth = async function changeDepth(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.changeDepth;
};
/**
* Get current nested depth.
* @param {Number} [acct=0]
* @returns {Number}
*/
Wallet.prototype.nestedDepth = async function nestedDepth(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.nestedDepth;
};
/**
* Get current receive address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @param {Number} [acct=0]
* @returns {Address}
*/
Wallet.prototype.getReceive = function getReceive(enc) {
return this.account.getReceive(enc);
Wallet.prototype.receiveAddress = async function receiveAddress(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.receiveAddress();
};
/**
* Get current change address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @param {Number} [acct=0]
* @returns {Address}
*/
Wallet.prototype.getChange = function getChange(enc) {
return this.account.getChange(enc);
Wallet.prototype.changeAddress = async function changeAddress(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.changeAddress();
};
/**
* Get current nested address.
* @param {String?} enc - `"base58"` or `null`.
* @returns {Address|Base58Address}
* @param {Number} [acct=0]
* @returns {Address}
*/
Wallet.prototype.getNested = function getNested(enc) {
return this.account.getNested(enc);
Wallet.prototype.nestedAddress = async function nestedAddress(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.nestedAddress();
};
/**
* Get current receive key.
* @param {Number} [acct=0]
* @returns {WalletKey}
*/
Wallet.prototype.receiveKey = async function receiveKey(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.receiveKey();
};
/**
* Get current change key.
* @param {Number} [acct=0]
* @returns {WalletKey}
*/
Wallet.prototype.changeKey = async function changeKey(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.changeKey();
};
/**
* Get current nested key.
* @param {Number} [acct=0]
* @returns {WalletKey}
*/
Wallet.prototype.nestedKey = async function nestedKey(acct = 0) {
const account = await this.getAccount(acct);
if (!account)
throw new Error('Account not found.');
return account.nestedKey();
};
/**
@ -2209,8 +2280,7 @@ Wallet.prototype.inspect = function inspect() {
token: this.token.toString('hex'),
tokenDepth: this.tokenDepth,
state: this.txdb.state ? this.txdb.state.toJSON(true) : null,
master: this.master,
account: this.account
master: this.master
};
};
@ -2233,8 +2303,7 @@ Wallet.prototype.toJSON = function toJSON(unsafe) {
token: this.token.toString('hex'),
tokenDepth: this.tokenDepth,
state: this.txdb.state.toJSON(true),
master: this.master.toJSON(unsafe),
account: this.account.toJSON(true)
master: this.master.toJSON(unsafe)
};
};

View File

@ -136,7 +136,7 @@ WalletDB.prototype._open = async function _open() {
await this.logger.open();
await this.db.open();
await this.db.checkVersion('V', 6);
await this.db.checkVersion('V', 7);
this.depth = await this.getDepth();
@ -157,7 +157,7 @@ WalletDB.prototype._open = async function _open() {
this.logger.info(
'Loaded primary wallet (id=%s, wid=%d, address=%s)',
wallet.id, wallet.wid, wallet.getAddress());
wallet.id, wallet.wid, await wallet.receiveAddress());
this.primary = wallet;
this.rpc.wallet = wallet;
@ -1299,15 +1299,14 @@ WalletDB.prototype.decryptKeys = async function decryptKeys(b, wid, key) {
*/
WalletDB.prototype.resend = async function resend() {
const keys = await this.db.keys({
const wids = await this.db.keys({
gte: layout.w(0x00000000),
lte: layout.w(0xffffffff)
lte: layout.w(0xffffffff),
parse: k => layout.ww(k)
});
for (const key of keys) {
const wid = layout.ww(key);
for (const wid of wids)
await this.resendPending(wid);
}
};
/**
@ -1319,26 +1318,27 @@ WalletDB.prototype.resend = async function resend() {
WalletDB.prototype.resendPending = async function resendPending(wid) {
const layout = layouts.txdb;
const prefix = layout.prefix(wid);
const b = this.db.bucket(prefix);
const keys = await this.db.keys({
gte: layout.prefix(wid, layout.p(encoding.NULL_HASH)),
lte: layout.prefix(wid, layout.p(encoding.HIGH_HASH))
const hashes = await b.keys({
gte: layout.p(encoding.NULL_HASH),
lte: layout.p(encoding.HIGH_HASH),
parse: k => layout.pp(k)
});
if (keys.length === 0)
if (hashes.length === 0)
return;
this.logger.info(
'Rebroadcasting %d transactions for %d.',
keys.length,
hashes.length,
wid);
const txs = [];
for (const key of keys) {
const hash = layout.pp(key);
const tkey = layout.prefix(wid, layout.t(hash));
const data = await this.db.get(tkey);
for (const hash of hashes) {
const data = await b.get(layout.t(hash));
if (!data)
continue;
@ -1718,7 +1718,7 @@ WalletDB.prototype.rollback = async function rollback(height) {
if (height === this.state.height) {
this.logger.debug('Rolled back to same height (%d).', height);
return true;
return;
}
this.logger.info(
@ -1730,8 +1730,6 @@ WalletDB.prototype.rollback = async function rollback(height) {
await this.revert(tip.height);
await this.syncState(tip);
return true;
};
/**
@ -2011,13 +2009,7 @@ WalletDB.prototype._resetChain = async function _resetChain(entry) {
if (entry.height > this.state.height)
throw new Error('WDB: Bad reset height.');
// Try to rollback.
if (await this.rollback(entry.height))
return;
// If we rolled back to the
// start block, we need a rescan.
await this.scan();
await this.rollback(entry.height);
};
/**

View File

@ -44,8 +44,8 @@ async function mineBlock(tip, tx) {
spend.addTX(tx, 0);
spend.addOutput(wallet.getReceive(), 25 * 1e8);
spend.addOutput(wallet.getChange(), 5 * 1e8);
spend.addOutput(await wallet.receiveAddress(), 25 * 1e8);
spend.addOutput(await wallet.changeAddress(), 5 * 1e8);
spend.setLocktime(chain.height);
@ -94,7 +94,7 @@ describe('Node', function() {
it('should open walletdb', async () => {
wallet = await wdb.create();
miner.addresses.length = 0;
miner.addAddress(wallet.getReceive());
miner.addAddress(await wallet.receiveAddress());
});
it('should mine a block', async () => {
@ -258,8 +258,8 @@ describe('Node', function() {
assert.strictEqual(balance.unconfirmed, 1250 * 1e8);
assert.strictEqual(balance.confirmed, 750 * 1e8);
assert(wallet.account.receiveDepth >= 7);
assert(wallet.account.changeDepth >= 6);
assert((await wallet.receiveDepth()) >= 7);
assert((await wallet.changeDepth()) >= 6);
assert.strictEqual(wdb.state.height, chain.height);
@ -447,7 +447,7 @@ describe('Node', function() {
it('should rescan for transactions', async () => {
await wdb.rescan(0);
assert.strictEqual(wallet.txdb.state.confirmed, 1289250000000);
assert.strictEqual((await wallet.getBalance()).confirmed, 1289250000000);
});
it('should reset miner mempool', async () => {
@ -572,7 +572,7 @@ describe('Node', function() {
rate: 100000,
outputs: [{
value: 100000,
address: wallet.getAddress()
address: await wallet.receiveAddress()
}]
});
@ -582,7 +582,7 @@ describe('Node', function() {
const tx = mtx.toTX();
await wallet.wdb.addTX(tx);
await wdb.addTX(tx);
const missing = await node.mempool.addTX(tx);
assert(!missing);
@ -597,7 +597,7 @@ describe('Node', function() {
rate: 1000,
outputs: [{
value: 50000,
address: wallet.getAddress()
address: await wallet.receiveAddress()
}]
});
@ -607,7 +607,7 @@ describe('Node', function() {
const tx = mtx.toTX();
await wallet.wdb.addTX(tx);
await wdb.addTX(tx);
const missing = await node.mempool.addTX(tx);
assert(!missing);

View File

@ -37,11 +37,6 @@ let importedKey = null;
let doubleSpendWallet = null;
let doubleSpendCoin = null;
function prevBlock(wdb) {
assert(wdb.state.height > 0);
return fakeBlock(wdb.state.height - 1);
};
function curBlock(wdb) {
return fakeBlock(wdb.state.height);
};
@ -73,21 +68,24 @@ function dummyInput() {
async function testP2PKH(witness, nesting) {
const flags = Script.flags.STANDARD_VERIFY_FLAGS;
const receiveAddress = nesting ? 'nestedAddress' : 'receiveAddress';
const type = witness ? Address.types.WITNESS : Address.types.PUBKEYHASH;
const wallet = await wdb.create({ witness });
const addr = Address.fromString(wallet.getAddress('string'));
const waddr = await wallet.receiveAddress();
const addr = Address.fromString(waddr.toString());
const type = witness ? Address.types.WITNESS : Address.types.PUBKEYHASH;
assert.strictEqual(addr.type, type);
assert.strictEqual(addr.type, waddr.type);
const src = new MTX();
src.addInput(dummyInput());
src.addOutput(nesting ? wallet.getNested() : wallet.getAddress(), 5460 * 2);
src.addOutput(await wallet[receiveAddress](), 5460 * 2);
src.addOutput(new Address(), 2 * 5460);
const mtx = new MTX();
mtx.addTX(src, 0);
mtx.addOutput(wallet.getAddress(), 5460);
mtx.addOutput(await wallet.receiveAddress(), 5460);
await wallet.sign(mtx);
@ -98,7 +96,7 @@ async function testP2PKH(witness, nesting) {
async function testP2SH(witness, nesting) {
const flags = Script.flags.STANDARD_VERIFY_FLAGS;
const receive = nesting ? 'nested' : 'receive';
const receiveAddress = nesting ? 'nestedAddress' : 'receiveAddress';
const receiveDepth = nesting ? 'nestedDepth' : 'receiveDepth';
const vector = witness ? 'witness' : 'script';
@ -115,17 +113,17 @@ async function testP2SH(witness, nesting) {
const carol = await wdb.create(options);
const recipient = await wdb.create();
await alice.addSharedKey(0, bob.account.accountKey);
await alice.addSharedKey(0, carol.account.accountKey);
await alice.addSharedKey(0, await bob.accountKey(0));
await alice.addSharedKey(0, await carol.accountKey(0));
await bob.addSharedKey(0, alice.account.accountKey);
await bob.addSharedKey(0, carol.account.accountKey);
await bob.addSharedKey(0, await alice.accountKey(0));
await bob.addSharedKey(0, await carol.accountKey(0));
await carol.addSharedKey(0, alice.account.accountKey);
await carol.addSharedKey(0, bob.account.accountKey);
await carol.addSharedKey(0, await alice.accountKey(0));
await carol.addSharedKey(0, await bob.accountKey(0));
// Our p2sh address
const addr1 = alice.account[receive].getAddress();
const addr1 = await alice[receiveAddress]();
if (witness) {
const type = nesting ? Address.types.SCRIPTHASH : Address.types.WITNESS;
@ -134,17 +132,17 @@ async function testP2SH(witness, nesting) {
assert.strictEqual(addr1.type, Address.types.SCRIPTHASH);
}
assert(alice.account[receive].getAddress().equals(addr1));
assert(bob.account[receive].getAddress().equals(addr1));
assert(carol.account[receive].getAddress().equals(addr1));
assert((await alice[receiveAddress]()).equals(addr1));
assert((await bob[receiveAddress]()).equals(addr1));
assert((await carol[receiveAddress]()).equals(addr1));
const nestedAddr1 = alice.getNested();
const nestedAddr1 = await alice.nestedAddress();
if (witness) {
assert(nestedAddr1);
assert(alice.getNested().equals(nestedAddr1));
assert(bob.getNested().equals(nestedAddr1));
assert(carol.getNested().equals(nestedAddr1));
assert((await alice.nestedAddress()).equals(nestedAddr1));
assert((await bob.nestedAddress()).equals(nestedAddr1));
assert((await carol.nestedAddress()).equals(nestedAddr1));
}
{
@ -154,25 +152,25 @@ async function testP2SH(witness, nesting) {
fund.addOutput(nesting ? nestedAddr1 : addr1, 5460 * 10);
// Simulate a confirmation
assert.strictEqual(alice.account[receiveDepth], 1);
assert.strictEqual(await alice[receiveDepth](), 1);
await wdb.addBlock(nextBlock(wdb), [fund.toTX()]);
assert.strictEqual(alice.account[receiveDepth], 2);
assert.strictEqual(alice.account.changeDepth, 1);
assert.strictEqual(await alice[receiveDepth](), 2);
assert.strictEqual(await alice.changeDepth(), 1);
}
const addr2 = alice.account[receive].getAddress();
const addr2 = await alice[receiveAddress]();
assert(!addr2.equals(addr1));
assert(alice.account[receive].getAddress().equals(addr2));
assert(bob.account[receive].getAddress().equals(addr2));
assert(carol.account[receive].getAddress().equals(addr2));
assert((await alice[receiveAddress]()).equals(addr2));
assert((await bob[receiveAddress]()).equals(addr2));
assert((await carol[receiveAddress]()).equals(addr2));
// Create a tx requiring 2 signatures
const send = new MTX();
send.addOutput(recipient.getAddress(), 5460);
send.addOutput(await recipient.receiveAddress(), 5460);
assert(!send.verify(flags));
@ -190,30 +188,30 @@ async function testP2SH(witness, nesting) {
const [tx, view] = send.commit();
assert(tx.verify(view, flags));
assert.strictEqual(alice.account.changeDepth, 1);
assert.strictEqual(await alice.changeDepth(), 1);
const change = alice.account.change.getAddress();
const change = await alice.changeAddress();
assert(alice.account.change.getAddress().equals(change));
assert(bob.account.change.getAddress().equals(change));
assert(carol.account.change.getAddress().equals(change));
assert((await alice.changeAddress()).equals(change));
assert((await bob.changeAddress()).equals(change));
assert((await carol.changeAddress()).equals(change));
// Simulate a confirmation
{
await wdb.addBlock(nextBlock(wdb), [tx]);
assert.strictEqual(alice.account[receiveDepth], 2);
assert.strictEqual(alice.account.changeDepth, 2);
assert.strictEqual(await alice[receiveDepth](), 2);
assert.strictEqual(await alice.changeDepth(), 2);
assert(alice.account[receive].getAddress().equals(addr2));
assert(!alice.account.change.getAddress().equals(change));
assert((await alice[receiveAddress]()).equals(addr2));
assert(!(await alice.changeAddress()).equals(change));
}
const change2 = alice.account.change.getAddress();
const change2 = await alice.changeAddress();
assert(alice.account.change.getAddress().equals(change2));
assert(bob.account.change.getAddress().equals(change2));
assert(carol.account.change.getAddress().equals(change2));
assert((await alice.changeAddress()).equals(change2));
assert((await bob.changeAddress()).equals(change2));
assert((await carol.changeAddress()).equals(change2));
const input = tx.inputs[0];
input[vector].setData(2, encoding.ZERO_SIG);
@ -234,7 +232,7 @@ describe('Wallet', function() {
it('should generate new key and address', async () => {
const wallet = await wdb.create();
const addr1 = wallet.getAddress();
const addr1 = await wallet.receiveAddress();
assert(addr1);
const str = addr1.toString();
@ -284,7 +282,7 @@ describe('Wallet', function() {
await wallet.addSharedKey(0, key);
const script = Script.fromMultisig(1, 2, [
wallet.account.receive.getPublicKey(),
(await wallet.receiveKey()).publicKey,
key.derivePath('m/0/0').publicKey
]);
@ -296,7 +294,7 @@ describe('Wallet', function() {
const tx = new MTX();
tx.addTX(src, 0);
tx.addOutput(wallet.getAddress(), 5460);
tx.addOutput(await wallet.receiveAddress(), 5460);
const maxSize = await tx.estimateSize();
@ -306,7 +304,7 @@ describe('Wallet', function() {
assert(tx.verify());
});
it('should handle missed and invalid txs', async () => {
it('should handle missed txs', async () => {
const alice = await wdb.create();
const bob = await wdb.create();
@ -314,13 +312,13 @@ describe('Wallet', function() {
// balance: 51000
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 50000);
t1.addOutput(alice.getAddress(), 1000);
t1.addOutput(await alice.receiveAddress(), 50000);
t1.addOutput(await alice.receiveAddress(), 1000);
const t2 = new MTX();
t2.addTX(t1, 0); // 50000
t2.addOutput(alice.getAddress(), 24000);
t2.addOutput(alice.getAddress(), 24000);
t2.addOutput(await alice.receiveAddress(), 24000);
t2.addOutput(await alice.receiveAddress(), 24000);
// Save for later.
doubleSpendWallet = alice;
@ -332,7 +330,7 @@ describe('Wallet', function() {
const t3 = new MTX();
t3.addTX(t1, 1); // 1000
t3.addTX(t2, 0); // 24000
t3.addOutput(alice.getAddress(), 23000);
t3.addOutput(await alice.receiveAddress(), 23000);
// balance: 47000
await alice.sign(t3);
@ -340,15 +338,15 @@ describe('Wallet', function() {
const t4 = new MTX();
t4.addTX(t2, 1); // 24000
t4.addTX(t3, 0); // 23000
t4.addOutput(alice.getAddress(), 11000);
t4.addOutput(alice.getAddress(), 11000);
t4.addOutput(await alice.receiveAddress(), 11000);
t4.addOutput(await alice.receiveAddress(), 11000);
// balance: 22000
await alice.sign(t4);
const f1 = new MTX();
f1.addTX(t4, 1); // 11000
f1.addOutput(bob.getAddress(), 10000);
f1.addOutput(await bob.receiveAddress(), 10000);
// balance: 11000
await alice.sign(f1);
@ -433,7 +431,6 @@ describe('Wallet', function() {
return wtx.tx.hash('hex') === f1.hash('hex');
}));
}
});
it('should cleanup spenders after double-spend', async () => {
@ -461,7 +458,7 @@ describe('Wallet', function() {
{
const tx = new MTX();
tx.addCoin(doubleSpendCoin);
tx.addOutput(wallet.getAddress(), 5000);
tx.addOutput(await wallet.receiveAddress(), 5000);
await wallet.sign(tx);
@ -482,22 +479,22 @@ describe('Wallet', function() {
}
});
it('should handle missed txs without resolution', async () => {
it('should handle more missed txs', async () => {
const alice = await wdb.create();
const bob = await wdb.create();
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 50000);
t1.addOutput(alice.getAddress(), 1000);
t1.addOutput(await alice.receiveAddress(), 50000);
t1.addOutput(await alice.receiveAddress(), 1000);
// balance: 51000
const t2 = new MTX();
t2.addTX(t1, 0); // 50000
t2.addOutput(alice.getAddress(), 24000);
t2.addOutput(alice.getAddress(), 24000);
t2.addOutput(await alice.receiveAddress(), 24000);
t2.addOutput(await alice.receiveAddress(), 24000);
// balance: 49000
await alice.sign(t2);
@ -505,7 +502,7 @@ describe('Wallet', function() {
const t3 = new MTX();
t3.addTX(t1, 1); // 1000
t3.addTX(t2, 0); // 24000
t3.addOutput(alice.getAddress(), 23000);
t3.addOutput(await alice.receiveAddress(), 23000);
// balance: 47000
await alice.sign(t3);
@ -513,15 +510,15 @@ describe('Wallet', function() {
const t4 = new MTX();
t4.addTX(t2, 1); // 24000
t4.addTX(t3, 0); // 23000
t4.addOutput(alice.getAddress(), 11000);
t4.addOutput(alice.getAddress(), 11000);
t4.addOutput(await alice.receiveAddress(), 11000);
t4.addOutput(await alice.receiveAddress(), 11000);
// balance: 22000
await alice.sign(t4);
const f1 = new MTX();
f1.addTX(t4, 1); // 11000
f1.addOutput(bob.getAddress(), 10000);
f1.addOutput(await bob.receiveAddress(), 10000);
// balance: 11000
await alice.sign(f1);
@ -599,16 +596,16 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Create new transaction
const m2 = new MTX();
m2.addOutput(bob.getAddress(), 5460);
m2.addOutput(await bob.receiveAddress(), 5460);
await alice.fund(m2, {
rate: 10000,
@ -627,7 +624,7 @@ describe('Wallet', function() {
// Create new transaction
const t3 = new MTX();
t3.addOutput(bob.getAddress(), 15000);
t3.addOutput(await bob.receiveAddress(), 15000);
let err;
try {
@ -655,16 +652,16 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addOutpoint(new Outpoint(encoding.NULL_HASH, 0));
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Create new transaction
const m2 = new MTX();
m2.addOutput(bob.getAddress(), 5460);
m2.addOutput(await bob.receiveAddress(), 5460);
await alice.fund(m2, {
rate: 10000
@ -697,7 +694,7 @@ describe('Wallet', function() {
// Create new transaction
const t3 = new MTX();
t3.addOutput(bob.getAddress(), 15000);
t3.addOutput(await bob.receiveAddress(), 15000);
let err;
try {
@ -721,25 +718,25 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
// Coinbase
const t2 = new MTX();
t2.addInput(dummyInput());
t2.addOutput(bob.getAddress(), 5460);
t2.addOutput(bob.getAddress(), 5460);
t2.addOutput(bob.getAddress(), 5460);
t2.addOutput(bob.getAddress(), 5460);
t2.addOutput(await bob.receiveAddress(), 5460);
t2.addOutput(await bob.receiveAddress(), 5460);
t2.addOutput(await bob.receiveAddress(), 5460);
t2.addOutput(await bob.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
await wdb.addTX(t2.toTX());
// Create our tx with an output
const tx = new MTX();
tx.addOutput(carol.getAddress(), 5460);
tx.addOutput(await carol.receiveAddress(), 5460);
const coins1 = await alice.getCoins();
const coins2 = await bob.getCoins();
@ -799,16 +796,16 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(account.receive.getAddress(), 5460);
t1.addOutput(account.receive.getAddress(), 5460);
t1.addOutput(account.receive.getAddress(), 5460);
t1.addOutput(account.receive.getAddress(), 5460);
t1.addOutput(account.receiveAddress(), 5460);
t1.addOutput(account.receiveAddress(), 5460);
t1.addOutput(account.receiveAddress(), 5460);
t1.addOutput(account.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Create new transaction
const t2 = new MTX();
t2.addOutput(bob.getAddress(), 5460);
t2.addOutput(await bob.receiveAddress(), 5460);
await alice.fund(t2, {
rate: 10000,
@ -825,7 +822,7 @@ describe('Wallet', function() {
// Create new transaction
const t3 = new MTX();
t3.addOutput(bob.getAddress(), 15000);
t3.addOutput(await bob.receiveAddress(), 15000);
let err;
try {
@ -858,27 +855,23 @@ describe('Wallet', function() {
const account = await wallet.getAccount('foo');
assert.strictEqual(account.name, 'foo');
assert.strictEqual(account.accountIndex, 1);
assert.strictEqual(wallet.account.accountIndex, 0);
assert(!account.receive.getAddress().equals(
wallet.account.receive.getAddress()));
assert(wallet.getAddress().equals(wallet.account.receive.getAddress()));
assert(!account.receiveAddress().equals(await wallet.receiveAddress()));
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(account.receive.getAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(account.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Should fill from `foo` and fail
const t2 = new MTX();
t2.addOutput(wallet.getAddress(), 5460);
t2.addOutput(await wallet.receiveAddress(), 5460);
let err;
try {
@ -895,7 +888,7 @@ describe('Wallet', function() {
// Should fill from whole wallet and succeed
const t3 = new MTX();
t3.addOutput(wallet.getAddress(), 5460);
t3.addOutput(await wallet.receiveAddress(), 5460);
await wallet.fund(t3, {
rate: 10000,
@ -905,15 +898,15 @@ describe('Wallet', function() {
// Coinbase
const t4 = new MTX();
t4.addInput(dummyInput());
t4.addOutput(account.receive.getAddress(), 5460);
t4.addOutput(account.receive.getAddress(), 5460);
t4.addOutput(account.receive.getAddress(), 5460);
t4.addOutput(await wallet.receiveAddress('foo'), 5460);
t4.addOutput(await wallet.receiveAddress('foo'), 5460);
t4.addOutput(await wallet.receiveAddress('foo'), 5460);
await wdb.addTX(t4.toTX());
// Should fill from `foo` and succeed
const t5 = new MTX();
t5.addOutput(wallet.getAddress(), 5460);
t5.addOutput(await wallet.receiveAddress(), 5460);
await wallet.fund(t5, {
rate: 10000,
@ -959,16 +952,16 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(wallet.getAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
t1.addOutput(await wallet.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Create new transaction
const t2 = new MTX();
t2.addOutput(wallet.getAddress(), 5460);
t2.addOutput(await wallet.receiveAddress(), 5460);
await wallet.fund(t2, {
rate: 10000,
@ -998,16 +991,16 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Create new transaction
const t2 = new MTX();
t2.addOutput(bob.getAddress(), 21840);
t2.addOutput(await bob.receiveAddress(), 21840);
await alice.fund(t2, {
rate: 10000,
@ -1031,10 +1024,10 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
@ -1042,7 +1035,7 @@ describe('Wallet', function() {
subtractFee: true,
rate: 10000,
round: true,
outputs: [{ address: bob.getAddress(), value: 21840 }]
outputs: [{ address: await bob.receiveAddress(), value: 21840 }]
};
// Create new transaction
@ -1063,20 +1056,20 @@ describe('Wallet', function() {
// Coinbase
const t1 = new MTX();
t1.addInput(dummyInput());
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(alice.getAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
t1.addOutput(await alice.receiveAddress(), 5460);
await wdb.addTX(t1.toTX());
// Coinbase
const t2 = new MTX();
t2.addInput(dummyInput());
t2.addOutput(alice.getAddress(), 5460);
t2.addOutput(alice.getAddress(), 5460);
t2.addOutput(alice.getAddress(), 5460);
t2.addOutput(alice.getAddress(), 5460);
t2.addOutput(await alice.receiveAddress(), 5460);
t2.addOutput(await alice.receiveAddress(), 5460);
t2.addOutput(await alice.receiveAddress(), 5460);
t2.addOutput(await alice.receiveAddress(), 5460);
await wdb.addBlock(nextBlock(wdb), [t2.toTX()]);
@ -1095,7 +1088,7 @@ describe('Wallet', function() {
subtractFee: true,
rate: 1000,
depth: 1,
outputs: [{ address: bob.getAddress(), value: 1461 }]
outputs: [{ address: await bob.receiveAddress(), value: 1461 }]
});
const coins = await alice.getSmartCoins();
@ -1127,7 +1120,7 @@ describe('Wallet', function() {
smart: true,
rate: 10000,
outputs: [{
address: bob.getAddress(),
address: await bob.receiveAddress(),
value: total
}]
};
@ -1228,7 +1221,7 @@ describe('Wallet', function() {
rate: 10000,
round: true,
outputs: [{
address: wallet.getAddress(),
address: await wallet.receiveAddress(),
value: 7000
}]
};
@ -1357,7 +1350,7 @@ describe('Wallet', function() {
master: KEY1
});
const addr = alice.getAddress();
const addr = await alice.receiveAddress();
// Coinbase
const t1 = new MTX();
@ -1417,7 +1410,7 @@ describe('Wallet', function() {
master: KEY1
});
const addr = alice.getAddress();
const addr = await alice.receiveAddress();
// Coinbase
const t1 = new MTX();