node/http: fix address type in http api

This commit is contained in:
lanford 2018-09-17 16:43:56 +08:00
commit 36dcacdbda
24 changed files with 355 additions and 340 deletions

View file

@ -11,6 +11,11 @@ $ npm install --production
$ ./bin/hsd
```
## Documentation
- Documentation Site: [https://handshake-org.github.io](https://handshake-org.github.io)
- API Docs: [https://handshake-org.github.io/api-docs/index.html](https://handshake-org.github.io/api-docs/index.html)
- JSDoc: [https://handshake-org.github.io/docs](https://handshake-org.github.io/docs)
## Testnet
A testnet is currently running as of August 2nd.

View file

@ -11,7 +11,7 @@ const path = require('path');
const AsyncEmitter = require('bevent');
const Logger = require('blgr');
const {Lock} = require('bmutex');
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
const LRU = require('blru');
const {BufferMap, BufferSet} = require('buffer-map');
const Network = require('../protocol/network');
@ -3155,7 +3155,15 @@ class Chain extends AsyncEmitter {
// so we can calculate that with:
// chain_height - (chain_height % interval)
const interval = this.network.names.treeInterval;
const mod = this.height % interval;
let mod = this.height % interval;
// If there's enough proof-of-work
// on top of the most recent root,
// it should be safe to use it.
if (mod >= 12)
mod = 0;
const height = this.height - mod;
const entry = await this.getEntryByHeight(height);
assert(entry);

View file

@ -68,7 +68,7 @@ class ChainDB {
this.logger.info('Opening ChainDB...');
await this.db.open();
await this.db.verify(layout.V.build(), 'chain', 0);
await this.db.verify(layout.V.encode(), 'chain', 0);
await this.tree.open();
const state = await this.getState();
@ -88,7 +88,7 @@ class ChainDB {
// Grab the current tree state.
if (!this.options.spv) {
const root = await this.db.get(layout.s.build());
const root = await this.db.get(layout.s.encode());
assert(root && root.length === 32);
await this.tree.inject(root);
@ -286,7 +286,7 @@ class ChainDB {
if (entry)
return entry.height;
const height = await this.db.get(layout.h.build(hash));
const height = await this.db.get(layout.h.encode(hash));
if (!height)
return -1;
@ -315,7 +315,7 @@ class ChainDB {
if (entry)
return entry.hash;
return this.db.get(layout.H.build(height));
return this.db.get(layout.H.encode(height));
}
/**
@ -335,7 +335,7 @@ class ChainDB {
if (cache)
return cache;
const hash = await this.db.get(layout.H.build(height));
const hash = await this.db.get(layout.H.encode(height));
if (!hash)
return null;
@ -372,7 +372,7 @@ class ChainDB {
if (cache)
return cache;
const raw = await this.db.get(layout.e.build(hash));
const raw = await this.db.get(layout.e.encode(hash));
if (!raw)
return null;
@ -549,7 +549,7 @@ class ChainDB {
*/
async getState() {
const data = await this.db.get(layout.R.build());
const data = await this.db.get(layout.R.encode());
if (!data)
return null;
@ -594,7 +594,7 @@ class ChainDB {
*/
async getFlags() {
const data = await this.db.get(layout.O.build());
const data = await this.db.get(layout.O.encode());
if (!data)
return null;
@ -668,7 +668,7 @@ class ChainDB {
});
for (const item of items) {
const [bit, hash] = layout.v.parse(item.key);
const [bit, hash] = layout.v.decode(item.key);
const state = item.value[0];
stateCache.insert(bit, hash, state);
}
@ -705,7 +705,7 @@ class ChainDB {
bw.writeI32(deployment.window);
}
b.put(layout.D.build(), bw.render());
b.put(layout.D.encode(), bw.render());
}
/**
@ -715,7 +715,7 @@ class ChainDB {
*/
async checkDeployments() {
const raw = await this.db.get(layout.D.build());
const raw = await this.db.get(layout.D.encode());
assert(raw, 'No deployment table found.');
@ -827,8 +827,8 @@ class ChainDB {
if (!hash)
throw new Error(`Cannot find hash for ${i}.`);
b.del(layout.b.build(hash));
b.del(layout.u.build(hash));
b.del(layout.b.encode(hash));
b.del(layout.u.encode(hash));
}
try {
@ -837,7 +837,7 @@ class ChainDB {
const flags = ChainFlags.fromOptions(options);
assert(flags.prune);
b.put(layout.O.build(), flags.encode());
b.put(layout.O.encode(), flags.encode());
await b.write();
} catch (e) {
@ -857,7 +857,7 @@ class ChainDB {
*/
async getNextHash(hash) {
return this.db.get(layout.n.build(hash));
return this.db.get(layout.n.encode(hash));
}
/**
@ -961,7 +961,7 @@ class ChainDB {
return this.db.keys({
gte: layout.p.min(),
lte: layout.p.max(),
parse: key => layout.p.parse(key)
parse: key => layout.p.decode(key)[0]
});
}
@ -985,7 +985,7 @@ class ChainDB {
if (cache)
return CoinEntry.decode(cache);
const raw = await this.db.get(layout.c.build(hash, index));
const raw = await this.db.get(layout.c.encode(hash, index));
if (!raw)
return null;
@ -1022,7 +1022,7 @@ class ChainDB {
async hasCoins(tx) {
for (let i = 0; i < tx.outputs.length; i++) {
const key = layout.c.build(tx.hash(), i);
const key = layout.c.encode(tx.hash(), i);
if (await this.db.has(key))
return true;
}
@ -1083,7 +1083,7 @@ class ChainDB {
*/
async getUndoCoins(hash) {
const data = await this.db.get(layout.u.build(hash));
const data = await this.db.get(layout.u.encode(hash));
if (!data)
return new UndoCoins();
@ -1182,7 +1182,7 @@ class ChainDB {
if (!hash)
return null;
return this.db.get(layout.b.build(hash));
return this.db.get(layout.b.encode(hash));
}
/**
@ -1223,7 +1223,7 @@ class ChainDB {
if (!this.options.indexTX)
return null;
const data = await this.db.get(layout.t.build(hash));
const data = await this.db.get(layout.t.encode(hash));
if (!data)
return null;
@ -1255,7 +1255,7 @@ class ChainDB {
if (!this.options.indexTX)
return false;
return this.db.has(layout.t.build(hash));
return this.db.has(layout.t.encode(hash));
}
/**
@ -1280,7 +1280,7 @@ class ChainDB {
gte: layout.C.min(hash),
lte: layout.C.max(hash),
parse: (key) => {
const [, txid, index] = layout.C.parse(key);
const [, txid, index] = layout.C.decode(key);
return [txid, index];
}
});
@ -1314,7 +1314,7 @@ class ChainDB {
gte: layout.T.min(hash),
lte: layout.T.max(hash),
parse: (key) => {
const [, txid] = layout.T.parse(key);
const [, txid] = layout.T.decode(key);
hashes.add(txid);
}
});
@ -1458,15 +1458,15 @@ class ChainDB {
const hash = block.hash();
// Hash->height index.
this.put(layout.h.build(hash), fromU32(entry.height));
this.put(layout.h.encode(hash), fromU32(entry.height));
// Entry data.
this.put(layout.e.build(hash), entry.encode());
this.put(layout.e.encode(hash), entry.encode());
this.cacheHash.push(entry.hash, entry);
// Tip index.
this.del(layout.p.build(entry.prevBlock));
this.put(layout.p.build(hash), null);
this.del(layout.p.encode(entry.prevBlock));
this.put(layout.p.encode(hash), null);
// Update state caches.
this.saveUpdates();
@ -1479,17 +1479,17 @@ class ChainDB {
// Hash->next-block index.
if (!entry.isGenesis())
this.put(layout.n.build(entry.prevBlock), hash);
this.put(layout.n.encode(entry.prevBlock), hash);
// Height->hash index.
this.put(layout.H.build(entry.height), hash);
this.put(layout.H.encode(entry.height), hash);
this.cacheHeight.push(entry.height, entry);
// Connect block and save data.
await this.saveBlock(entry, block, view);
// Commit new chain state.
this.put(layout.R.build(), this.pending.commit(hash));
this.put(layout.R.encode(), this.pending.commit(hash));
}
/**
@ -1526,10 +1526,10 @@ class ChainDB {
assert(!entry.isGenesis());
// We can now add a hash->next-block index.
this.put(layout.n.build(entry.prevBlock), hash);
this.put(layout.n.encode(entry.prevBlock), hash);
// We can now add a height->hash index.
this.put(layout.H.build(entry.height), hash);
this.put(layout.H.encode(entry.height), hash);
this.cacheHeight.push(entry.height, entry);
// Re-insert into cache.
@ -1542,7 +1542,7 @@ class ChainDB {
await this.connectBlock(entry, block, view);
// Update chain state.
this.put(layout.R.build(), this.pending.commit(hash));
this.put(layout.R.encode(), this.pending.commit(hash));
}
/**
@ -1578,10 +1578,10 @@ class ChainDB {
async _disconnect(entry, block) {
// Remove hash->next-block index.
this.del(layout.n.build(entry.prevBlock));
this.del(layout.n.encode(entry.prevBlock));
// Remove height->hash index.
this.del(layout.H.build(entry.height));
this.del(layout.H.encode(entry.height));
this.cacheHeight.unpush(entry.height);
// Update state caches.
@ -1591,7 +1591,7 @@ class ChainDB {
const view = await this.disconnectBlock(entry, block);
// Revert chain state to previous tip.
this.put(layout.R.build(), this.pending.commit(entry.prevBlock));
this.put(layout.R.encode(), this.pending.commit(entry.prevBlock));
return view;
}
@ -1611,7 +1611,7 @@ class ChainDB {
for (const update of updates) {
const {bit, hash} = update;
this.put(layout.v.build(bit, hash), update.encode());
this.put(layout.v.encode(bit, hash), update.encode());
}
}
@ -1650,7 +1650,7 @@ class ChainDB {
// Stop once we hit our target tip.
if (tip.hash.equals(entry.hash)) {
this.put(layout.R.build(), this.pending.commit(tip.hash));
this.put(layout.R.encode(), this.pending.commit(tip.hash));
await this.commit();
break;
}
@ -1658,15 +1658,15 @@ class ChainDB {
assert(!tip.isGenesis());
// Revert the tip index.
this.del(layout.p.build(tip.hash));
this.put(layout.p.build(tip.prevBlock), null);
this.del(layout.p.encode(tip.hash));
this.put(layout.p.encode(tip.prevBlock), null);
// Remove all records (including
// main-chain-only records).
this.del(layout.H.build(tip.height));
this.del(layout.h.build(tip.hash));
this.del(layout.e.build(tip.hash));
this.del(layout.n.build(tip.prevBlock));
this.del(layout.H.encode(tip.height));
this.del(layout.h.encode(tip.hash));
this.del(layout.e.encode(tip.hash));
this.del(layout.n.encode(tip.prevBlock));
// Disconnect and remove block data.
try {
@ -1677,7 +1677,7 @@ class ChainDB {
}
// Revert chain state to previous tip.
this.put(layout.R.build(), this.pending.commit(tip.prevBlock));
this.put(layout.R.encode(), this.pending.commit(tip.prevBlock));
await this.commit();
@ -1737,10 +1737,10 @@ class ChainDB {
assert(!tip.isGenesis());
// Remove all non-main-chain records.
this.del(layout.p.build(tip.hash));
this.del(layout.h.build(tip.hash));
this.del(layout.e.build(tip.hash));
this.del(layout.b.build(tip.hash));
this.del(layout.p.encode(tip.hash));
this.del(layout.h.encode(tip.hash));
this.del(layout.e.encode(tip.hash));
this.del(layout.b.encode(tip.hash));
// Queue up hash to be removed
// on successful write.
@ -1768,7 +1768,7 @@ class ChainDB {
// Write actual block data (this may be
// better suited to flat files in the future).
this.put(layout.b.build(hash), block.encode());
this.put(layout.b.encode(hash), block.encode());
if (!view)
return undefined;
@ -1792,7 +1792,7 @@ class ChainDB {
if (!block)
throw new Error('Block not found.');
this.del(layout.b.build(block.hash()));
this.del(layout.b.encode(block.hash()));
return this.disconnectBlock(entry, block);
}
@ -1807,7 +1807,7 @@ class ChainDB {
for (const [hash, coins] of view.map) {
for (const [index, coin] of coins.outputs) {
if (coin.spent) {
this.del(layout.c.build(hash, index));
this.del(layout.c.encode(hash, index));
if (this.coinCache.capacity > 0)
this.coinCache.unpush(Outpoint.toKey(hash, index));
continue;
@ -1815,7 +1815,7 @@ class ChainDB {
const raw = coin.encode();
this.put(layout.c.build(hash, index), raw);
this.put(layout.c.encode(hash, index), raw);
if (this.coinCache.capacity > 0)
this.coinCache.push(Outpoint.toKey(hash, index), raw);
@ -1843,7 +1843,7 @@ class ChainDB {
}
if ((height % this.network.names.treeInterval) === 0)
this.put(layout.s.build(), await this.txn.commit());
this.put(layout.s.encode(), await this.txn.commit());
}
/**
@ -1857,9 +1857,9 @@ class ChainDB {
const undo = view.toNameUndo();
if (undo.names.length === 0)
this.del(layout.w.build(height));
this.del(layout.w.encode(height));
else
this.put(layout.w.build(height), undo.encode());
this.put(layout.w.encode(height), undo.encode());
return this.saveNames(view, height);
}
@ -1872,7 +1872,7 @@ class ChainDB {
*/
async disconnectNames(view, height) {
const raw = await this.db.get(layout.w.build(height));
const raw = await this.db.get(layout.w.encode(height));
if (raw) {
const undo = NameUndo.decode(raw);
@ -1883,7 +1883,7 @@ class ChainDB {
ns.applyState(delta);
}
this.del(layout.w.build(height));
this.del(layout.w.encode(height));
}
return this.saveNames(view, height - 1);
@ -1943,7 +1943,7 @@ class ChainDB {
// Write undo coins (if there are any).
if (!view.undo.isEmpty())
this.put(layout.u.build(hash), view.undo.commit());
this.put(layout.u.encode(hash), view.undo.commit());
// Prune height-288 if pruning is enabled.
await this.pruneBlock(entry);
@ -2016,7 +2016,7 @@ class ChainDB {
this.saveView(view);
// Remove undo coins.
this.del(layout.u.build(hash));
this.del(layout.u.encode(hash));
// Connect name state.
await this.disconnectNames(view, entry.height);
@ -2049,8 +2049,8 @@ class ChainDB {
if (!hash)
return;
this.del(layout.b.build(hash));
this.del(layout.u.build(hash));
this.del(layout.b.encode(hash));
this.del(layout.u.encode(hash));
}
/**
@ -2061,7 +2061,7 @@ class ChainDB {
saveFlags() {
const flags = ChainFlags.fromOptions(this.options);
const b = this.db.batch();
b.put(layout.O.build(), flags.encode());
b.put(layout.O.encode(), flags.encode());
return b.write();
}
@ -2080,11 +2080,11 @@ class ChainDB {
if (this.options.indexTX) {
const meta = TXMeta.fromTX(tx, entry, index);
this.put(layout.t.build(hash), meta.encode());
this.put(layout.t.encode(hash), meta.encode());
if (this.options.indexAddress) {
for (const addr of tx.getHashes(view))
this.put(layout.T.build(addr, hash), null);
this.put(layout.T.encode(addr, hash), null);
}
}
@ -2102,7 +2102,7 @@ class ChainDB {
if (!addr)
continue;
this.del(layout.C.build(addr, hash, index));
this.del(layout.C.encode(addr, hash, index));
}
}
@ -2113,7 +2113,7 @@ class ChainDB {
if (!addr)
continue;
this.put(layout.C.build(addr, hash, i), null);
this.put(layout.C.encode(addr, hash, i), null);
}
}
@ -2128,10 +2128,10 @@ class ChainDB {
const hash = tx.hash();
if (this.options.indexTX) {
this.del(layout.t.build(hash));
this.del(layout.t.encode(hash));
if (this.options.indexAddress) {
for (const addr of tx.getHashes(view))
this.del(layout.T.build(addr, hash));
this.del(layout.T.encode(addr, hash));
}
}
@ -2149,7 +2149,7 @@ class ChainDB {
if (!addr)
continue;
this.put(layout.C.build(addr, hash, index), null);
this.put(layout.C.encode(addr, hash, index), null);
}
}
@ -2160,7 +2160,7 @@ class ChainDB {
if (!addr)
continue;
this.del(layout.C.build(addr, hash, i));
this.del(layout.C.encode(addr, hash, i));
}
}
}

View file

@ -8,7 +8,7 @@
const assert = require('bsert');
const bio = require('bufio');
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
const {Solution} = require('bcuckoo');
const consensus = require('../protocol/consensus');
const Headers = require('../primitives/headers');

View file

@ -35,18 +35,18 @@ const layout = {
O: bdb.key('O'),
R: bdb.key('R'),
D: bdb.key('D'),
e: bdb.key('e', ['bhash256']),
h: bdb.key('h', ['bhash256']),
e: bdb.key('e', ['hash256']),
h: bdb.key('h', ['hash256']),
H: bdb.key('H', ['uint32']),
n: bdb.key('n', ['bhash256']),
p: bdb.key('p', ['bhash256']),
b: bdb.key('b', ['bhash256']),
t: bdb.key('t', ['bhash256']),
c: bdb.key('c', ['bhash256', 'uint32']),
u: bdb.key('u', ['bhash256']),
v: bdb.key('v', ['uint8', 'bhash256']),
T: bdb.key('T', ['bhash', 'bhash256']),
C: bdb.key('C', ['bhash', 'bhash256', 'uint32']),
n: bdb.key('n', ['hash256']),
p: bdb.key('p', ['hash256']),
b: bdb.key('b', ['hash256']),
t: bdb.key('t', ['hash256']),
c: bdb.key('c', ['hash256', 'uint32']),
u: bdb.key('u', ['hash256']),
v: bdb.key('v', ['uint8', 'hash256']),
T: bdb.key('T', ['hash', 'hash256']),
C: bdb.key('C', ['hash', 'hash256', 'uint32']),
w: bdb.key('w', ['uint32']),
s: bdb.key('s')
};

View file

@ -191,6 +191,9 @@ class RootServer extends DNSServer {
if (!this.lookup)
throw new Error('Tree not available.');
if (!rules.verifyName(name))
return null;
const hash = rules.hashName(name);
const data = await this.lookup(hash);

View file

@ -96,7 +96,6 @@ hsd.policy = require('./protocol/policy');
// Script
hsd.script = require('./script');
hsd.Opcode = require('./script/opcode');
hsd.Program = require('./script/program');
hsd.Script = require('./script/script');
hsd.ScriptNum = require('./script/scriptnum');
hsd.SigCache = require('./script/sigcache');

View file

@ -115,7 +115,6 @@ hsd.define('policy', './protocol/policy');
// Script
hsd.define('script', './script');
hsd.define('Opcode', './script/opcode');
hsd.define('Program', './script/program');
hsd.define('Script', './script/script');
hsd.define('ScriptNum', './script/scriptnum');
hsd.define('SigCache', './script/sigcache');

View file

@ -21,7 +21,7 @@ const layout = {
v: bdb.key('v'),
R: bdb.key('R'),
F: bdb.key('F'),
e: bdb.key('e', ['bhash256'])
e: bdb.key('e', ['hash256'])
};
/*

View file

@ -2784,7 +2784,7 @@ class MempoolCache {
}
async getVersion() {
const data = await this.db.get(layout.v.build());
const data = await this.db.get(layout.v.encode());
if (!data)
return -1;
@ -2793,7 +2793,7 @@ class MempoolCache {
}
async getTip() {
const tip = await this.db.get(layout.R.build());
const tip = await this.db.get(layout.R.encode());
if (!tip)
return consensus.ZERO_HASH;
@ -2802,7 +2802,7 @@ class MempoolCache {
}
async getFees() {
const data = await this.db.get(layout.F.build());
const data = await this.db.get(layout.F.encode());
if (!data)
return null;
@ -2840,7 +2840,7 @@ class MempoolCache {
return;
await this.db.open();
await this.db.verify(layout.V.build(), 'mempool', 0);
await this.db.verify(layout.V.encode(), 'mempool', 0);
await this.verify();
@ -2860,28 +2860,28 @@ class MempoolCache {
if (!this.db)
return;
this.batch.put(layout.e.build(entry.hash()), entry.encode());
this.batch.put(layout.e.encode(entry.hash()), entry.encode());
}
remove(hash) {
if (!this.db)
return;
this.batch.del(layout.e.build(hash));
this.batch.del(layout.e.encode(hash));
}
sync(tip) {
if (!this.db)
return;
this.batch.put(layout.R.build(), tip);
this.batch.put(layout.R.encode(), tip);
}
writeFees(fees) {
if (!this.db)
return;
this.batch.put(layout.F.build(), fees.encode());
this.batch.put(layout.F.encode(), fees.encode());
}
clear() {
@ -2900,8 +2900,8 @@ class MempoolCache {
async init(hash) {
const batch = this.db.batch();
batch.put(layout.v.build(), fromU32(MempoolCache.VERSION));
batch.put(layout.R.build(), hash);
batch.put(layout.v.encode(), fromU32(MempoolCache.VERSION));
batch.put(layout.R.encode(), hash);
await batch.write();
}
@ -2952,9 +2952,9 @@ class MempoolCache {
for (const key of keys)
batch.del(key);
batch.put(layout.v.build(), fromU32(MempoolCache.VERSION));
batch.put(layout.R.build(), this.chain.tip.hash);
batch.del(layout.F.build());
batch.put(layout.v.encode(), fromU32(MempoolCache.VERSION));
batch.put(layout.R.encode(), this.chain.tip.hash);
batch.del(layout.F.encode());
await batch.write();

View file

@ -8,7 +8,7 @@
const assert = require('bsert');
const consensus = require('../protocol/consensus');
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
/**
* @exports mining/common

View file

@ -192,12 +192,14 @@ class HTTP extends Server {
const addressStrings = valid.array('addresses');
enforce(addressStrings, 'Addresses is required.');
addressStrings.forEach(addrString => {
enforce(typeof addrString === 'string', 'Address should be string.');
});
enforce(!this.chain.options.spv, 'Cannot get coins in SPV mode.');
const addresses = addressStrings.map(addrString => Address.fromString(addrString));
const addresses = [];
for (const addrString of addressStrings) {
enforce(typeof addrString === 'string', 'Address should be string.');
addresses.push(Address.fromString(addrString));
}
const coins = await this.node.getCoinsByAddress(addresses);
const result = [];
@ -253,12 +255,14 @@ class HTTP extends Server {
const addressStrings = valid.array('addresses');
enforce(addressStrings, 'Addresses is required.');
addressStrings.forEach(addrString => {
enforce(typeof addrString === 'string', 'Address should be string.');
});
enforce(!this.chain.options.spv, 'Cannot get TX in SPV mode.');
const addresses = addressStrings.map(addrString => Address.fromString(addrString));
const addresses = [];
for (const addrString of addressStrings) {
enforce(typeof addrString === 'string', 'Address should be string.');
addresses.push(Address.fromString(addrString));
}
const metas = await this.node.getMetaByAddress(addresses);
const result = [];

View file

@ -11,7 +11,7 @@
*/
const assert = require('bsert');
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
const {Cuckoo, Solution, codes} = require('bcuckoo');
/**

View file

@ -12,7 +12,7 @@
* @module protocol/networks
*/
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
const genesis = require('./genesis');
const network = exports;

View file

@ -35,9 +35,9 @@ exports.wdb = {
O: bdb.key('O'),
R: bdb.key('R'),
D: bdb.key('D'),
p: bdb.key('p', ['bhash']),
P: bdb.key('P', ['uint32', 'bhash']),
r: bdb.key('r', ['uint32', 'uint32', 'bhash']),
p: bdb.key('p', ['hash']),
P: bdb.key('P', ['uint32', 'hash']),
r: bdb.key('r', ['uint32', 'uint32', 'hash']),
w: bdb.key('w', ['uint32']),
W: bdb.key('W', ['uint32']),
l: bdb.key('l', ['ascii']),
@ -46,12 +46,12 @@ exports.wdb = {
n: bdb.key('n', ['uint32', 'uint32']),
h: bdb.key('h', ['uint32']),
b: bdb.key('b', ['uint32']),
o: bdb.key('o', ['bhash256', 'uint32']),
T: bdb.key('T', ['bhash256']),
o: bdb.key('o', ['hash256', 'uint32']),
T: bdb.key('T', ['hash256']),
t: bdb.key('t', ['uint32']),
// Name Map
N: bdb.key('N', ['bhash256'])
N: bdb.key('N', ['hash256'])
};
/*
@ -77,29 +77,29 @@ exports.txdb = {
prefix: bdb.key('t', ['uint32']),
R: bdb.key('R'),
r: bdb.key('r', ['uint32']),
t: bdb.key('t', ['bhash256']),
c: bdb.key('c', ['bhash256', 'uint32']),
d: bdb.key('d', ['bhash256', 'uint32']),
s: bdb.key('s', ['bhash256', 'uint32']),
p: bdb.key('p', ['bhash256']),
m: bdb.key('m', ['uint32', 'bhash256']),
h: bdb.key('h', ['uint32', 'bhash256']),
T: bdb.key('T', ['uint32', 'bhash256']),
P: bdb.key('P', ['uint32', 'bhash256']),
M: bdb.key('M', ['uint32', 'uint32', 'bhash256']),
H: bdb.key('H', ['uint32', 'uint32', 'bhash256']),
C: bdb.key('C', ['uint32', 'bhash256', 'uint32']),
t: bdb.key('t', ['hash256']),
c: bdb.key('c', ['hash256', 'uint32']),
d: bdb.key('d', ['hash256', 'uint32']),
s: bdb.key('s', ['hash256', 'uint32']),
p: bdb.key('p', ['hash256']),
m: bdb.key('m', ['uint32', 'hash256']),
h: bdb.key('h', ['uint32', 'hash256']),
T: bdb.key('T', ['uint32', 'hash256']),
P: bdb.key('P', ['uint32', 'hash256']),
M: bdb.key('M', ['uint32', 'uint32', 'hash256']),
H: bdb.key('H', ['uint32', 'uint32', 'hash256']),
C: bdb.key('C', ['uint32', 'hash256', 'uint32']),
b: bdb.key('b', ['uint32']),
// Name records
A: bdb.key('A', ['bhash256']),
A: bdb.key('A', ['hash256']),
// Name undo records
U: bdb.key('U', ['bhash256']),
U: bdb.key('U', ['hash256']),
// Bids
i: bdb.key('i', ['bhash256', 'bhash256', 'uint32']),
i: bdb.key('i', ['hash256', 'hash256', 'uint32']),
// Reveals
B: bdb.key('B', ['bhash256', 'bhash256', 'uint32']),
B: bdb.key('B', ['hash256', 'hash256', 'uint32']),
// Blinds
v: bdb.key('v', ['bhash256']),
v: bdb.key('v', ['hash256']),
// Opens
o: bdb.key('o', ['bhash256'])
o: bdb.key('o', ['hash256'])
};

View file

@ -1877,17 +1877,18 @@ class RPC extends RPCBase {
}
async sendOpen(args, help) {
if (help || args.length !== 1)
throw new RPCError(errs.MISC_ERROR, 'sendopen "name"');
if (help || args.length < 1 || args.length > 2)
throw new RPCError(errs.MISC_ERROR, 'sendopen "name" ( force )');
const wallet = this.wallet;
const valid = new Validator(args);
const name = valid.str(0);
const force = valid.bool(1, false);
if (!name || !rules.verifyName(name))
throw new RPCError(errs.TYPE_ERROR, 'Invalid name.');
const tx = await wallet.sendOpen(name);
const tx = await wallet.sendOpen(name, force);
return tx.getJSON(this.network);
}

View file

@ -59,7 +59,7 @@ class TXDB {
*/
async open(wallet) {
const prefix = layout.prefix.build(wallet.wid);
const prefix = layout.prefix.encode(wallet.wid);
this.wid = wallet.wid;
this.bucket = this.db.bucket(prefix);
@ -118,8 +118,8 @@ class TXDB {
async saveCredit(b, credit, path) {
const {coin} = credit;
b.put(layout.c.build(coin.hash, coin.index), credit.encode());
b.put(layout.C.build(path.account, coin.hash, coin.index), null);
b.put(layout.c.encode(coin.hash, coin.index), credit.encode());
b.put(layout.C.encode(path.account, coin.hash, coin.index), null);
return this.addOutpointMap(b, coin.hash, coin.index);
}
@ -133,8 +133,8 @@ class TXDB {
async removeCredit(b, credit, path) {
const {coin} = credit;
b.del(layout.c.build(coin.hash, coin.index));
b.del(layout.C.build(path.account, coin.hash, coin.index));
b.del(layout.c.encode(coin.hash, coin.index));
b.del(layout.C.encode(path.account, coin.hash, coin.index));
return this.removeOutpointMap(b, coin.hash, coin.index);
}
@ -149,8 +149,8 @@ class TXDB {
spendCredit(b, credit, tx, index) {
const prevout = tx.inputs[index].prevout;
const spender = Outpoint.fromTX(tx, index);
b.put(layout.s.build(prevout.hash, prevout.index), spender.encode());
b.put(layout.d.build(spender.hash, spender.index), credit.coin.encode());
b.put(layout.s.encode(prevout.hash, prevout.index), spender.encode());
b.put(layout.d.encode(spender.hash, spender.index), credit.coin.encode());
}
/**
@ -162,8 +162,8 @@ class TXDB {
unspendCredit(b, tx, index) {
const prevout = tx.inputs[index].prevout;
const spender = Outpoint.fromTX(tx, index);
b.del(layout.s.build(prevout.hash, prevout.index));
b.del(layout.d.build(spender.hash, spender.index));
b.del(layout.s.encode(prevout.hash, prevout.index));
b.del(layout.d.encode(spender.hash, spender.index));
}
/**
@ -175,7 +175,7 @@ class TXDB {
async writeInput(b, tx, index) {
const prevout = tx.inputs[index].prevout;
const spender = Outpoint.fromTX(tx, index);
b.put(layout.s.build(prevout.hash, prevout.index), spender.encode());
b.put(layout.s.encode(prevout.hash, prevout.index), spender.encode());
return this.addOutpointMap(b, prevout.hash, prevout.index);
}
@ -187,7 +187,7 @@ class TXDB {
async removeInput(b, tx, index) {
const prevout = tx.inputs[index].prevout;
b.del(layout.s.build(prevout.hash, prevout.index));
b.del(layout.s.encode(prevout.hash, prevout.index));
return this.removeOutpointMap(b, prevout.hash, prevout.index);
}
@ -199,7 +199,7 @@ class TXDB {
async updateBalance(b, state) {
const balance = await this.getWalletBalance();
state.applyTo(balance);
b.put(layout.R.build(), balance.encode());
b.put(layout.R.encode(), balance.encode());
return balance;
}
@ -212,7 +212,7 @@ class TXDB {
async updateAccountBalance(b, acct, delta) {
const balance = await this.getAccountBalance(acct);
delta.applyTo(balance);
b.put(layout.r.build(acct), balance.encode());
b.put(layout.r.encode(acct), balance.encode());
return balance;
}
@ -224,7 +224,7 @@ class TXDB {
*/
async getSpent(hash, index) {
const data = await this.bucket.get(layout.s.build(hash, index));
const data = await this.bucket.get(layout.s.encode(hash, index));
if (!data)
return null;
@ -240,7 +240,7 @@ class TXDB {
*/
isSpent(hash, index) {
return this.bucket.has(layout.s.build(hash, index));
return this.bucket.has(layout.s.encode(hash, index));
}
/**
@ -336,7 +336,7 @@ class TXDB {
return this.bucket.keys({
gte: layout.b.min(),
lte: layout.b.max(),
parse: key => layout.b.parse(key)
parse: key => layout.b.decode(key)[0]
});
}
@ -347,7 +347,7 @@ class TXDB {
*/
async getBlock(height) {
const data = await this.bucket.get(layout.b.build(height));
const data = await this.bucket.get(layout.b.encode(height));
if (!data)
return null;
@ -363,7 +363,7 @@ class TXDB {
*/
async addBlock(b, hash, block) {
const key = layout.b.build(block.height);
const key = layout.b.encode(block.height);
const data = await this.bucket.get(key);
if (!data) {
@ -391,7 +391,7 @@ class TXDB {
*/
async removeBlock(b, hash, height) {
const key = layout.b.build(height);
const key = layout.b.encode(height);
const data = await this.bucket.get(key);
if (!data)
@ -430,11 +430,11 @@ class TXDB {
return;
if (block.hashes.size === 0) {
b.del(layout.b.build(height));
b.del(layout.b.encode(height));
return;
}
b.put(layout.b.build(height), block.encode());
b.put(layout.b.encode(height), block.encode());
}
/**
@ -444,7 +444,7 @@ class TXDB {
*/
async hasNameState(nameHash) {
return this.bucket.has(layout.A.build(nameHash));
return this.bucket.has(layout.A.encode(nameHash));
}
/**
@ -454,7 +454,7 @@ class TXDB {
*/
async getNameState(nameHash) {
const raw = await this.bucket.get(layout.A.build(nameHash));
const raw = await this.bucket.get(layout.A.encode(nameHash));
if (!raw)
return null;
@ -480,7 +480,7 @@ class TXDB {
const names = [];
await iter.each((key, raw) => {
const nameHash = layout.A.parse(key);
const [nameHash] = layout.A.decode(key);
const ns = NameState.decode(raw);
ns.nameHash = nameHash;
names.push(ns);
@ -498,7 +498,7 @@ class TXDB {
async hasBid(nameHash, outpoint) {
const {hash, index} = outpoint;
return this.bucket.has(layout.i.build(nameHash, hash, index));
return this.bucket.has(layout.i.encode(nameHash, hash, index));
}
/**
@ -510,7 +510,7 @@ class TXDB {
async getBid(nameHash, outpoint) {
const {hash, index} = outpoint;
const raw = await this.bucket.get(layout.i.build(nameHash, hash, index));
const raw = await this.bucket.get(layout.i.encode(nameHash, hash, index));
if (!raw)
return null;
@ -538,7 +538,7 @@ class TXDB {
bb.lockup = options.lockup;
bb.blind = options.blind;
bb.own = options.own;
b.put(layout.i.build(nameHash, hash, index), bb.encode());
b.put(layout.i.encode(nameHash, hash, index), bb.encode());
}
/**
@ -550,7 +550,7 @@ class TXDB {
removeBid(b, nameHash, outpoint) {
const {hash, index} = outpoint;
b.del(layout.i.build(nameHash, hash, index));
b.del(layout.i.encode(nameHash, hash, index));
}
/**
@ -569,7 +569,7 @@ class TXDB {
const bids = [];
await iter.each(async (key, raw) => {
const [nameHash, hash, index] = layout.i.parse(key);
const [nameHash, hash, index] = layout.i.decode(key);
const bb = BlindBid.decode(raw);
bb.nameHash = nameHash;
@ -609,7 +609,7 @@ class TXDB {
async hasReveal(nameHash, outpoint) {
const {hash, index} = outpoint;
return this.bucket.has(layout.B.build(nameHash, hash, index));
return this.bucket.has(layout.B.encode(nameHash, hash, index));
}
/**
@ -621,7 +621,7 @@ class TXDB {
async getReveal(nameHash, outpoint) {
const {hash, index} = outpoint;
const raw = await this.bucket.get(layout.B.build(nameHash, hash, index));
const raw = await this.bucket.get(layout.B.encode(nameHash, hash, index));
if (!raw)
return null;
@ -649,7 +649,7 @@ class TXDB {
brv.value = options.value;
brv.height = options.height;
brv.own = options.own;
b.put(layout.B.build(nameHash, hash, index), brv.encode());
b.put(layout.B.encode(nameHash, hash, index), brv.encode());
}
/**
@ -661,7 +661,7 @@ class TXDB {
removeReveal(b, nameHash, outpoint) {
const {hash, index} = outpoint;
b.del(layout.B.build(nameHash, hash, index));
b.del(layout.B.encode(nameHash, hash, index));
}
/**
@ -680,7 +680,7 @@ class TXDB {
const reveals = [];
await iter.each(async (key, raw) => {
const [nameHash, hash, index] = layout.B.parse(key);
const [nameHash, hash, index] = layout.B.decode(key);
const brv = BidReveal.decode(raw);
brv.nameHash = nameHash;
brv.prevout = new Outpoint(hash, index);
@ -712,7 +712,7 @@ class TXDB {
*/
async hasBlind(blind) {
return this.bucket.has(layout.v.build(blind));
return this.bucket.has(layout.v.encode(blind));
}
/**
@ -722,7 +722,7 @@ class TXDB {
*/
async getBlind(blind) {
const raw = await this.bucket.get(layout.v.build(blind));
const raw = await this.bucket.get(layout.v.encode(blind));
if (!raw)
return null;
@ -742,7 +742,7 @@ class TXDB {
const bv = new BlindValue();
bv.value = value;
bv.nonce = nonce;
b.put(layout.v.build(blind), bv.encode());
b.put(layout.v.encode(blind), bv.encode());
}
/**
@ -764,7 +764,7 @@ class TXDB {
*/
removeBlind(b, blind) {
b.del(layout.v.build(blind));
b.del(layout.v.encode(blind));
}
/**
@ -826,7 +826,7 @@ class TXDB {
continue;
const nameHash = covenant.getHash(0);
const key = layout.o.build(nameHash);
const key = layout.o.encode(nameHash);
if (await this.bucket.has(key))
return true;
@ -847,7 +847,7 @@ class TXDB {
continue;
const nameHash = covenant.getHash(0);
const key = layout.o.build(nameHash);
const key = layout.o.encode(nameHash);
const hash = await this.bucket.get(key);
if (!hash)
@ -870,7 +870,7 @@ class TXDB {
continue;
const nameHash = covenant.getHash(0);
const key = layout.o.build(nameHash);
const key = layout.o.encode(nameHash);
b.put(key, tx.hash());
}
@ -889,7 +889,7 @@ class TXDB {
continue;
const nameHash = covenant.getHash(0);
const key = layout.o.build(nameHash);
const key = layout.o.encode(nameHash);
b.del(key);
}
@ -1018,13 +1018,13 @@ class TXDB {
this.indexOpens(b, tx);
// Save and index the transaction record.
b.put(layout.t.build(hash), wtx.encode());
b.put(layout.m.build(wtx.mtime, hash), null);
b.put(layout.t.encode(hash), wtx.encode());
b.put(layout.m.encode(wtx.mtime, hash), null);
if (!block)
b.put(layout.p.build(hash), null);
b.put(layout.p.encode(hash), null);
else
b.put(layout.h.build(height, hash), null);
b.put(layout.h.encode(height, hash), null);
// Do some secondary indexing for account-based
// queries. This saves us a lot of time for
@ -1032,13 +1032,13 @@ class TXDB {
for (const [acct, delta] of state.accounts) {
await this.updateAccountBalance(b, acct, delta);
b.put(layout.T.build(acct, hash), null);
b.put(layout.M.build(acct, wtx.mtime, hash), null);
b.put(layout.T.encode(acct, hash), null);
b.put(layout.M.encode(acct, wtx.mtime, hash), null);
if (!block)
b.put(layout.P.build(acct, hash), null);
b.put(layout.P.encode(acct, hash), null);
else
b.put(layout.H.build(acct, height, hash), null);
b.put(layout.H.encode(acct, height, hash), null);
}
// Update block records.
@ -1181,15 +1181,15 @@ class TXDB {
// Save the new serialized transaction as
// the block-related properties have been
// updated. Also reindex for height.
b.put(layout.t.build(hash), wtx.encode());
b.del(layout.p.build(hash));
b.put(layout.h.build(height, hash), null);
b.put(layout.t.encode(hash), wtx.encode());
b.del(layout.p.encode(hash));
b.put(layout.h.encode(height, hash), null);
// Secondary indexing also needs to change.
for (const [acct, delta] of state.accounts) {
await this.updateAccountBalance(b, acct, delta);
b.del(layout.P.build(acct, hash));
b.put(layout.H.build(acct, height, hash), null);
b.del(layout.P.encode(acct, hash));
b.put(layout.H.encode(acct, height, hash), null);
}
await this.removeTXMap(b, hash);
@ -1311,25 +1311,25 @@ class TXDB {
// Remove the transaction data
// itself as well as unindex.
b.del(layout.t.build(hash));
b.del(layout.m.build(wtx.mtime, hash));
b.del(layout.t.encode(hash));
b.del(layout.m.encode(wtx.mtime, hash));
if (!block)
b.del(layout.p.build(hash));
b.del(layout.p.encode(hash));
else
b.del(layout.h.build(height, hash));
b.del(layout.h.encode(height, hash));
// Remove all secondary indexing.
for (const [acct, delta] of state.accounts) {
await this.updateAccountBalance(b, acct, delta);
b.del(layout.T.build(acct, hash));
b.del(layout.M.build(acct, wtx.mtime, hash));
b.del(layout.T.encode(acct, hash));
b.del(layout.M.encode(acct, wtx.mtime, hash));
if (!block)
b.del(layout.P.build(acct, hash));
b.del(layout.P.encode(acct, hash));
else
b.del(layout.H.build(acct, height, hash));
b.del(layout.H.encode(acct, height, hash));
}
// Update block records.
@ -1514,15 +1514,15 @@ class TXDB {
// We need to update the now-removed
// block properties and reindex due
// to the height change.
b.put(layout.t.build(hash), wtx.encode());
b.put(layout.p.build(hash), null);
b.del(layout.h.build(height, hash));
b.put(layout.t.encode(hash), wtx.encode());
b.put(layout.p.encode(hash), null);
b.del(layout.h.encode(height, hash));
// Secondary indexing also needs to change.
for (const [acct, delta] of state.accounts) {
await this.updateAccountBalance(b, acct, delta);
b.put(layout.P.build(acct, hash), null);
b.del(layout.H.build(acct, height, hash));
b.put(layout.P.encode(acct, hash), null);
b.del(layout.H.encode(acct, height, hash));
}
// Commit state due to unconfirmed
@ -1997,18 +1997,18 @@ class TXDB {
const {nameHash} = ns;
if (ns.isNull()) {
b.del(layout.A.build(nameHash));
b.del(layout.A.encode(nameHash));
continue;
}
b.put(layout.A.build(nameHash), ns.encode());
b.put(layout.A.encode(nameHash), ns.encode());
}
if (updated) {
const undo = view.toNameUndo();
if (undo.names.length > 0)
b.put(layout.U.build(hash), undo.encode());
b.put(layout.U.encode(hash), undo.encode());
}
return updated;
@ -2047,7 +2047,7 @@ class TXDB {
}
}
const raw = await this.bucket.get(layout.U.build(hash));
const raw = await this.bucket.get(layout.U.encode(hash));
if (!raw)
return;
@ -2061,12 +2061,12 @@ class TXDB {
ns.applyState(delta);
if (ns.isNull())
b.del(layout.A.build(nameHash));
b.del(layout.A.encode(nameHash));
else
b.put(layout.A.build(nameHash), ns.encode());
b.put(layout.A.encode(nameHash), ns.encode());
}
b.del(layout.U.build(hash));
b.del(layout.U.encode(hash));
}
/**
@ -2178,7 +2178,7 @@ class TXDB {
gte: layout.T.min(acct),
lte: layout.T.max(acct),
parse: (key) => {
const [, hash] = layout.T.parse(key);
const [, hash] = layout.T.decode(key);
return hash;
}
});
@ -2199,7 +2199,7 @@ class TXDB {
return this.bucket.keys({
gte: layout.t.min(),
lte: layout.t.max(),
parse: key => layout.t.parse(key)
parse: key => layout.t.decode(key)[0]
});
}
@ -2215,7 +2215,7 @@ class TXDB {
gte: layout.P.min(acct),
lte: layout.P.max(acct),
parse: (key) => {
const [, hash] = layout.P.parse(key);
const [, hash] = layout.P.decode(key);
return hash;
}
});
@ -2236,7 +2236,7 @@ class TXDB {
return this.bucket.keys({
gte: layout.p.min(),
lte: layout.p.max(),
parse: key => layout.p.parse(key)
parse: key => layout.p.decode(key)[0]
});
}
@ -2252,7 +2252,7 @@ class TXDB {
gte: layout.C.min(acct),
lte: layout.C.max(acct),
parse: (key) => {
const [, hash, index] = layout.C.parse(key);
const [, hash, index] = layout.C.decode(key);
return new Outpoint(hash, index);
}
});
@ -2274,7 +2274,7 @@ class TXDB {
gte: layout.c.min(),
lte: layout.c.max(),
parse: (key) => {
const [hash, index] = layout.c.parse(key);
const [hash, index] = layout.c.decode(key);
return new Outpoint(hash, index);
}
});
@ -2303,7 +2303,7 @@ class TXDB {
limit: options.limit,
reverse: options.reverse,
parse: (key) => {
const [,, hash] = layout.H.parse(key);
const [,, hash] = layout.H.decode(key);
return hash;
}
});
@ -2335,7 +2335,7 @@ class TXDB {
limit: options.limit,
reverse: options.reverse,
parse: (key) => {
const [, hash] = layout.h.parse(key);
const [, hash] = layout.h.decode(key);
return hash;
}
});
@ -2374,7 +2374,7 @@ class TXDB {
limit: options.limit,
reverse: options.reverse,
parse: (key) => {
const [,, hash] = layout.M.parse(key);
const [,, hash] = layout.M.decode(key);
return hash;
}
});
@ -2406,7 +2406,7 @@ class TXDB {
limit: options.limit,
reverse: options.reverse,
parse: (key) => {
const [, hash] = layout.m.parse(key);
const [, hash] = layout.m.decode(key);
return hash;
}
});
@ -2529,7 +2529,7 @@ class TXDB {
gte: layout.c.min(),
lte: layout.c.max(),
parse: (key, value) => {
const [hash, index] = layout.c.parse(key);
const [hash, index] = layout.c.decode(key);
const credit = Credit.decode(value);
credit.coin.hash = hash;
credit.coin.index = index;
@ -2577,7 +2577,7 @@ class TXDB {
gte: layout.d.min(hash),
lte: layout.d.max(hash),
parse: (key, value) => {
const [, index] = layout.d.parse(key);
const [, index] = layout.d.decode(key);
const coin = Coin.decode(value);
const input = tx.inputs[index];
assert(input);
@ -2711,7 +2711,7 @@ class TXDB {
*/
async getTX(hash) {
const raw = await this.bucket.get(layout.t.build(hash));
const raw = await this.bucket.get(layout.t.encode(hash));
if (!raw)
return null;
@ -2798,7 +2798,7 @@ class TXDB {
*/
hasTX(hash) {
return this.bucket.has(layout.t.build(hash));
return this.bucket.has(layout.t.encode(hash));
}
/**
@ -2825,7 +2825,7 @@ class TXDB {
*/
async getCredit(hash, index) {
const data = await this.bucket.get(layout.c.build(hash, index));
const data = await this.bucket.get(layout.c.encode(hash, index));
if (!data)
return null;
@ -2845,7 +2845,8 @@ class TXDB {
*/
async getSpentCoin(spent, prevout) {
const data = await this.bucket.get(layout.d.build(spent.hash, spent.index));
const key = layout.d.encode(spent.hash, spent.index);
const data = await this.bucket.get(key);
if (!data)
return null;
@ -2864,7 +2865,7 @@ class TXDB {
*/
hasSpentCoin(spent) {
return this.bucket.has(layout.d.build(spent.hash, spent.index));
return this.bucket.has(layout.d.encode(spent.hash, spent.index));
}
/**
@ -2889,7 +2890,7 @@ class TXDB {
coin.height = height;
b.put(layout.d.build(spent.hash, spent.index), coin.encode());
b.put(layout.d.encode(spent.hash, spent.index), coin.encode());
}
/**
@ -2899,7 +2900,7 @@ class TXDB {
*/
async hasCoin(hash, index) {
return this.bucket.has(layout.c.build(hash, index));
return this.bucket.has(layout.c.encode(hash, index));
}
/**
@ -2923,7 +2924,7 @@ class TXDB {
*/
async getWalletBalance() {
const data = await this.bucket.get(layout.R.build());
const data = await this.bucket.get(layout.R.encode());
if (!data)
return new Balance();
@ -2938,7 +2939,7 @@ class TXDB {
*/
async getAccountBalance(acct) {
const data = await this.bucket.get(layout.r.build(acct));
const data = await this.bucket.get(layout.r.encode(acct));
if (!data)
return new Balance(acct);
@ -2991,7 +2992,7 @@ class TXDB {
*/
async abandon(hash) {
const result = await this.bucket.has(layout.p.build(hash));
const result = await this.bucket.has(layout.p.encode(hash));
if (!result)
throw new Error('TX not eligible.');

View file

@ -1486,11 +1486,13 @@ class Wallet extends EventEmitter {
* Make a open MTX.
* @param {String} name
* @param {Number} acct
* @param {Boolean} force
* @returns {MTX}
*/
async makeOpen(name, acct) {
async makeOpen(name, force, acct) {
assert(typeof name === 'string');
assert(typeof force === 'boolean');
assert((acct >>> 0) === acct);
if (!rules.verifyName(name))
@ -1546,15 +1548,14 @@ class Wallet extends EventEmitter {
/**
* Create and finalize a open MTX.
* @param {String} name
* @param {Number} value
* @param {Number} lockup
* @param {Boolean} force
* @param {Object} options
* @returns {MTX}
*/
async createOpen(name, value, lockup, options) {
async createOpen(name, force, options) {
const acct = options ? options.account || 0 : 0;
const mtx = await this.makeOpen(name, acct);
const mtx = await this.makeOpen(name, force, acct);
await this.fill(mtx, options);
return this.finalize(mtx, options);
}
@ -1562,29 +1563,27 @@ class Wallet extends EventEmitter {
/**
* Create and send a open MTX.
* @param {String} name
* @param {Number} value
* @param {Number} lockup
* @param {Boolean} force
* @param {Object} options
*/
async _sendOpen(name, value, lockup, options) {
async _sendOpen(name, force, options) {
const passphrase = options ? options.passphrase : null;
const mtx = await this.createOpen(name, value, lockup, options);
const mtx = await this.createOpen(name, force, options);
return this.sendMTX(mtx, passphrase);
}
/**
* Create and send a open MTX.
* @param {String} name
* @param {Number} value
* @param {Number} lockup
* @param {Boolean} force
* @param {Object} options
*/
async sendOpen(name, value, lockup, options) {
async sendOpen(name, force, options) {
const unlock = await this.fundLock.lock();
try {
return await this._sendOpen(name, value, lockup, options);
return await this._sendOpen(name, force, options);
} finally {
unlock();
}

View file

@ -176,7 +176,7 @@ class WalletDB extends EventEmitter {
async open() {
await this.db.open();
await this.db.verify(layout.V.build(), 'wallet', 0);
await this.db.verify(layout.V.encode(), 'wallet', 0);
await this.verifyNetwork();
@ -213,11 +213,11 @@ class WalletDB extends EventEmitter {
*/
async verifyNetwork() {
const raw = await this.db.get(layout.O.build());
const raw = await this.db.get(layout.O.encode());
if (!raw) {
const b = this.db.batch();
b.put(layout.O.build(), fromU32(this.network.magic));
b.put(layout.O.encode(), fromU32(this.network.magic));
return b.write();
}
@ -260,7 +260,7 @@ class WalletDB extends EventEmitter {
let hashes = 0;
await piter.each((key) => {
const data = layout.p.parse(key);
const [data] = layout.p.decode(key);
this.filter.add(data);
@ -277,7 +277,7 @@ class WalletDB extends EventEmitter {
let outpoints = 0;
await oiter.each((key) => {
const [hash, index] = layout.o.parse(key);
const [hash, index] = layout.o.decode(key);
const outpoint = new Outpoint(hash, index);
const data = outpoint.encode();
@ -349,7 +349,7 @@ class WalletDB extends EventEmitter {
for (let height = 0; height < hashes.length; height++) {
const hash = hashes[height];
const meta = new BlockMeta(hash, height);
b.put(layout.h.build(height), meta.toHash());
b.put(layout.h.encode(height), meta.toHash());
tip = meta;
}
@ -361,7 +361,7 @@ class WalletDB extends EventEmitter {
state.height = tip.height;
state.marked = false;
b.put(layout.R.build(), state.encode());
b.put(layout.R.encode(), state.encode());
await b.write();
@ -603,7 +603,7 @@ class WalletDB extends EventEmitter {
*/
async getDepth() {
const raw = await this.db.get(layout.D.build());
const raw = await this.db.get(layout.D.encode());
if (!raw)
return 0;
@ -694,7 +694,7 @@ class WalletDB extends EventEmitter {
async ensureWID(id) {
if (typeof id === 'number') {
if (!await this.db.has(layout.W.build(id)))
if (!await this.db.has(layout.W.encode(id)))
return -1;
return id;
}
@ -709,7 +709,7 @@ class WalletDB extends EventEmitter {
*/
async getWID(id) {
const data = await this.db.get(layout.l.build(id));
const data = await this.db.get(layout.l.encode(id));
if (!data)
return -1;
@ -726,7 +726,7 @@ class WalletDB extends EventEmitter {
*/
async getID(wid) {
const data = await this.db.get(layout.W.build(wid));
const data = await this.db.get(layout.W.encode(wid));
if (!data)
return null;
@ -773,7 +773,7 @@ class WalletDB extends EventEmitter {
if (!id)
return null;
const data = await this.db.get(layout.w.build(wid));
const data = await this.db.get(layout.w.encode(wid));
assert(data);
const wallet = Wallet.decode(this, data);
@ -797,9 +797,9 @@ class WalletDB extends EventEmitter {
const wid = wallet.wid;
const id = wallet.id;
b.put(layout.w.build(wid), wallet.encode());
b.put(layout.W.build(wid), fromString(id));
b.put(layout.l.build(id), fromU32(wid));
b.put(layout.w.encode(wid), wallet.encode());
b.put(layout.W.encode(wid), fromString(id));
b.put(layout.l.encode(id), fromU32(wid));
}
/**
@ -809,7 +809,7 @@ class WalletDB extends EventEmitter {
*/
increment(b, wid) {
b.put(layout.D.build(), fromU32(wid + 1));
b.put(layout.D.encode(), fromU32(wid + 1));
}
/**
@ -846,13 +846,13 @@ class WalletDB extends EventEmitter {
const b = this.db.batch();
// Update wid->id index.
b.put(layout.W.build(wallet.wid), fromString(id));
b.put(layout.W.encode(wallet.wid), fromString(id));
// Delete old id->wid index.
b.del(layout.l.build(wallet.id));
b.del(layout.l.encode(wallet.id));
// Add new id->wid index.
b.put(layout.l.build(id), fromU32(wallet.wid));
b.put(layout.l.encode(id), fromU32(wallet.wid));
await b.write();
@ -870,13 +870,13 @@ class WalletDB extends EventEmitter {
const index = account.accountIndex;
// Remove old wid/name->account index.
b.del(layout.i.build(wid, account.name));
b.del(layout.i.encode(wid, account.name));
// Name->Index lookups
b.put(layout.i.build(wid, name), fromU32(index));
b.put(layout.i.encode(wid, name), fromU32(index));
// Index->Name lookups
b.put(layout.n.build(wid, index), fromString(name));
b.put(layout.n.encode(wid, index), fromString(name));
account.name = name;
}
@ -925,9 +925,9 @@ class WalletDB extends EventEmitter {
const b = this.db.batch();
b.del(layout.w.build(wid));
b.del(layout.W.build(wid));
b.del(layout.l.build(id));
b.del(layout.w.encode(wid));
b.del(layout.W.encode(wid));
b.del(layout.l.encode(id));
const piter = this.db.iterator({
gte: layout.P.min(wid),
@ -935,7 +935,7 @@ class WalletDB extends EventEmitter {
});
await piter.each((key, value) => {
const [, hash] = layout.P.parse(key);
const [, hash] = layout.P.decode(key);
b.del(key);
return this.removePathMap(b, hash, wid);
});
@ -965,11 +965,11 @@ class WalletDB extends EventEmitter {
});
await removeRange({
gt: layout.t.build(wid),
lt: layout.t.build(wid + 1)
gt: layout.t.encode(wid),
lt: layout.t.encode(wid + 1)
});
const bucket = this.db.bucket(layout.t.build(wid));
const bucket = this.db.bucket(layout.t.encode(wid));
const biter = bucket.iterator({
gte: tlayout.b.min(),
@ -977,7 +977,7 @@ class WalletDB extends EventEmitter {
});
await biter.each((key, value) => {
const height = tlayout.b.parse(key);
const [height] = tlayout.b.decode(key);
return this.removeBlockMap(b, height, wid);
});
@ -988,7 +988,7 @@ class WalletDB extends EventEmitter {
});
await siter.each((key, value) => {
const [hash, index] = tlayout.s.parse(key);
const [hash, index] = tlayout.s.decode(key);
return this.removeOutpointMap(b, hash, index, wid);
});
@ -999,7 +999,7 @@ class WalletDB extends EventEmitter {
});
await uiter.each((key, value) => {
const hash = tlayout.p.parse(key);
const [hash] = tlayout.p.decode(key);
return this.removeTXMap(b, hash, wid);
});
@ -1124,7 +1124,7 @@ class WalletDB extends EventEmitter {
if (!name)
return null;
const data = await this.db.get(layout.a.build(wid, index));
const data = await this.db.get(layout.a.encode(wid, index));
assert(data);
const account = Account.decode(this, data);
@ -1157,7 +1157,7 @@ class WalletDB extends EventEmitter {
*/
async getAccountIndex(wid, name) {
const index = await this.db.get(layout.i.build(wid, name));
const index = await this.db.get(layout.i.encode(wid, name));
if (!index)
return -1;
@ -1173,7 +1173,7 @@ class WalletDB extends EventEmitter {
*/
async getAccountName(wid, index) {
const name = await this.db.get(layout.n.build(wid, index));
const name = await this.db.get(layout.n.encode(wid, index));
if (!name)
return null;
@ -1193,13 +1193,13 @@ class WalletDB extends EventEmitter {
const name = account.name;
// Account data
b.put(layout.a.build(wid, index), account.encode());
b.put(layout.a.encode(wid, index), account.encode());
// Name->Index lookups
b.put(layout.i.build(wid, name), fromU32(index));
b.put(layout.i.encode(wid, name), fromU32(index));
// Index->Name lookups
b.put(layout.n.build(wid, index), fromString(name));
b.put(layout.n.encode(wid, index), fromString(name));
}
/**
@ -1210,7 +1210,7 @@ class WalletDB extends EventEmitter {
*/
async hasAccount(wid, index) {
return this.db.has(layout.a.build(wid, index));
return this.db.has(layout.a.encode(wid, index));
}
/**
@ -1242,10 +1242,10 @@ class WalletDB extends EventEmitter {
await this.addPathMap(b, path.hash, wid);
// Wallet ID + Address Hash -> Path Data
b.put(layout.P.build(wid, path.hash), path.encode());
b.put(layout.P.encode(wid, path.hash), path.encode());
// Wallet ID + Account Index + Address Hash -> Dummy
b.put(layout.r.build(wid, path.account, path.hash), null);
b.put(layout.r.encode(wid, path.account, path.hash), null);
}
/**
@ -1275,7 +1275,7 @@ class WalletDB extends EventEmitter {
*/
async readPath(wid, hash) {
const data = await this.db.get(layout.P.build(wid, hash));
const data = await this.db.get(layout.P.encode(wid, hash));
if (!data)
return null;
@ -1294,7 +1294,7 @@ class WalletDB extends EventEmitter {
*/
async hasPath(wid, hash) {
return this.db.has(layout.P.build(wid, hash));
return this.db.has(layout.P.encode(wid, hash));
}
/**
@ -1306,7 +1306,7 @@ class WalletDB extends EventEmitter {
return this.db.keys({
gte: layout.p.min(),
lte: layout.p.max(),
parse: key => layout.p.parse(key)
parse: key => layout.p.decode(key)[0]
});
}
@ -1320,7 +1320,7 @@ class WalletDB extends EventEmitter {
gte: layout.o.min(),
lte: layout.o.max(),
parse: (key) => {
const [hash, index] = layout.o.parse(key);
const [hash, index] = layout.o.decode(key);
return new Outpoint(hash, index);
}
});
@ -1336,7 +1336,7 @@ class WalletDB extends EventEmitter {
return this.db.keys({
gte: layout.P.min(wid),
lte: layout.P.max(wid),
parse: key => layout.P.parse(key)[1]
parse: key => layout.P.decode(key)[1]
});
}
@ -1351,7 +1351,7 @@ class WalletDB extends EventEmitter {
return this.db.keys({
gte: layout.r.min(wid, account),
lte: layout.r.max(wid, account),
parse: key => layout.r.parse(key)[2]
parse: key => layout.r.decode(key)[2]
});
}
@ -1370,7 +1370,7 @@ class WalletDB extends EventEmitter {
const paths = [];
for (const {key, value} of items) {
const [, hash] = layout.P.parse(key);
const [, hash] = layout.P.decode(key);
const path = Path.decode(value);
path.hash = hash;
@ -1411,7 +1411,7 @@ class WalletDB extends EventEmitter {
});
await iter.each((k, value) => {
const [, hash] = layout.P.parse(k);
const [, hash] = layout.P.decode(k);
const path = Path.decode(value);
if (!path.data)
@ -1443,7 +1443,7 @@ class WalletDB extends EventEmitter {
});
await iter.each((k, value) => {
const [, hash] = layout.P.parse(k);
const [, hash] = layout.P.decode(k);
const path = Path.decode(value);
if (!path.data)
@ -1469,7 +1469,7 @@ class WalletDB extends EventEmitter {
const wids = await this.db.keys({
gte: layout.w.min(),
lte: layout.w.max(),
parse: key => layout.w.parse(key)
parse: key => layout.w.decode(key)[0]
});
this.logger.info('Resending from %d wallets.', wids.length);
@ -1486,13 +1486,13 @@ class WalletDB extends EventEmitter {
*/
async resendPending(wid) {
const prefix = layout.t.build(wid);
const prefix = layout.t.encode(wid);
const b = this.db.bucket(prefix);
const hashes = await b.keys({
gte: tlayout.p.min(),
lte: tlayout.p.max(),
parse: key => tlayout.p.parse(key)
parse: key => tlayout.p.decode(key)[0]
});
if (hashes.length === 0)
@ -1506,7 +1506,7 @@ class WalletDB extends EventEmitter {
const txs = [];
for (const hash of hashes) {
const data = await b.get(tlayout.t.build(hash));
const data = await b.get(tlayout.t.encode(hash));
if (!data)
continue;
@ -1592,7 +1592,7 @@ class WalletDB extends EventEmitter {
*/
async getState() {
const data = await this.db.get(layout.R.build());
const data = await this.db.get(layout.R.encode());
if (!data)
return null;
@ -1614,7 +1614,7 @@ class WalletDB extends EventEmitter {
// Hashes ahead of our new tip
// that we need to delete.
while (state.height !== tip.height) {
b.del(layout.h.build(state.height));
b.del(layout.h.encode(state.height));
state.height -= 1;
}
} else if (tip.height > state.height) {
@ -1629,8 +1629,8 @@ class WalletDB extends EventEmitter {
}
// Save tip and state.
b.put(layout.h.build(tip.height), tip.toHash());
b.put(layout.R.build(), state.encode());
b.put(layout.h.encode(tip.height), tip.toHash());
b.put(layout.R.encode(), state.encode());
await b.write();
@ -1651,7 +1651,7 @@ class WalletDB extends EventEmitter {
state.marked = true;
const b = this.db.batch();
b.put(layout.R.build(), state.encode());
b.put(layout.R.encode(), state.encode());
await b.write();
this.state = state;
@ -1733,7 +1733,7 @@ class WalletDB extends EventEmitter {
*/
async getPathMap(hash) {
return this.getMap(layout.p.build(hash));
return this.getMap(layout.p.encode(hash));
}
/**
@ -1745,7 +1745,7 @@ class WalletDB extends EventEmitter {
async addPathMap(b, hash, wid) {
await this.addHash(hash);
return this.addMap(b, layout.p.build(hash), wid);
return this.addMap(b, layout.p.encode(hash), wid);
}
/**
@ -1756,7 +1756,7 @@ class WalletDB extends EventEmitter {
*/
async removePathMap(b, hash, wid) {
return this.removeMap(b, layout.p.build(hash), wid);
return this.removeMap(b, layout.p.encode(hash), wid);
}
/**
@ -1766,7 +1766,7 @@ class WalletDB extends EventEmitter {
*/
async getBlockMap(height) {
return this.getMap(layout.b.build(height));
return this.getMap(layout.b.encode(height));
}
/**
@ -1777,7 +1777,7 @@ class WalletDB extends EventEmitter {
*/
async addBlockMap(b, height, wid) {
return this.addMap(b, layout.b.build(height), wid);
return this.addMap(b, layout.b.encode(height), wid);
}
/**
@ -1788,7 +1788,7 @@ class WalletDB extends EventEmitter {
*/
async removeBlockMap(b, height, wid) {
return this.removeMap(b, layout.b.build(height), wid);
return this.removeMap(b, layout.b.encode(height), wid);
}
/**
@ -1798,7 +1798,7 @@ class WalletDB extends EventEmitter {
*/
async getTXMap(hash) {
return this.getMap(layout.T.build(hash));
return this.getMap(layout.T.encode(hash));
}
/**
@ -1809,7 +1809,7 @@ class WalletDB extends EventEmitter {
*/
async addTXMap(b, hash, wid) {
return this.addMap(b, layout.T.build(hash), wid);
return this.addMap(b, layout.T.encode(hash), wid);
}
/**
@ -1820,7 +1820,7 @@ class WalletDB extends EventEmitter {
*/
async removeTXMap(b, hash, wid) {
return this.removeMap(b, layout.T.build(hash), wid);
return this.removeMap(b, layout.T.encode(hash), wid);
}
/**
@ -1830,7 +1830,7 @@ class WalletDB extends EventEmitter {
*/
async getOutpointMap(hash, index) {
return this.getMap(layout.o.build(hash, index));
return this.getMap(layout.o.encode(hash, index));
}
/**
@ -1842,7 +1842,7 @@ class WalletDB extends EventEmitter {
async addOutpointMap(b, hash, index, wid) {
await this.addOutpoint(hash, index);
return this.addMap(b, layout.o.build(hash, index), wid);
return this.addMap(b, layout.o.encode(hash, index), wid);
}
/**
@ -1853,7 +1853,7 @@ class WalletDB extends EventEmitter {
*/
async removeOutpointMap(b, hash, index, wid) {
return this.removeMap(b, layout.o.build(hash, index), wid);
return this.removeMap(b, layout.o.encode(hash, index), wid);
}
/**
@ -1863,7 +1863,7 @@ class WalletDB extends EventEmitter {
*/
async getNameMap(nameHash) {
return this.getMap(layout.N.build(nameHash));
return this.getMap(layout.N.encode(nameHash));
}
/**
@ -1875,7 +1875,7 @@ class WalletDB extends EventEmitter {
async addNameMap(b, nameHash, wid) {
await this.addName(nameHash);
return this.addMap(b, layout.N.build(nameHash), wid);
return this.addMap(b, layout.N.encode(nameHash), wid);
}
/**
@ -1886,7 +1886,7 @@ class WalletDB extends EventEmitter {
*/
async removeNameMap(b, nameHash, wid) {
return this.removeMap(b, layout.N.build(nameHash), wid);
return this.removeMap(b, layout.N.encode(nameHash), wid);
}
/**
@ -1896,7 +1896,7 @@ class WalletDB extends EventEmitter {
*/
async getBlock(height) {
const hash = await this.db.get(layout.h.build(height));
const hash = await this.db.get(layout.h.encode(height));
if (!hash)
return null;
@ -1974,7 +1974,7 @@ class WalletDB extends EventEmitter {
async revert(target) {
const iter = this.db.iterator({
gte: layout.b.build(target + 1),
gte: layout.b.encode(target + 1),
lte: layout.b.max(),
reverse: true,
values: true
@ -1983,7 +1983,7 @@ class WalletDB extends EventEmitter {
let total = 0;
await iter.each(async (key, value) => {
const height = layout.b.parse(key);
const [height] = layout.b.decode(key);
const block = MapRecord.decode(value);
for (const wid of block.wids) {

View file

@ -22,9 +22,9 @@
},
"dependencies": {
"bcfg": "~0.1.2",
"bcrypto": "~1.0.0",
"bcuckoo": "~0.4.0",
"bdb": "~0.2.3",
"bcrypto": "~1.1.0",
"bcuckoo": "~0.5.0",
"bdb": "~1.1.0",
"bdns": "~0.1.1",
"bevent": "~0.1.1",
"bfile": "~0.1.1",
@ -35,14 +35,13 @@
"blru": "~0.1.2",
"blst": "~0.1.1",
"bmutex": "~0.1.2",
"bn.js": "~4.11.8",
"bns": "~0.2.3",
"bns": "~0.3.0",
"bs32": "~0.1.1",
"bsert": "~0.0.4",
"bsip": "~0.1.1",
"bsock": "~0.1.2",
"bsocks": "~0.2.1",
"bstring": "~0.1.1",
"bstring": "~0.2.0",
"btcp": "~0.1.1",
"buffer-map": "~0.0.2",
"bufio": "~1.0.1",

View file

@ -5,7 +5,7 @@
const assert = require('./util/assert');
const consensus = require('../lib/protocol/consensus');
const BN = require('bn.js');
const BN = require('bcrypto/lib/bn.js');
describe('Consensus', function() {
it('should calculate reward properly', () => {

View file

@ -18,8 +18,7 @@ module.exports = {
},
resolve: {
modules: ['node_modules'],
extensions: ['-browser.js', '.js', '.json'],
alias: require('bcrypto/compat')
extensions: ['-browser.js', '.js', '.json']
},
plugins: [
new webpack.DefinePlugin({

View file

@ -20,8 +20,7 @@ module.exports = {
},
resolve: {
modules: ['node_modules'],
extensions: ['-browser.js', '.js', '.json'],
alias: require('bcrypto/compat')
extensions: ['-browser.js', '.js', '.json']
},
plugins: [
new webpack.DefinePlugin({

View file

@ -20,8 +20,7 @@ module.exports = {
},
resolve: {
modules: ['node_modules'],
extensions: ['-compat.js', '-browser.js', '.js', '.json'],
alias: require('bcrypto/compat')
extensions: ['-compat.js', '-browser.js', '.js', '.json']
},
module: {
rules: [{