program. addresses.
This commit is contained in:
parent
32e26446b1
commit
7862418ccc
1
bin/node
1
bin/node
@ -7,6 +7,7 @@ var utils = bcoin.utils;
|
|||||||
var assert = utils.assert;
|
var assert = utils.assert;
|
||||||
|
|
||||||
process.on('uncaughtException', function(err) {
|
process.on('uncaughtException', function(err) {
|
||||||
|
bcoin.debug(err.stack);
|
||||||
bcoin.error(err);
|
bcoin.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -35,6 +35,16 @@ function Address(options) {
|
|||||||
if (!(this instanceof Address))
|
if (!(this instanceof Address))
|
||||||
return new Address(options);
|
return new Address(options);
|
||||||
|
|
||||||
|
this.hash = null;
|
||||||
|
this.type = null;
|
||||||
|
this.version = null;
|
||||||
|
this.network = bcoin.network.get().type;
|
||||||
|
|
||||||
|
if (options)
|
||||||
|
this.fromOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Address.prototype.fromOptions = function fromOptions(options) {
|
||||||
this.hash = options.hash;
|
this.hash = options.hash;
|
||||||
this.type = options.type || 'pubkeyhash';
|
this.type = options.type || 'pubkeyhash';
|
||||||
this.version = options.version == null ? -1 : options.version;
|
this.version = options.version == null ? -1 : options.version;
|
||||||
@ -42,7 +52,11 @@ function Address(options) {
|
|||||||
|
|
||||||
if (!Buffer.isBuffer(this.hash))
|
if (!Buffer.isBuffer(this.hash))
|
||||||
this.hash = new Buffer(this.hash, 'hex');
|
this.hash = new Buffer(this.hash, 'hex');
|
||||||
}
|
};
|
||||||
|
|
||||||
|
Address.fromOptions = function fromOptions(options) {
|
||||||
|
return new Address().fromOptions(options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the address hash.
|
* Get the address hash.
|
||||||
@ -161,7 +175,7 @@ Address.toBase58 = function toBase58(hash, type, version, network) {
|
|||||||
* @throws Parse error
|
* @throws Parse error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseBase58 = function parseBase58(address) {
|
Address.prototype.fromBase58 = function fromBase58(address) {
|
||||||
var i, prefix, type, version, hash, network, p;
|
var i, prefix, type, version, hash, network, p;
|
||||||
|
|
||||||
if (!Buffer.isBuffer(address))
|
if (!Buffer.isBuffer(address))
|
||||||
@ -194,12 +208,12 @@ Address.parseBase58 = function parseBase58(address) {
|
|||||||
|
|
||||||
p.verifyChecksum();
|
p.verifyChecksum();
|
||||||
|
|
||||||
return {
|
this.network = network.type;
|
||||||
network: network.type,
|
this.type = type;
|
||||||
type: type,
|
this.hash = hash;
|
||||||
hash: hash,
|
this.version = version == null ? -1 : version;
|
||||||
version: version == null ? -1 : version
|
|
||||||
};
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,7 +224,7 @@ Address.parseBase58 = function parseBase58(address) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromBase58 = function fromBase58(address) {
|
Address.fromBase58 = function fromBase58(address) {
|
||||||
return new Address(Address.parseBase58(address));
|
return new Address().fromBase58(address);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,50 +235,61 @@ Address.fromBase58 = function fromBase58(address) {
|
|||||||
* @returns {ParsedAddress|null}
|
* @returns {ParsedAddress|null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseScript = function parseScript(script) {
|
Address.prototype.fromScript = function fromScript(script) {
|
||||||
var program, hash;
|
var program, hash;
|
||||||
|
|
||||||
if (script.isWitnessProgram()) {
|
if (script.isWitnessProgram()) {
|
||||||
program = script.getWitnessProgram();
|
program = script.toProgram();
|
||||||
if (!program.type || program.type === 'unknown')
|
if (program.isUnknown())
|
||||||
return;
|
return;
|
||||||
return {
|
this.hash = program.data;
|
||||||
hash: program.data,
|
this.type = program.type;
|
||||||
type: program.type,
|
this.version = program.version;
|
||||||
version: program.version
|
return this;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast case
|
// Fast case
|
||||||
if (script.isPubkey()) {
|
if (script.isPubkey()) {
|
||||||
hash = utils.ripesha(script.raw.slice(1, script.raw[0] + 1));
|
this.hash = utils.ripesha(script.raw.slice(1, script.raw[0] + 1));
|
||||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
this.type = 'pubkeyhash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.isPubkeyhash()) {
|
if (script.isPubkeyhash()) {
|
||||||
hash = script.raw.slice(3, 23);
|
this.hash = script.raw.slice(3, 23);
|
||||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
this.type = 'pubkeyhash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.isScripthash()) {
|
if (script.isScripthash()) {
|
||||||
hash = script.raw.slice(2, 22);
|
this.hash = script.raw.slice(2, 22);
|
||||||
return { hash: hash, type: 'scripthash', version: -1 };
|
this.type = 'scripthash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slow case (allow non-minimal data and parse script)
|
// Slow case (allow non-minimal data and parse script)
|
||||||
if (script.isPubkey(true)) {
|
if (script.isPubkey(true)) {
|
||||||
hash = utils.ripesha(script.code[0].data);
|
this.hash = utils.ripesha(script.code[0].data);
|
||||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
this.type = 'pubkeyhash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.isPubkeyhash(true)) {
|
if (script.isPubkeyhash(true)) {
|
||||||
hash = script.code[2].data;
|
this.hash = script.code[2].data;
|
||||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
this.type = 'pubkeyhash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.isMultisig()) {
|
if (script.isMultisig()) {
|
||||||
hash = utils.ripesha(script.raw);
|
this.hash = utils.ripesha(script.raw);
|
||||||
return { hash: hash, type: 'scripthash', version: -1 };
|
this.type = 'scripthash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -275,17 +300,21 @@ Address.parseScript = function parseScript(script) {
|
|||||||
* @returns {ParsedAddress|null}
|
* @returns {ParsedAddress|null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseWitness = function parseWitness(witness) {
|
Address.prototype.fromWitness = function fromWitness(witness) {
|
||||||
var hash;
|
var hash;
|
||||||
|
|
||||||
if (witness.isPubkeyhashInput()) {
|
if (witness.isPubkeyhashInput()) {
|
||||||
hash = utils.ripesha(witness.items[1]);
|
this.hash = utils.ripesha(witness.items[1]);
|
||||||
return { hash: hash, type: 'witnesspubkeyhash', version: 0 };
|
this.type = 'witnesspubkeyhash';
|
||||||
|
this.version = 0;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (witness.isScripthashInput()) {
|
if (witness.isScripthashInput()) {
|
||||||
hash = utils.sha256(witness.items[witness.items.length - 1]);
|
this.hash = utils.sha256(witness.items[witness.items.length - 1]);
|
||||||
return { hash: hash, type: 'witnessscripthash', version: 0 };
|
this.type = 'witnessscripthash';
|
||||||
|
this.version = 0;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -296,17 +325,21 @@ Address.parseWitness = function parseWitness(witness) {
|
|||||||
* @returns {ParsedAddress|null}
|
* @returns {ParsedAddress|null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseInputScript = function parseInputScript(script) {
|
Address.prototype.fromInputScript = function fromInputScript(script) {
|
||||||
var hash;
|
var hash;
|
||||||
|
|
||||||
if (script.isPubkeyhashInput()) {
|
if (script.isPubkeyhashInput()) {
|
||||||
hash = utils.ripesha(script.code[1].data);
|
this.hash = utils.ripesha(script.code[1].data);
|
||||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
this.type = 'pubkeyhash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script.isScripthashInput()) {
|
if (script.isScripthashInput()) {
|
||||||
hash = utils.ripesha(script.code[script.code.length - 1].data);
|
this.hash = utils.ripesha(script.code[script.code.length - 1].data);
|
||||||
return { hash: hash, type: 'scripthash', version: -1 };
|
this.type = 'scripthash';
|
||||||
|
this.version = -1;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -317,12 +350,7 @@ Address.parseInputScript = function parseInputScript(script) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromWitness = function fromWitness(witness) {
|
Address.fromWitness = function fromWitness(witness) {
|
||||||
var data = Address.parseWitness(witness);
|
return new Address().fromWitness(witness);
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return new Address(data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,12 +360,7 @@ Address.fromWitness = function fromWitness(witness) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromInputScript = function fromInputScript(script) {
|
Address.fromInputScript = function fromInputScript(script) {
|
||||||
var data = Address.parseInputScript(script);
|
return new Address().fromInputScript(script);
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return new Address(data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -347,12 +370,7 @@ Address.fromInputScript = function fromInputScript(script) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromScript = function fromScript(script) {
|
Address.fromScript = function fromScript(script) {
|
||||||
var data = Address.parseScript(script);
|
return new Address().fromScript(script);
|
||||||
|
|
||||||
if (!data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
return new Address(data);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -363,15 +381,16 @@ Address.fromScript = function fromScript(script) {
|
|||||||
* @returns {ParsedAddress}
|
* @returns {ParsedAddress}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseHash = function parseHash(hash, type, version) {
|
Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||||
if (!Buffer.isBuffer(hash))
|
if (typeof hash === 'string')
|
||||||
hash = new Buffer(hash, 'hex');
|
hash = new Buffer(hash, 'hex');
|
||||||
|
|
||||||
return {
|
this.hash = hash;
|
||||||
hash: hash,
|
this.type = type || 'pubkeyhash';
|
||||||
type: type || 'pubkeyhash',
|
this.version = version == null ? -1 : version;
|
||||||
version: version == null ? -1 : version
|
this.network = bcoin.network.get(network).type;
|
||||||
};
|
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -382,8 +401,8 @@ Address.parseHash = function parseHash(hash, type, version) {
|
|||||||
* @returns {Address}
|
* @returns {Address}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromHash = function fromHash(hash, type, version) {
|
Address.fromHash = function fromHash(hash, type, version, network) {
|
||||||
return new Address(Address.parseHash(hash, type, version));
|
return new Address().fromHash(hash, type, version, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -394,13 +413,13 @@ Address.fromHash = function fromHash(hash, type, version) {
|
|||||||
* @returns {ParsedAddress}
|
* @returns {ParsedAddress}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.parseData = function parseData(data, type, version) {
|
Address.prototype.fromData = function fromData(data, type, version, network) {
|
||||||
if (type === 'witnessscripthash')
|
if (type === 'witnessscripthash')
|
||||||
data = utils.sha256(data);
|
data = utils.sha256(data);
|
||||||
else
|
else
|
||||||
data = utils.ripesha(data);
|
data = utils.ripesha(data);
|
||||||
|
|
||||||
return Address.parseHash(data, type, version);
|
return this.fromHash(data, type, version, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -411,8 +430,8 @@ Address.parseData = function parseData(data, type, version) {
|
|||||||
* @returns {Address}
|
* @returns {Address}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Address.fromData = function fromData(data, type, version) {
|
Address.fromData = function fromData(data, type, version, network) {
|
||||||
return new Address(Address.parseData(data, type, version));
|
return new Address().fromData(data, type, version, network);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -430,7 +449,7 @@ Address.validate = function validate(address, type) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
address = Address.parseBase58(address);
|
address = Address.fromBase58(address);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -460,7 +479,7 @@ Address.getHash = function getHash(data, enc) {
|
|||||||
hash = data.hash;
|
hash = data.hash;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
hash = Address.parseBase58(data).hash;
|
hash = Address.fromBase58(data).hash;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,6 +182,7 @@ function Environment(options) {
|
|||||||
this.walletdb = require('./walletdb');
|
this.walletdb = require('./walletdb');
|
||||||
this.provider = this.walletdb.Provider;
|
this.provider = this.walletdb.Provider;
|
||||||
this.peer = require('./peer');
|
this.peer = require('./peer');
|
||||||
|
this.networkaddress = this.peer.NetworkAddress;
|
||||||
this.pool = require('./pool');
|
this.pool = require('./pool');
|
||||||
this.miner = require('./miner');
|
this.miner = require('./miner');
|
||||||
this.minerblock = this.miner.MinerBlock;
|
this.minerblock = this.miner.MinerBlock;
|
||||||
|
|||||||
@ -275,12 +275,8 @@ Peer.prototype._onConnect = function _onConnect() {
|
|||||||
version: constants.VERSION,
|
version: constants.VERSION,
|
||||||
services: constants.LOCAL_SERVICES,
|
services: constants.LOCAL_SERVICES,
|
||||||
ts: bcoin.now(),
|
ts: bcoin.now(),
|
||||||
remote: {},
|
remote: new NetworkAddress(),
|
||||||
local: {
|
local: this.pool.address,
|
||||||
services: constants.LOCAL_SERVICES,
|
|
||||||
host: this.pool.host,
|
|
||||||
port: this.pool.port
|
|
||||||
},
|
|
||||||
nonce: this.pool.localNonce,
|
nonce: this.pool.localNonce,
|
||||||
agent: constants.USER_AGENT,
|
agent: constants.USER_AGENT,
|
||||||
height: this.chain.height,
|
height: this.chain.height,
|
||||||
@ -288,15 +284,10 @@ Peer.prototype._onConnect = function _onConnect() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Advertise our address.
|
// Advertise our address.
|
||||||
if (this.pool.host !== '0.0.0.0'
|
if (this.pool.address.host !== '0.0.0.0'
|
||||||
&& !this.pool.options.selfish
|
&& !this.pool.options.selfish
|
||||||
&& this.pool.server) {
|
&& this.pool.server) {
|
||||||
this.write(this.framer.addr([{
|
this.write(this.framer.addr([this.pool.address]));
|
||||||
ts: utils.now() - (process.uptime() | 0),
|
|
||||||
services: constants.LOCAL_SERVICES,
|
|
||||||
host: this.pool.host,
|
|
||||||
port: this.pool.port
|
|
||||||
}]));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1443,7 +1434,7 @@ Peer.prototype._handleAddr = function _handleAddr(addrs) {
|
|||||||
var i, addr;
|
var i, addr;
|
||||||
|
|
||||||
for (i = 0; i < addrs.length; i++) {
|
for (i = 0; i < addrs.length; i++) {
|
||||||
addr = new NetworkAddress(addrs[i]);
|
addr = addrs[i];
|
||||||
this.addrFilter.add(addr.host, 'ascii');
|
this.addrFilter.add(addr.host, 'ascii');
|
||||||
hosts.push(addr);
|
hosts.push(addr);
|
||||||
}
|
}
|
||||||
@ -1866,17 +1857,23 @@ Peer.prototype.inspect = function inspect() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
function NetworkAddress(options) {
|
function NetworkAddress(options) {
|
||||||
var host, ts, now;
|
|
||||||
|
|
||||||
if (!(this instanceof NetworkAddress))
|
if (!(this instanceof NetworkAddress))
|
||||||
return new NetworkAddress(options);
|
return new NetworkAddress(options);
|
||||||
|
|
||||||
now = utils.now();
|
this.id = NetworkAddress.uid++;
|
||||||
host = options.host;
|
this.host = '0.0.0.0';
|
||||||
ts = options.ts;
|
this.port = 0;
|
||||||
|
this.services = 0;
|
||||||
|
this.ts = 0;
|
||||||
|
|
||||||
if (ts <= 100000000 || ts > now + 10 * 60)
|
if (options)
|
||||||
ts = now - 5 * 24 * 60 * 60;
|
this.fromOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkAddress.uid = 0;
|
||||||
|
|
||||||
|
NetworkAddress.prototype.fromOptions = function fromOptions(options) {
|
||||||
|
var host = options.host;
|
||||||
|
|
||||||
if (IP.version(host) !== -1)
|
if (IP.version(host) !== -1)
|
||||||
host = IP.normalize(host);
|
host = IP.normalize(host);
|
||||||
@ -1886,14 +1883,17 @@ function NetworkAddress(options) {
|
|||||||
assert(typeof options.services === 'number');
|
assert(typeof options.services === 'number');
|
||||||
assert(typeof options.ts === 'number');
|
assert(typeof options.ts === 'number');
|
||||||
|
|
||||||
this.id = NetworkAddress.uid++;
|
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.port = options.port;
|
this.port = options.port;
|
||||||
this.services = options.services;
|
this.services = options.services;
|
||||||
this.ts = ts;
|
this.ts = options.ts;
|
||||||
}
|
|
||||||
|
|
||||||
NetworkAddress.uid = 0;
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkAddress.fromOptions = function fromOptions(options) {
|
||||||
|
return NetworkAddress().fromOptions(options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether the `host` field is an ip address.
|
* Test whether the `host` field is an ip address.
|
||||||
@ -1962,18 +1962,63 @@ NetworkAddress.prototype.inspect = function inspect() {
|
|||||||
* @returns {NetworkAddress}
|
* @returns {NetworkAddress}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NetworkAddress.fromHostname = function fromHostname(hostname, network) {
|
NetworkAddress.prototype.fromHostname = function fromHostname(hostname, network) {
|
||||||
var address = IP.parseHost(hostname);
|
var address = IP.parseHost(hostname);
|
||||||
|
|
||||||
network = bcoin.network.get(network);
|
network = bcoin.network.get(network);
|
||||||
return new NetworkAddress({
|
|
||||||
host: address.host,
|
this.host = address.host;
|
||||||
port: address.port || network.port,
|
this.port = address.port || network.port;
|
||||||
version: constants.VERSION,
|
this.version = constants.VERSION;
|
||||||
services: constants.services.NETWORK
|
this.services = constants.services.NETWORK
|
||||||
| constants.services.BLOOM
|
| constants.services.BLOOM
|
||||||
| constants.services.WITNESS,
|
| constants.services.WITNESS;
|
||||||
ts: utils.now()
|
this.ts = bcoin.now();
|
||||||
});
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkAddress.fromHostname = function fromHostname(hostname, network) {
|
||||||
|
return new NetworkAddress().fromHostname(hostname, network);
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkAddress.prototype.fromRaw = function fromRaw(data, full) {
|
||||||
|
var p = bcoin.reader(data);
|
||||||
|
var now = bcoin.now();
|
||||||
|
|
||||||
|
if (full) // only version >= 31402
|
||||||
|
this.ts = p.readU32();
|
||||||
|
else
|
||||||
|
this.ts = 0;
|
||||||
|
|
||||||
|
this.services = p.readU53();
|
||||||
|
this.host = IP.toString(p.readBytes(16));
|
||||||
|
this.port = p.readU16BE();
|
||||||
|
|
||||||
|
if (this.ts <= 100000000 || this.ts > now + 10 * 60)
|
||||||
|
this.ts = now - 5 * 24 * 60 * 60;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkAddress.fromRaw = function fromRaw(data, full) {
|
||||||
|
return new NetworkAddress().fromRaw(data, full);
|
||||||
|
};
|
||||||
|
|
||||||
|
NetworkAddress.prototype.toRaw = function toRaw(full, writer) {
|
||||||
|
var p = bcoin.writer(writer);
|
||||||
|
|
||||||
|
if (full)
|
||||||
|
p.writeU32(this.ts);
|
||||||
|
|
||||||
|
p.writeU64(this.services);
|
||||||
|
p.writeBytes(IP.toBuffer(this.host));
|
||||||
|
p.writeU16BE(this.port);
|
||||||
|
|
||||||
|
if (!writer)
|
||||||
|
p = p.render();
|
||||||
|
|
||||||
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -116,8 +116,13 @@ function Pool(options) {
|
|||||||
|
|
||||||
this.hosts = [];
|
this.hosts = [];
|
||||||
this.hostMap = {};
|
this.hostMap = {};
|
||||||
this.host = '0.0.0.0';
|
|
||||||
this.port = this.network.port;
|
this.address = new NetworkAddress({
|
||||||
|
ts: utils.now() - (process.uptime() | 0),
|
||||||
|
services: constants.LOCAL_SERVICES,
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: this.network.port
|
||||||
|
});
|
||||||
|
|
||||||
this.server = null;
|
this.server = null;
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
@ -326,7 +331,7 @@ Pool.prototype._init = function _init() {
|
|||||||
bcoin.error(err);
|
bcoin.error(err);
|
||||||
|
|
||||||
if (ip) {
|
if (ip) {
|
||||||
self.host = ip;
|
self.address.host = ip;
|
||||||
bcoin.debug('External IP found: %s.', ip);
|
bcoin.debug('External IP found: %s.', ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -407,34 +407,6 @@ Framer.prototype.feeFilter = function feeFilter(options) {
|
|||||||
return this.packet('feefilter', Framer.feeFilter(options));
|
return this.packet('feefilter', Framer.feeFilter(options));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Serialize an address.
|
|
||||||
* @param {NakedNetworkAddress} data
|
|
||||||
* @param {Boolean?} full - Whether to include the timestamp.
|
|
||||||
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
|
||||||
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Framer.address = function address(data, full, writer) {
|
|
||||||
var p = new BufferWriter(writer);
|
|
||||||
|
|
||||||
if (full) {
|
|
||||||
if (!data.ts)
|
|
||||||
p.writeU32(utils.now() - (process.uptime() | 0));
|
|
||||||
else
|
|
||||||
p.writeU32(data.ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.writeU64(data.services || 0);
|
|
||||||
p.writeBytes(IP.toBuffer(data.host));
|
|
||||||
p.writeU16BE(data.port || 0);
|
|
||||||
|
|
||||||
if (!writer)
|
|
||||||
p = p.render();
|
|
||||||
|
|
||||||
return p;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a version packet (without a header).
|
* Create a version packet (without a header).
|
||||||
* @param {VersionPacket} options
|
* @param {VersionPacket} options
|
||||||
@ -446,8 +418,8 @@ Framer.version = function version(options, writer) {
|
|||||||
var p = new BufferWriter(writer);
|
var p = new BufferWriter(writer);
|
||||||
var agent = options.agent || constants.USER_AGENT;
|
var agent = options.agent || constants.USER_AGENT;
|
||||||
var services = options.services;
|
var services = options.services;
|
||||||
var remote = options.remote || {};
|
var remote = options.remote || new bcoin.networkaddress();
|
||||||
var local = options.local || {};
|
var local = options.local || new bcoin.networkaddress();
|
||||||
var nonce = options.nonce;
|
var nonce = options.nonce;
|
||||||
|
|
||||||
if (services == null)
|
if (services == null)
|
||||||
@ -462,8 +434,8 @@ Framer.version = function version(options, writer) {
|
|||||||
p.write32(options.version || constants.VERSION);
|
p.write32(options.version || constants.VERSION);
|
||||||
p.writeU64(services);
|
p.writeU64(services);
|
||||||
p.write64(options.ts || bcoin.now());
|
p.write64(options.ts || bcoin.now());
|
||||||
Framer.address(remote, false, p);
|
remote.toRaw(false, p);
|
||||||
Framer.address(local, false, p);
|
local.toRaw(false, p);
|
||||||
p.writeU64(nonce);
|
p.writeU64(nonce);
|
||||||
p.writeVarString(agent, 'ascii');
|
p.writeVarString(agent, 'ascii');
|
||||||
p.write32(options.height || 0);
|
p.write32(options.height || 0);
|
||||||
@ -765,7 +737,7 @@ Framer.reject = function reject(details, writer) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an addr packet (without a header).
|
* Create an addr packet (without a header).
|
||||||
* @param {NakedNetworkAddress[]} hosts
|
* @param {NetworkAddress[]} hosts
|
||||||
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
||||||
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
||||||
*/
|
*/
|
||||||
@ -777,7 +749,7 @@ Framer.addr = function addr(hosts, writer) {
|
|||||||
p.writeVarint(hosts.length);
|
p.writeVarint(hosts.length);
|
||||||
|
|
||||||
for (i = 0; i < hosts.length; i++)
|
for (i = 0; i < hosts.length; i++)
|
||||||
Framer.address(hosts[i], true, p);
|
hosts[i].toRaw(true, p);
|
||||||
|
|
||||||
if (!writer)
|
if (!writer)
|
||||||
p = p.render();
|
p = p.render();
|
||||||
|
|||||||
@ -481,10 +481,10 @@ Parser.parseVersion = function parseVersion(p) {
|
|||||||
version = p.read32();
|
version = p.read32();
|
||||||
services = p.readU53();
|
services = p.readU53();
|
||||||
ts = p.read53();
|
ts = p.read53();
|
||||||
recv = Parser.parseAddress(p, false);
|
recv = bcoin.networkaddress.fromRaw(p, false);
|
||||||
|
|
||||||
if (p.left() > 0) {
|
if (p.left() > 0) {
|
||||||
from = Parser.parseAddress(p, false);
|
from = bcoin.networkaddress.fromRaw(p, false);
|
||||||
nonce = p.readU64();
|
nonce = p.readU64();
|
||||||
} else {
|
} else {
|
||||||
from = {};
|
from = {};
|
||||||
@ -720,40 +720,10 @@ Parser.parseReject = function parseReject(p) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse serialized network address.
|
|
||||||
* @param {Buffer|BufferReader} p
|
|
||||||
* @returns {NakedNetworkAddress}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Parser.parseAddress = function parseAddress(p, full) {
|
|
||||||
var ts, services, ip, port;
|
|
||||||
|
|
||||||
p = new BufferReader(p);
|
|
||||||
|
|
||||||
if (full) // only version >= 31402
|
|
||||||
ts = p.readU32();
|
|
||||||
else
|
|
||||||
ts = 0;
|
|
||||||
|
|
||||||
services = p.readU53();
|
|
||||||
|
|
||||||
ip = p.readBytes(16);
|
|
||||||
|
|
||||||
port = p.readU16BE();
|
|
||||||
|
|
||||||
return {
|
|
||||||
ts: ts,
|
|
||||||
services: services,
|
|
||||||
host: IP.toString(ip),
|
|
||||||
port: port
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse addr packet.
|
* Parse addr packet.
|
||||||
* @param {Buffer|BufferReader} p
|
* @param {Buffer|BufferReader} p
|
||||||
* @returns {NakedNetworkAddress[]}
|
* @returns {NetworkAddress[]}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Parser.parseAddr = function parseAddr(p) {
|
Parser.parseAddr = function parseAddr(p) {
|
||||||
@ -767,7 +737,7 @@ Parser.parseAddr = function parseAddr(p) {
|
|||||||
assert(count <= 10000, 'Too many addresses.');
|
assert(count <= 10000, 'Too many addresses.');
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
addrs.push(Parser.parseAddress(p, true));
|
addrs.push(bcoin.networkaddress.fromRaw(p, true));
|
||||||
|
|
||||||
return addrs;
|
return addrs;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2771,7 +2771,7 @@ Script.prototype.isWitnessProgram = function isWitnessProgram() {
|
|||||||
* @returns {Program|null}
|
* @returns {Program|null}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
Script.prototype.toProgram = function toProgram() {
|
||||||
var version, data, type;
|
var version, data, type;
|
||||||
|
|
||||||
if (!this.isWitnessProgram())
|
if (!this.isWitnessProgram())
|
||||||
@ -2780,23 +2780,7 @@ Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
|||||||
version = Script.getSmall(this.raw[0]);
|
version = Script.getSmall(this.raw[0]);
|
||||||
data = this.raw.slice(2);
|
data = this.raw.slice(2);
|
||||||
|
|
||||||
if (version > 0) {
|
return new Program(version, data);
|
||||||
// No interpretation of script (anyone can spend)
|
|
||||||
type = 'unknown';
|
|
||||||
} else if (version === 0 && data.length === 20) {
|
|
||||||
type = 'witnesspubkeyhash';
|
|
||||||
} else if (version === 0 && data.length === 32) {
|
|
||||||
type = 'witnessscripthash';
|
|
||||||
} else {
|
|
||||||
// Fail on bad version=0
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
version: version,
|
|
||||||
type: type,
|
|
||||||
data: data
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3819,7 +3803,7 @@ Script.getWitnessSigops = function getWitnessSigops(input, output, witness, flag
|
|||||||
assert((flags & constants.flags.VERIFY_P2SH) !== 0);
|
assert((flags & constants.flags.VERIFY_P2SH) !== 0);
|
||||||
|
|
||||||
if (output.isWitnessProgram())
|
if (output.isWitnessProgram())
|
||||||
return Script.witnessSigops(output.getWitnessProgram(), witness, flags);
|
return Script.witnessSigops(output.toProgram(), witness, flags);
|
||||||
|
|
||||||
// This is a unique situation in terms of consensus
|
// This is a unique situation in terms of consensus
|
||||||
// rules. We can just grab the redeem script without
|
// rules. We can just grab the redeem script without
|
||||||
@ -3831,7 +3815,7 @@ Script.getWitnessSigops = function getWitnessSigops(input, output, witness, flag
|
|||||||
if (output.isScripthash() && input.isPushOnly()) {
|
if (output.isScripthash() && input.isPushOnly()) {
|
||||||
redeem = input.getRedeem();
|
redeem = input.getRedeem();
|
||||||
if (redeem && redeem.isWitnessProgram())
|
if (redeem && redeem.isWitnessProgram())
|
||||||
return Script.witnessSigops(redeem.getWitnessProgram(), witness, flags);
|
return Script.witnessSigops(redeem.toProgram(), witness, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -4050,7 +4034,7 @@ Script.verify = function verify(input, witness, output, tx, i, flags) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
|
Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
|
||||||
var program = output.getWitnessProgram();
|
var program = output.toProgram();
|
||||||
var stack = witness.toStack();
|
var stack = witness.toStack();
|
||||||
var witnessScript, redeem, j;
|
var witnessScript, redeem, j;
|
||||||
|
|
||||||
@ -4505,6 +4489,47 @@ Opcode.isOpcode = function isOpcode(obj) {
|
|||||||
&& (Buffer.isBuffer(obj.data) || obj.data === null);
|
&& (Buffer.isBuffer(obj.data) || obj.data === null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Witness Program
|
||||||
|
* @constructor
|
||||||
|
* @private
|
||||||
|
* @param {Number} version
|
||||||
|
* @param {Buffer} data
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Program(version, data) {
|
||||||
|
if (!(this instanceof Program))
|
||||||
|
return new Program(version, data);
|
||||||
|
|
||||||
|
this.version = version;
|
||||||
|
this.data = data;
|
||||||
|
this.type = null;
|
||||||
|
|
||||||
|
if (version > 0) {
|
||||||
|
// No interpretation of script (anyone can spend)
|
||||||
|
this.type = 'unknown';
|
||||||
|
} else if (version === 0 && data.length === 20) {
|
||||||
|
this.type = 'witnesspubkeyhash';
|
||||||
|
} else if (version === 0 && data.length === 32) {
|
||||||
|
this.type = 'witnessscripthash';
|
||||||
|
} else {
|
||||||
|
// Fail on bad version=0
|
||||||
|
this.type = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Program.prototype.isUnknown = function isUnknown() {
|
||||||
|
return !this.type || this.type === 'unknown';
|
||||||
|
};
|
||||||
|
|
||||||
|
Program.prototype.inspect = function inspect() {
|
||||||
|
return '<Program:'
|
||||||
|
+ ' version=' + this.version
|
||||||
|
+ ' data=' + this.data.toString('hex')
|
||||||
|
+ ' type=' + this.type
|
||||||
|
+ '>';
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -31,14 +31,38 @@ describe('Protocol', function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
packetTest('version', {}, function(payload) {
|
var v1 = {
|
||||||
|
version: constants.VERSION,
|
||||||
|
services: constants.LOCAL_SERVICES,
|
||||||
|
ts: bcoin.now(),
|
||||||
|
remote: new bcoin.networkaddress(),
|
||||||
|
local: new bcoin.networkaddress(),
|
||||||
|
nonce: utils.nonce(),
|
||||||
|
agent: constants.USER_AGENT,
|
||||||
|
height: 0,
|
||||||
|
relay: false
|
||||||
|
};
|
||||||
|
|
||||||
|
packetTest('version', v1, function(payload) {
|
||||||
assert.equal(payload.version, constants.VERSION);
|
assert.equal(payload.version, constants.VERSION);
|
||||||
assert.equal(payload.agent, agent);
|
assert.equal(payload.agent, agent);
|
||||||
assert.equal(payload.height, 0);
|
assert.equal(payload.height, 0);
|
||||||
assert.equal(payload.relay, false);
|
assert.equal(payload.relay, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
packetTest('version', { relay: true, height: 10 }, function(payload) {
|
var v2 = {
|
||||||
|
version: constants.VERSION,
|
||||||
|
services: constants.LOCAL_SERVICES,
|
||||||
|
ts: bcoin.now(),
|
||||||
|
remote: new bcoin.networkaddress(),
|
||||||
|
local: new bcoin.networkaddress(),
|
||||||
|
nonce: utils.nonce(),
|
||||||
|
agent: constants.USER_AGENT,
|
||||||
|
height: 10,
|
||||||
|
relay: true
|
||||||
|
};
|
||||||
|
|
||||||
|
packetTest('version', v2, function(payload) {
|
||||||
assert.equal(payload.version, constants.VERSION);
|
assert.equal(payload.version, constants.VERSION);
|
||||||
assert.equal(payload.agent, agent);
|
assert.equal(payload.agent, agent);
|
||||||
assert.equal(payload.height, 10);
|
assert.equal(payload.height, 10);
|
||||||
@ -49,18 +73,18 @@ describe('Protocol', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var hosts = [
|
var hosts = [
|
||||||
{
|
new bcoin.networkaddress({
|
||||||
services: constants.LOCAL_SERVICES,
|
services: constants.LOCAL_SERVICES,
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 8333,
|
port: 8333,
|
||||||
ts: Date.now() / 1000 | 0
|
ts: Date.now() / 1000 | 0
|
||||||
},
|
}),
|
||||||
{
|
new bcoin.networkaddress({
|
||||||
services: constants.LOCAL_SERVICES,
|
services: constants.LOCAL_SERVICES,
|
||||||
host: '::123:456:789a',
|
host: '::123:456:789a',
|
||||||
port: 18333,
|
port: 18333,
|
||||||
ts: Date.now() / 1000 | 0
|
ts: Date.now() / 1000 | 0
|
||||||
}
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
packetTest('addr', hosts, function(payload) {
|
packetTest('addr', hosts, function(payload) {
|
||||||
|
|||||||
@ -105,9 +105,9 @@ describe('Wallet', function() {
|
|||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
|
||||||
if (witness)
|
if (witness)
|
||||||
assert(bcoin.address.parseBase58(w.getAddress()).type === 'witnesspubkeyhash');
|
assert(bcoin.address.fromBase58(w.getAddress()).type === 'witnesspubkeyhash');
|
||||||
else
|
else
|
||||||
assert(bcoin.address.parseBase58(w.getAddress()).type === 'pubkeyhash');
|
assert(bcoin.address.fromBase58(w.getAddress()).type === 'pubkeyhash');
|
||||||
|
|
||||||
var src = bcoin.mtx({
|
var src = bcoin.mtx({
|
||||||
outputs: [{
|
outputs: [{
|
||||||
@ -606,9 +606,9 @@ describe('Wallet', function() {
|
|||||||
var addr = w1.getAddress();
|
var addr = w1.getAddress();
|
||||||
|
|
||||||
if (witness)
|
if (witness)
|
||||||
assert(bcoin.address.parseBase58(addr).type === 'witnessscripthash');
|
assert(bcoin.address.fromBase58(addr).type === 'witnessscripthash');
|
||||||
else
|
else
|
||||||
assert(bcoin.address.parseBase58(addr).type === 'scripthash');
|
assert(bcoin.address.fromBase58(addr).type === 'scripthash');
|
||||||
|
|
||||||
assert.equal(w1.getAddress(), addr);
|
assert.equal(w1.getAddress(), addr);
|
||||||
assert.equal(w2.getAddress(), addr);
|
assert.equal(w2.getAddress(), addr);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user