wallet: better/less property tracking.
This commit is contained in:
parent
fe261db706
commit
40bb08aed6
@ -44,10 +44,10 @@ function HTTPServer(options) {
|
|||||||
this.options = options;
|
this.options = options;
|
||||||
this.network = this.options.network;
|
this.network = this.options.network;
|
||||||
this.logger = this.options.logger.context('http');
|
this.logger = this.options.logger.context('http');
|
||||||
this.walletdb = this.options.walletdb;
|
this.wdb = this.options.walletdb;
|
||||||
|
|
||||||
this.server = new HTTPBase(this.options);
|
this.server = new HTTPBase(this.options);
|
||||||
this.rpc = this.walletdb.rpc;
|
this.rpc = this.wdb.rpc;
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
const token = valid.buf('token');
|
const token = valid.buf('token');
|
||||||
|
|
||||||
if (!this.options.walletAuth) {
|
if (!this.options.walletAuth) {
|
||||||
const wallet = await this.walletdb.get(id);
|
const wallet = await this.wdb.get(id);
|
||||||
|
|
||||||
if (!wallet) {
|
if (!wallet) {
|
||||||
res.send(404);
|
res.send(404);
|
||||||
@ -138,7 +138,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
|
|
||||||
let wallet;
|
let wallet;
|
||||||
try {
|
try {
|
||||||
wallet = await this.walletdb.auth(id, token);
|
wallet = await this.wdb.auth(id, token);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.info('Auth failure for %s: %s.', id, err.message);
|
this.logger.info('Auth failure for %s: %s.', id, err.message);
|
||||||
res.error(403, err);
|
res.error(403, err);
|
||||||
@ -162,12 +162,12 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
|
|
||||||
res.send(200, { success: true });
|
res.send(200, { success: true });
|
||||||
|
|
||||||
await this.walletdb.rescan(height);
|
await this.wdb.rescan(height);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resend
|
// Resend
|
||||||
this.post('/_admin/resend', async (req, res) => {
|
this.post('/_admin/resend', async (req, res) => {
|
||||||
await this.walletdb.resend();
|
await this.wdb.resend();
|
||||||
|
|
||||||
res.send(200, { success: true });
|
res.send(200, { success: true });
|
||||||
});
|
});
|
||||||
@ -179,14 +179,14 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
|
|
||||||
enforce(path, 'Path is required.');
|
enforce(path, 'Path is required.');
|
||||||
|
|
||||||
await this.walletdb.backup(path);
|
await this.wdb.backup(path);
|
||||||
|
|
||||||
res.send(200, { success: true });
|
res.send(200, { success: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
// List wallets
|
// List wallets
|
||||||
this.get('/_admin/wallets', async (req, res) => {
|
this.get('/_admin/wallets', async (req, res) => {
|
||||||
const wallets = await this.walletdb.getWallets();
|
const wallets = await this.wdb.getWallets();
|
||||||
res.send(200, wallets);
|
res.send(200, wallets);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
this.post('/', async (req, res) => {
|
this.post('/', async (req, res) => {
|
||||||
const valid = req.valid();
|
const valid = req.valid();
|
||||||
|
|
||||||
const wallet = await this.walletdb.create({
|
const wallet = await this.wdb.create({
|
||||||
id: valid.str('id'),
|
id: valid.str('id'),
|
||||||
type: valid.str('type'),
|
type: valid.str('type'),
|
||||||
m: valid.u32('m'),
|
m: valid.u32('m'),
|
||||||
@ -227,7 +227,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
this.put('/:id', async (req, res) => {
|
this.put('/:id', async (req, res) => {
|
||||||
const valid = req.valid();
|
const valid = req.valid();
|
||||||
|
|
||||||
const wallet = await this.walletdb.create({
|
const wallet = await this.wdb.create({
|
||||||
id: valid.str('id'),
|
id: valid.str('id'),
|
||||||
type: valid.str('type'),
|
type: valid.str('type'),
|
||||||
m: valid.u32('m'),
|
m: valid.u32('m'),
|
||||||
@ -425,7 +425,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
|
|
||||||
const details = await req.wallet.getDetails(tx.hash('hex'));
|
const details = await req.wallet.getDetails(tx.hash('hex'));
|
||||||
|
|
||||||
res.send(200, details.toJSON(this.network));
|
res.send(200, details.toJSON(this.network, this.wdb.height));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create TX
|
// Create TX
|
||||||
@ -724,7 +724,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const item of details)
|
for (const item of details)
|
||||||
result.push(item.toJSON(this.network));
|
result.push(item.toJSON(this.network, this.wdb.height));
|
||||||
|
|
||||||
res.send(200, result);
|
res.send(200, result);
|
||||||
});
|
});
|
||||||
@ -741,7 +741,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const item of details)
|
for (const item of details)
|
||||||
result.push(item.toJSON(this.network));
|
result.push(item.toJSON(this.network, this.wdb.height));
|
||||||
|
|
||||||
res.send(200, result);
|
res.send(200, result);
|
||||||
});
|
});
|
||||||
@ -763,7 +763,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const item of details)
|
for (const item of details)
|
||||||
result.push(item.toJSON(this.network));
|
result.push(item.toJSON(this.network, this.wdb.height));
|
||||||
|
|
||||||
res.send(200, result);
|
res.send(200, result);
|
||||||
});
|
});
|
||||||
@ -778,7 +778,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const item of details)
|
for (const item of details)
|
||||||
result.push(item.toJSON(this.network));
|
result.push(item.toJSON(this.network, this.wdb.height));
|
||||||
|
|
||||||
res.send(200, result);
|
res.send(200, result);
|
||||||
});
|
});
|
||||||
@ -799,7 +799,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
|
|||||||
|
|
||||||
const details = await req.wallet.toDetails(tx);
|
const details = await req.wallet.toDetails(tx);
|
||||||
|
|
||||||
res.send(200, details.toJSON(this.network));
|
res.send(200, details.toJSON(this.network, this.wdb.height));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Resend
|
// Resend
|
||||||
@ -822,32 +822,32 @@ HTTPServer.prototype.initSockets = function initSockets() {
|
|||||||
this.handleSocket(socket);
|
this.handleSocket(socket);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('tx', (w, tx, details) => {
|
this.wdb.on('tx', (w, tx, details) => {
|
||||||
const json = details.toJSON(this.network);
|
const json = details.toJSON(this.network, this.wdb.height);
|
||||||
this.to(`w:${w.id}`, 'wallet tx', json);
|
this.to(`w:${w.id}`, 'wallet tx', json);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('confirmed', (w, tx, details) => {
|
this.wdb.on('confirmed', (w, tx, details) => {
|
||||||
const json = details.toJSON(this.network);
|
const json = details.toJSON(this.network, this.wdb.height);
|
||||||
this.to(`w:${w.id}`, 'wallet confirmed', json);
|
this.to(`w:${w.id}`, 'wallet confirmed', json);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('unconfirmed', (w, tx, details) => {
|
this.wdb.on('unconfirmed', (w, tx, details) => {
|
||||||
const json = details.toJSON(this.network);
|
const json = details.toJSON(this.network, this.wdb.height);
|
||||||
this.to(`w:${w.id}`, 'wallet unconfirmed', json);
|
this.to(`w:${w.id}`, 'wallet unconfirmed', json);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('conflict', (w, tx, details) => {
|
this.wdb.on('conflict', (w, tx, details) => {
|
||||||
const json = details.toJSON(this.network);
|
const json = details.toJSON(this.network, this.wdb.height);
|
||||||
this.to(`w:${w.id}`, 'wallet conflict', json);
|
this.to(`w:${w.id}`, 'wallet conflict', json);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('balance', (w, balance) => {
|
this.wdb.on('balance', (w, balance) => {
|
||||||
const json = balance.toJSON();
|
const json = balance.toJSON();
|
||||||
this.to(`w:${w.id}`, 'wallet balance', json);
|
this.to(`w:${w.id}`, 'wallet balance', json);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.walletdb.on('address', (w, receive) => {
|
this.wdb.on('address', (w, receive) => {
|
||||||
const json = [];
|
const json = [];
|
||||||
|
|
||||||
for (const addr of receive)
|
for (const addr of receive)
|
||||||
@ -917,7 +917,7 @@ HTTPServer.prototype.handleAuth = function handleAuth(socket) {
|
|||||||
|
|
||||||
let wallet;
|
let wallet;
|
||||||
try {
|
try {
|
||||||
wallet = await this.walletdb.auth(id, token);
|
wallet = await this.wdb.auth(id, token);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.info('Wallet auth failure for %s: %s.', id, e.message);
|
this.logger.info('Wallet auth failure for %s: %s.', id, e.message);
|
||||||
throw new Error('Bad token.');
|
throw new Error('Bad token.');
|
||||||
|
|||||||
@ -30,8 +30,6 @@ function Path(options) {
|
|||||||
|
|
||||||
this.keyType = Path.types.HD;
|
this.keyType = Path.types.HD;
|
||||||
|
|
||||||
this.id = null; // Passed in by caller.
|
|
||||||
this.wid = -1; // Passed in by caller.
|
|
||||||
this.name = null; // Passed in by caller.
|
this.name = null; // Passed in by caller.
|
||||||
this.account = 0;
|
this.account = 0;
|
||||||
this.branch = -1;
|
this.branch = -1;
|
||||||
@ -71,8 +69,6 @@ Path.types = {
|
|||||||
Path.prototype.fromOptions = function fromOptions(options) {
|
Path.prototype.fromOptions = function fromOptions(options) {
|
||||||
this.keyType = options.keyType;
|
this.keyType = options.keyType;
|
||||||
|
|
||||||
this.id = options.id;
|
|
||||||
this.wid = options.wid;
|
|
||||||
this.name = options.name;
|
this.name = options.name;
|
||||||
this.account = options.account;
|
this.account = options.account;
|
||||||
this.branch = options.branch;
|
this.branch = options.branch;
|
||||||
@ -108,8 +104,6 @@ Path.prototype.clone = function clone() {
|
|||||||
|
|
||||||
path.keyType = this.keyType;
|
path.keyType = this.keyType;
|
||||||
|
|
||||||
path.id = this.id;
|
|
||||||
path.wid = this.wid;
|
|
||||||
path.name = this.name;
|
path.name = this.name;
|
||||||
path.account = this.account;
|
path.account = this.account;
|
||||||
path.branch = this.branch;
|
path.branch = this.branch;
|
||||||
@ -247,8 +241,6 @@ Path.prototype.toRaw = function toRaw() {
|
|||||||
|
|
||||||
Path.prototype.fromAddress = function fromAddress(account, address) {
|
Path.prototype.fromAddress = function fromAddress(account, address) {
|
||||||
this.keyType = Path.types.ADDRESS;
|
this.keyType = Path.types.ADDRESS;
|
||||||
this.id = account.id;
|
|
||||||
this.wid = account.wid;
|
|
||||||
this.name = account.name;
|
this.name = account.name;
|
||||||
this.account = account.accountIndex;
|
this.account = account.accountIndex;
|
||||||
this.version = address.version;
|
this.version = address.version;
|
||||||
@ -309,7 +301,7 @@ Path.prototype.toJSON = function toJSON() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Path.prototype.inspect = function inspect() {
|
Path.prototype.inspect = function inspect() {
|
||||||
return `<Path: ${this.id}(${this.wid})/${this.name}:${this.toPath()}>`;
|
return `<Path: ${this.name}:${this.toPath()}>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -25,22 +25,19 @@ const TXRecord = records.TXRecord;
|
|||||||
* TXDB
|
* TXDB
|
||||||
* @alias module:wallet.TXDB
|
* @alias module:wallet.TXDB
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Wallet} wallet
|
* @param {WalletDB} wdb
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function TXDB(wdb) {
|
function TXDB(wdb, wid) {
|
||||||
if (!(this instanceof TXDB))
|
if (!(this instanceof TXDB))
|
||||||
return new TXDB(wdb);
|
return new TXDB(wdb);
|
||||||
|
|
||||||
this.wdb = wdb;
|
this.wdb = wdb;
|
||||||
this.db = wdb.db;
|
this.db = wdb.db;
|
||||||
this.logger = wdb.logger;
|
this.logger = wdb.logger;
|
||||||
this.network = wdb.network;
|
|
||||||
this.options = wdb.options;
|
|
||||||
|
|
||||||
this.wid = 0;
|
this.wid = wid || 0;
|
||||||
this.id = null;
|
this.prefix = layout.prefix(this.wid);
|
||||||
this.prefix = layout.prefix(0);
|
|
||||||
this.wallet = null;
|
this.wallet = null;
|
||||||
this.locked = new Set();
|
this.locked = new Set();
|
||||||
}
|
}
|
||||||
@ -58,10 +55,8 @@ TXDB.layout = layout;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TXDB.prototype.open = async function open(wallet) {
|
TXDB.prototype.open = async function open(wallet) {
|
||||||
const {wid, id} = wallet;
|
this.wid = wallet.wid;
|
||||||
this.id = id;
|
this.prefix = layout.prefix(this.wid);
|
||||||
this.wid = wid;
|
|
||||||
this.prefix = layout.prefix(wid);
|
|
||||||
this.wallet = wallet;
|
this.wallet = wallet;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,7 +142,7 @@ TXDB.prototype.getPath = function getPath(output) {
|
|||||||
if (!hash)
|
if (!hash)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return this.wdb.getPath(this.wid, this.id, hash);
|
return this.wdb.getPath(this.wid, hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -392,18 +387,18 @@ TXDB.prototype.getBlock = async function getBlock(height) {
|
|||||||
/**
|
/**
|
||||||
* Append to the global block record.
|
* Append to the global block record.
|
||||||
* @param {Hash} hash
|
* @param {Hash} hash
|
||||||
* @param {BlockMeta} meta
|
* @param {BlockMeta} block
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TXDB.prototype.addBlock = async function addBlock(b, hash, meta) {
|
TXDB.prototype.addBlock = async function addBlock(b, hash, block) {
|
||||||
const key = layout.b(meta.height);
|
const key = layout.b(block.height);
|
||||||
const data = await this.get(key);
|
const data = await this.get(key);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
const block = BlockRecord.fromMeta(meta);
|
const blk = BlockRecord.fromMeta(block);
|
||||||
block.add(hash);
|
blk.add(hash);
|
||||||
b.put(key, block.toRaw());
|
b.put(key, blk.toRaw());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +521,7 @@ TXDB.prototype.insert = async function insert(wtx, block) {
|
|||||||
const b = this.bucket();
|
const b = this.bucket();
|
||||||
const {tx, hash} = wtx;
|
const {tx, hash} = wtx;
|
||||||
const height = block ? block.height : -1;
|
const height = block ? block.height : -1;
|
||||||
const details = new Details(this, wtx, block);
|
const details = new Details(wtx, block);
|
||||||
const state = new BalanceDelta();
|
const state = new BalanceDelta();
|
||||||
|
|
||||||
let own = false;
|
let own = false;
|
||||||
@ -682,7 +677,7 @@ TXDB.prototype.confirm = async function confirm(wtx, block) {
|
|||||||
const b = this.bucket();
|
const b = this.bucket();
|
||||||
const {tx, hash} = wtx;
|
const {tx, hash} = wtx;
|
||||||
const height = block.height;
|
const height = block.height;
|
||||||
const details = new Details(this, wtx, block);
|
const details = new Details(wtx, block);
|
||||||
const state = new BalanceDelta();
|
const state = new BalanceDelta();
|
||||||
|
|
||||||
wtx.setBlock(block);
|
wtx.setBlock(block);
|
||||||
@ -697,21 +692,18 @@ TXDB.prototype.confirm = async function confirm(wtx, block) {
|
|||||||
const input = tx.inputs[i];
|
const input = tx.inputs[i];
|
||||||
const {hash, index} = input.prevout;
|
const {hash, index} = input.prevout;
|
||||||
|
|
||||||
let credit = credits[i];
|
let resolved = false;
|
||||||
|
|
||||||
// There may be new credits available
|
// There may be new credits available
|
||||||
// that we haven't seen yet.
|
// that we haven't seen yet.
|
||||||
if (!credit) {
|
if (!credits[i]) {
|
||||||
await this.removeInput(b, tx, i);
|
await this.removeInput(b, tx, i);
|
||||||
|
|
||||||
credit = await this.getCredit(hash, index);
|
const credit = await this.getCredit(hash, index);
|
||||||
|
|
||||||
if (!credit)
|
if (!credit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const path = await this.getPath(credit.coin);
|
|
||||||
assert(path);
|
|
||||||
|
|
||||||
// Add a spend record and undo coin
|
// Add a spend record and undo coin
|
||||||
// for the coin we now know is ours.
|
// for the coin we now know is ours.
|
||||||
// We don't need to remove the coin
|
// We don't need to remove the coin
|
||||||
@ -719,10 +711,11 @@ TXDB.prototype.confirm = async function confirm(wtx, block) {
|
|||||||
// first place.
|
// first place.
|
||||||
this.spendCredit(b, credit, tx, i);
|
this.spendCredit(b, credit, tx, i);
|
||||||
|
|
||||||
state.coin(path, -1);
|
credits[i] = credit;
|
||||||
state.unconfirmed(path, -credit.coin.value);
|
resolved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const credit = credits[i];
|
||||||
const coin = credit.coin;
|
const coin = credit.coin;
|
||||||
|
|
||||||
assert(coin.height !== -1);
|
assert(coin.height !== -1);
|
||||||
@ -732,6 +725,11 @@ TXDB.prototype.confirm = async function confirm(wtx, block) {
|
|||||||
|
|
||||||
details.setInput(i, path, coin);
|
details.setInput(i, path, coin);
|
||||||
|
|
||||||
|
if (resolved) {
|
||||||
|
state.coin(path, -1);
|
||||||
|
state.unconfirmed(path, -coin.value);
|
||||||
|
}
|
||||||
|
|
||||||
// We can now safely remove the credit
|
// We can now safely remove the credit
|
||||||
// entirely, now that we know it's also
|
// entirely, now that we know it's also
|
||||||
// been removed on-chain.
|
// been removed on-chain.
|
||||||
@ -828,7 +826,7 @@ TXDB.prototype.erase = async function erase(wtx, block) {
|
|||||||
const b = this.bucket();
|
const b = this.bucket();
|
||||||
const {tx, hash} = wtx;
|
const {tx, hash} = wtx;
|
||||||
const height = block ? block.height : -1;
|
const height = block ? block.height : -1;
|
||||||
const details = new Details(this, wtx, block);
|
const details = new Details(wtx, block);
|
||||||
const state = new BalanceDelta();
|
const state = new BalanceDelta();
|
||||||
|
|
||||||
if (!tx.isCoinbase()) {
|
if (!tx.isCoinbase()) {
|
||||||
@ -1015,7 +1013,7 @@ TXDB.prototype.unconfirm = async function unconfirm(hash) {
|
|||||||
TXDB.prototype.disconnect = async function disconnect(wtx, block) {
|
TXDB.prototype.disconnect = async function disconnect(wtx, block) {
|
||||||
const b = this.bucket();
|
const b = this.bucket();
|
||||||
const {tx, hash, height} = wtx;
|
const {tx, hash, height} = wtx;
|
||||||
const details = new Details(this, wtx, block);
|
const details = new Details(wtx, block);
|
||||||
const state = new BalanceDelta();
|
const state = new BalanceDelta();
|
||||||
|
|
||||||
assert(block);
|
assert(block);
|
||||||
@ -1780,9 +1778,9 @@ TXDB.prototype.getCoinView = async function getCoinView(tx) {
|
|||||||
if (tx.isCoinbase())
|
if (tx.isCoinbase())
|
||||||
return view;
|
return view;
|
||||||
|
|
||||||
for (const input of tx.inputs) {
|
for (const {prevout} of tx.inputs) {
|
||||||
const prevout = input.prevout;
|
const {hash, index} = prevout;
|
||||||
const coin = await this.getCoin(prevout.hash, prevout.index);
|
const coin = await this.getCoin(hash, index);
|
||||||
|
|
||||||
if (!coin)
|
if (!coin)
|
||||||
continue;
|
continue;
|
||||||
@ -1881,7 +1879,7 @@ TXDB.prototype.toDetails = async function toDetails(wtxs) {
|
|||||||
TXDB.prototype._toDetails = async function _toDetails(wtx) {
|
TXDB.prototype._toDetails = async function _toDetails(wtx) {
|
||||||
const tx = wtx.tx;
|
const tx = wtx.tx;
|
||||||
const block = wtx.getBlock();
|
const block = wtx.getBlock();
|
||||||
const details = new Details(this, wtx, block);
|
const details = new Details(wtx, block);
|
||||||
const coins = await this.getSpentCoins(tx);
|
const coins = await this.getSpentCoins(tx);
|
||||||
|
|
||||||
for (let i = 0; i < tx.inputs.length; i++) {
|
for (let i = 0; i < tx.inputs.length; i++) {
|
||||||
@ -2083,8 +2081,8 @@ TXDB.prototype.zap = async function zap(acct, age) {
|
|||||||
|
|
||||||
assert(now - wtx.mtime >= age);
|
assert(now - wtx.mtime >= age);
|
||||||
|
|
||||||
this.logger.debug('Zapping TX: %s (%s)',
|
this.logger.debug('Zapping TX: %s (%d)',
|
||||||
wtx.tx.txid(), this.id);
|
wtx.tx.txid(), this.wid);
|
||||||
|
|
||||||
await this.remove(wtx.hash);
|
await this.remove(wtx.hash);
|
||||||
|
|
||||||
@ -2365,13 +2363,9 @@ Credit.fromTX = function fromTX(tx, index, height) {
|
|||||||
* @param {TX} tx
|
* @param {TX} tx
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function Details(txdb, wtx, block) {
|
function Details(wtx, block) {
|
||||||
if (!(this instanceof Details))
|
if (!(this instanceof Details))
|
||||||
return new Details(txdb, wtx, block);
|
return new Details(wtx, block);
|
||||||
|
|
||||||
this.wid = txdb.wid;
|
|
||||||
this.id = txdb.id;
|
|
||||||
this.tip = txdb.wdb.state.height;
|
|
||||||
|
|
||||||
this.hash = wtx.hash;
|
this.hash = wtx.hash;
|
||||||
this.tx = wtx.tx;
|
this.tx = wtx.tx;
|
||||||
@ -2452,11 +2446,14 @@ Details.prototype.setOutput = function setOutput(i, path) {
|
|||||||
* @returns {Number}
|
* @returns {Number}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Details.prototype.getDepth = function getDepth() {
|
Details.prototype.getDepth = function getDepth(height) {
|
||||||
if (this.height === -1)
|
if (this.height === -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const depth = this.tip - this.height;
|
if (height == null)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const depth = height - this.height;
|
||||||
|
|
||||||
if (depth < 0)
|
if (depth < 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -2503,13 +2500,11 @@ Details.prototype.getRate = function getRate(fee) {
|
|||||||
* @returns {Object}
|
* @returns {Object}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Details.prototype.toJSON = function toJSON(network) {
|
Details.prototype.toJSON = function toJSON(network, height) {
|
||||||
const fee = this.getFee();
|
const fee = this.getFee();
|
||||||
const rate = this.getRate(fee);
|
const rate = this.getRate(fee);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
wid: this.wid,
|
|
||||||
id: this.id,
|
|
||||||
hash: util.revHex(this.hash),
|
hash: util.revHex(this.hash),
|
||||||
height: this.height,
|
height: this.height,
|
||||||
block: this.block ? util.revHex(this.block) : null,
|
block: this.block ? util.revHex(this.block) : null,
|
||||||
@ -2521,7 +2516,7 @@ Details.prototype.toJSON = function toJSON(network) {
|
|||||||
virtualSize: this.vsize,
|
virtualSize: this.vsize,
|
||||||
fee: fee,
|
fee: fee,
|
||||||
rate: rate,
|
rate: rate,
|
||||||
confirmations: this.getDepth(),
|
confirmations: this.getDepth(height),
|
||||||
inputs: this.inputs.map((input) => {
|
inputs: this.inputs.map((input) => {
|
||||||
return input.getJSON(network);
|
return input.getJSON(network);
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -895,7 +895,7 @@ Wallet.prototype.hasAddress = async function hasAddress(address) {
|
|||||||
|
|
||||||
Wallet.prototype.getPath = async function getPath(address) {
|
Wallet.prototype.getPath = async function getPath(address) {
|
||||||
const hash = Address.getHash(address, 'hex');
|
const hash = Address.getHash(address, 'hex');
|
||||||
return this.wdb.getPath(this.wid, this.id, hash);
|
return this.wdb.getPath(this.wid, hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -907,7 +907,7 @@ Wallet.prototype.getPath = async function getPath(address) {
|
|||||||
|
|
||||||
Wallet.prototype.readPath = async function readPath(address) {
|
Wallet.prototype.readPath = async function readPath(address) {
|
||||||
const hash = Address.getHash(address, 'hex');
|
const hash = Address.getHash(address, 'hex');
|
||||||
return this.wdb.readPath(this.wid, this.id, hash);
|
return this.wdb.readPath(this.wid, hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -935,7 +935,6 @@ Wallet.prototype.getPaths = async function getPaths(acct) {
|
|||||||
const result = [];
|
const result = [];
|
||||||
|
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
path.id = this.id;
|
|
||||||
path.name = await this.getAccountName(path.account);
|
path.name = await this.getAccountName(path.account);
|
||||||
|
|
||||||
assert(path.name);
|
assert(path.name);
|
||||||
|
|||||||
@ -80,6 +80,7 @@ function WalletDB(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.state = new ChainState();
|
this.state = new ChainState();
|
||||||
|
this.height = 0;
|
||||||
this.wallets = new Map();
|
this.wallets = new Map();
|
||||||
this.depth = 0;
|
this.depth = 0;
|
||||||
this.rescanning = false;
|
this.rescanning = false;
|
||||||
@ -303,6 +304,7 @@ WalletDB.prototype.init = async function init() {
|
|||||||
|
|
||||||
if (cache) {
|
if (cache) {
|
||||||
this.state = cache;
|
this.state = cache;
|
||||||
|
this.height = cache.height;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +339,7 @@ WalletDB.prototype.init = async function init() {
|
|||||||
await b.write();
|
await b.write();
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.height = state.height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -827,7 +830,6 @@ WalletDB.prototype._rename = async function _rename(wallet, id) {
|
|||||||
b.del(layout.l(old));
|
b.del(layout.l(old));
|
||||||
|
|
||||||
wallet.id = id;
|
wallet.id = id;
|
||||||
wallet.txdb.id = id;
|
|
||||||
|
|
||||||
this.save(b, wallet);
|
this.save(b, wallet);
|
||||||
|
|
||||||
@ -1085,8 +1087,8 @@ WalletDB.prototype.savePath = async function savePath(b, wid, path) {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype.getPath = async function getPath(wid, id, hash) {
|
WalletDB.prototype.getPath = async function getPath(wid, hash) {
|
||||||
const path = await this.readPath(wid, id, hash);
|
const path = await this.readPath(wid, hash);
|
||||||
|
|
||||||
if (!path)
|
if (!path)
|
||||||
return null;
|
return null;
|
||||||
@ -1104,15 +1106,13 @@ WalletDB.prototype.getPath = async function getPath(wid, id, hash) {
|
|||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype.readPath = async function readPath(wid, id, hash) {
|
WalletDB.prototype.readPath = async function readPath(wid, hash) {
|
||||||
const data = await this.db.get(layout.P(wid, hash));
|
const data = await this.db.get(layout.P(wid, hash));
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const path = Path.fromRaw(data);
|
const path = Path.fromRaw(data);
|
||||||
path.id = id;
|
|
||||||
path.wid = wid;
|
|
||||||
path.hash = hash;
|
path.hash = hash;
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
@ -1206,7 +1206,6 @@ WalletDB.prototype.getWalletPaths = async function getWalletPaths(wid) {
|
|||||||
const path = Path.fromRaw(item.value);
|
const path = Path.fromRaw(item.value);
|
||||||
|
|
||||||
path.hash = hash;
|
path.hash = hash;
|
||||||
path.wid = wid;
|
|
||||||
|
|
||||||
paths.push(path);
|
paths.push(path);
|
||||||
}
|
}
|
||||||
@ -1453,6 +1452,7 @@ WalletDB.prototype.syncState = async function syncState(tip) {
|
|||||||
await b.write();
|
await b.write();
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.height = state.height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1472,6 +1472,7 @@ WalletDB.prototype.markState = async function markState(block) {
|
|||||||
await b.write();
|
await b.write();
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
this.height = state.height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -26,8 +26,6 @@ function WalletKey(options, network) {
|
|||||||
|
|
||||||
this.keyType = Path.types.HD;
|
this.keyType = Path.types.HD;
|
||||||
|
|
||||||
this.id = null;
|
|
||||||
this.wid = -1;
|
|
||||||
this.name = null;
|
this.name = null;
|
||||||
this.account = -1;
|
this.account = -1;
|
||||||
this.branch = -1;
|
this.branch = -1;
|
||||||
@ -121,8 +119,6 @@ WalletKey.fromSecret = function fromSecret(data, network) {
|
|||||||
WalletKey.prototype.toJSON = function toJSON() {
|
WalletKey.prototype.toJSON = function toJSON() {
|
||||||
return {
|
return {
|
||||||
network: this.network.type,
|
network: this.network.type,
|
||||||
wid: this.wid,
|
|
||||||
id: this.id,
|
|
||||||
name: this.name,
|
name: this.name,
|
||||||
account: this.account,
|
account: this.account,
|
||||||
branch: this.branch,
|
branch: this.branch,
|
||||||
@ -169,8 +165,6 @@ WalletKey.fromRaw = function fromRaw(data) {
|
|||||||
|
|
||||||
WalletKey.prototype.fromHD = function fromHD(account, key, branch, index) {
|
WalletKey.prototype.fromHD = function fromHD(account, key, branch, index) {
|
||||||
this.keyType = Path.types.HD;
|
this.keyType = Path.types.HD;
|
||||||
this.id = account.id;
|
|
||||||
this.wid = account.wid;
|
|
||||||
this.name = account.name;
|
this.name = account.name;
|
||||||
this.account = account.accountIndex;
|
this.account = account.accountIndex;
|
||||||
this.branch = branch;
|
this.branch = branch;
|
||||||
@ -207,8 +201,6 @@ WalletKey.fromHD = function fromHD(account, key, branch, index) {
|
|||||||
|
|
||||||
WalletKey.prototype.fromImport = function fromImport(account, data) {
|
WalletKey.prototype.fromImport = function fromImport(account, data) {
|
||||||
this.keyType = Path.types.KEY;
|
this.keyType = Path.types.KEY;
|
||||||
this.id = account.id;
|
|
||||||
this.wid = account.wid;
|
|
||||||
this.name = account.name;
|
this.name = account.name;
|
||||||
this.account = account.accountIndex;
|
this.account = account.accountIndex;
|
||||||
this.witness = account.witness;
|
this.witness = account.witness;
|
||||||
@ -236,8 +228,6 @@ WalletKey.fromImport = function fromImport(account, data) {
|
|||||||
|
|
||||||
WalletKey.prototype.fromRing = function fromRing(account, ring) {
|
WalletKey.prototype.fromRing = function fromRing(account, ring) {
|
||||||
this.keyType = Path.types.KEY;
|
this.keyType = Path.types.KEY;
|
||||||
this.id = account.id;
|
|
||||||
this.wid = account.wid;
|
|
||||||
this.name = account.name;
|
this.name = account.name;
|
||||||
this.account = account.accountIndex;
|
this.account = account.accountIndex;
|
||||||
this.witness = account.witness;
|
this.witness = account.witness;
|
||||||
@ -263,8 +253,6 @@ WalletKey.fromRing = function fromRing(account, ring) {
|
|||||||
WalletKey.prototype.toPath = function toPath() {
|
WalletKey.prototype.toPath = function toPath() {
|
||||||
const path = new Path();
|
const path = new Path();
|
||||||
|
|
||||||
path.id = this.id;
|
|
||||||
path.wid = this.wid;
|
|
||||||
path.name = this.name;
|
path.name = this.name;
|
||||||
path.account = this.account;
|
path.account = this.account;
|
||||||
|
|
||||||
|
|||||||
@ -1318,7 +1318,8 @@ describe('Wallet', function() {
|
|||||||
|
|
||||||
const details = await wallet.toDetails(txs);
|
const details = await wallet.toDetails(txs);
|
||||||
|
|
||||||
assert.strictEqual(details[0].toJSON().id, 'test');
|
assert(details.length > 0);
|
||||||
|
assert.strictEqual(wallet.id, 'test');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change passphrase with encrypted imports', async () => {
|
it('should change passphrase with encrypted imports', async () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user