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;
|
||||
|
||||
process.on('uncaughtException', function(err) {
|
||||
bcoin.debug(err.stack);
|
||||
bcoin.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@ -35,6 +35,16 @@ function Address(options) {
|
||||
if (!(this instanceof Address))
|
||||
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.type = options.type || 'pubkeyhash';
|
||||
this.version = options.version == null ? -1 : options.version;
|
||||
@ -42,7 +52,11 @@ function Address(options) {
|
||||
|
||||
if (!Buffer.isBuffer(this.hash))
|
||||
this.hash = new Buffer(this.hash, 'hex');
|
||||
}
|
||||
};
|
||||
|
||||
Address.fromOptions = function fromOptions(options) {
|
||||
return new Address().fromOptions(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the address hash.
|
||||
@ -161,7 +175,7 @@ Address.toBase58 = function toBase58(hash, type, version, network) {
|
||||
* @throws Parse error
|
||||
*/
|
||||
|
||||
Address.parseBase58 = function parseBase58(address) {
|
||||
Address.prototype.fromBase58 = function fromBase58(address) {
|
||||
var i, prefix, type, version, hash, network, p;
|
||||
|
||||
if (!Buffer.isBuffer(address))
|
||||
@ -194,12 +208,12 @@ Address.parseBase58 = function parseBase58(address) {
|
||||
|
||||
p.verifyChecksum();
|
||||
|
||||
return {
|
||||
network: network.type,
|
||||
type: type,
|
||||
hash: hash,
|
||||
version: version == null ? -1 : version
|
||||
};
|
||||
this.network = network.type;
|
||||
this.type = type;
|
||||
this.hash = hash;
|
||||
this.version = version == null ? -1 : version;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -210,7 +224,7 @@ Address.parseBase58 = function parseBase58(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}
|
||||
*/
|
||||
|
||||
Address.parseScript = function parseScript(script) {
|
||||
Address.prototype.fromScript = function fromScript(script) {
|
||||
var program, hash;
|
||||
|
||||
if (script.isWitnessProgram()) {
|
||||
program = script.getWitnessProgram();
|
||||
if (!program.type || program.type === 'unknown')
|
||||
program = script.toProgram();
|
||||
if (program.isUnknown())
|
||||
return;
|
||||
return {
|
||||
hash: program.data,
|
||||
type: program.type,
|
||||
version: program.version
|
||||
};
|
||||
this.hash = program.data;
|
||||
this.type = program.type;
|
||||
this.version = program.version;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Fast case
|
||||
if (script.isPubkey()) {
|
||||
hash = utils.ripesha(script.raw.slice(1, script.raw[0] + 1));
|
||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
||||
this.hash = utils.ripesha(script.raw.slice(1, script.raw[0] + 1));
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isPubkeyhash()) {
|
||||
hash = script.raw.slice(3, 23);
|
||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
||||
this.hash = script.raw.slice(3, 23);
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthash()) {
|
||||
hash = script.raw.slice(2, 22);
|
||||
return { hash: hash, type: 'scripthash', version: -1 };
|
||||
this.hash = script.raw.slice(2, 22);
|
||||
this.type = 'scripthash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Slow case (allow non-minimal data and parse script)
|
||||
if (script.isPubkey(true)) {
|
||||
hash = utils.ripesha(script.code[0].data);
|
||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
||||
this.hash = utils.ripesha(script.code[0].data);
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isPubkeyhash(true)) {
|
||||
hash = script.code[2].data;
|
||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
||||
this.hash = script.code[2].data;
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isMultisig()) {
|
||||
hash = utils.ripesha(script.raw);
|
||||
return { hash: hash, type: 'scripthash', version: -1 };
|
||||
this.hash = utils.ripesha(script.raw);
|
||||
this.type = 'scripthash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
@ -275,17 +300,21 @@ Address.parseScript = function parseScript(script) {
|
||||
* @returns {ParsedAddress|null}
|
||||
*/
|
||||
|
||||
Address.parseWitness = function parseWitness(witness) {
|
||||
Address.prototype.fromWitness = function fromWitness(witness) {
|
||||
var hash;
|
||||
|
||||
if (witness.isPubkeyhashInput()) {
|
||||
hash = utils.ripesha(witness.items[1]);
|
||||
return { hash: hash, type: 'witnesspubkeyhash', version: 0 };
|
||||
this.hash = utils.ripesha(witness.items[1]);
|
||||
this.type = 'witnesspubkeyhash';
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (witness.isScripthashInput()) {
|
||||
hash = utils.sha256(witness.items[witness.items.length - 1]);
|
||||
return { hash: hash, type: 'witnessscripthash', version: 0 };
|
||||
this.hash = utils.sha256(witness.items[witness.items.length - 1]);
|
||||
this.type = 'witnessscripthash';
|
||||
this.version = 0;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
@ -296,17 +325,21 @@ Address.parseWitness = function parseWitness(witness) {
|
||||
* @returns {ParsedAddress|null}
|
||||
*/
|
||||
|
||||
Address.parseInputScript = function parseInputScript(script) {
|
||||
Address.prototype.fromInputScript = function fromInputScript(script) {
|
||||
var hash;
|
||||
|
||||
if (script.isPubkeyhashInput()) {
|
||||
hash = utils.ripesha(script.code[1].data);
|
||||
return { hash: hash, type: 'pubkeyhash', version: -1 };
|
||||
this.hash = utils.ripesha(script.code[1].data);
|
||||
this.type = 'pubkeyhash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (script.isScripthashInput()) {
|
||||
hash = utils.ripesha(script.code[script.code.length - 1].data);
|
||||
return { hash: hash, type: 'scripthash', version: -1 };
|
||||
this.hash = utils.ripesha(script.code[script.code.length - 1].data);
|
||||
this.type = 'scripthash';
|
||||
this.version = -1;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
@ -317,12 +350,7 @@ Address.parseInputScript = function parseInputScript(script) {
|
||||
*/
|
||||
|
||||
Address.fromWitness = function fromWitness(witness) {
|
||||
var data = Address.parseWitness(witness);
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
return new Address(data);
|
||||
return new Address().fromWitness(witness);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -332,12 +360,7 @@ Address.fromWitness = function fromWitness(witness) {
|
||||
*/
|
||||
|
||||
Address.fromInputScript = function fromInputScript(script) {
|
||||
var data = Address.parseInputScript(script);
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
return new Address(data);
|
||||
return new Address().fromInputScript(script);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -347,12 +370,7 @@ Address.fromInputScript = function fromInputScript(script) {
|
||||
*/
|
||||
|
||||
Address.fromScript = function fromScript(script) {
|
||||
var data = Address.parseScript(script);
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
return new Address(data);
|
||||
return new Address().fromScript(script);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -363,15 +381,16 @@ Address.fromScript = function fromScript(script) {
|
||||
* @returns {ParsedAddress}
|
||||
*/
|
||||
|
||||
Address.parseHash = function parseHash(hash, type, version) {
|
||||
if (!Buffer.isBuffer(hash))
|
||||
Address.prototype.fromHash = function fromHash(hash, type, version, network) {
|
||||
if (typeof hash === 'string')
|
||||
hash = new Buffer(hash, 'hex');
|
||||
|
||||
return {
|
||||
hash: hash,
|
||||
type: type || 'pubkeyhash',
|
||||
version: version == null ? -1 : version
|
||||
};
|
||||
this.hash = hash;
|
||||
this.type = type || 'pubkeyhash';
|
||||
this.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}
|
||||
*/
|
||||
|
||||
Address.fromHash = function fromHash(hash, type, version) {
|
||||
return new Address(Address.parseHash(hash, type, version));
|
||||
Address.fromHash = function fromHash(hash, type, version, network) {
|
||||
return new Address().fromHash(hash, type, version, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -394,13 +413,13 @@ Address.fromHash = function fromHash(hash, type, version) {
|
||||
* @returns {ParsedAddress}
|
||||
*/
|
||||
|
||||
Address.parseData = function parseData(data, type, version) {
|
||||
Address.prototype.fromData = function fromData(data, type, version, network) {
|
||||
if (type === 'witnessscripthash')
|
||||
data = utils.sha256(data);
|
||||
else
|
||||
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}
|
||||
*/
|
||||
|
||||
Address.fromData = function fromData(data, type, version) {
|
||||
return new Address(Address.parseData(data, type, version));
|
||||
Address.fromData = function fromData(data, type, version, network) {
|
||||
return new Address().fromData(data, type, version, network);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -430,7 +449,7 @@ Address.validate = function validate(address, type) {
|
||||
return false;
|
||||
|
||||
try {
|
||||
address = Address.parseBase58(address);
|
||||
address = Address.fromBase58(address);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
@ -460,7 +479,7 @@ Address.getHash = function getHash(data, enc) {
|
||||
hash = data.hash;
|
||||
} else {
|
||||
try {
|
||||
hash = Address.parseBase58(data).hash;
|
||||
hash = Address.fromBase58(data).hash;
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -182,6 +182,7 @@ function Environment(options) {
|
||||
this.walletdb = require('./walletdb');
|
||||
this.provider = this.walletdb.Provider;
|
||||
this.peer = require('./peer');
|
||||
this.networkaddress = this.peer.NetworkAddress;
|
||||
this.pool = require('./pool');
|
||||
this.miner = require('./miner');
|
||||
this.minerblock = this.miner.MinerBlock;
|
||||
|
||||
@ -275,12 +275,8 @@ Peer.prototype._onConnect = function _onConnect() {
|
||||
version: constants.VERSION,
|
||||
services: constants.LOCAL_SERVICES,
|
||||
ts: bcoin.now(),
|
||||
remote: {},
|
||||
local: {
|
||||
services: constants.LOCAL_SERVICES,
|
||||
host: this.pool.host,
|
||||
port: this.pool.port
|
||||
},
|
||||
remote: new NetworkAddress(),
|
||||
local: this.pool.address,
|
||||
nonce: this.pool.localNonce,
|
||||
agent: constants.USER_AGENT,
|
||||
height: this.chain.height,
|
||||
@ -288,15 +284,10 @@ Peer.prototype._onConnect = function _onConnect() {
|
||||
}));
|
||||
|
||||
// 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.server) {
|
||||
this.write(this.framer.addr([{
|
||||
ts: utils.now() - (process.uptime() | 0),
|
||||
services: constants.LOCAL_SERVICES,
|
||||
host: this.pool.host,
|
||||
port: this.pool.port
|
||||
}]));
|
||||
this.write(this.framer.addr([this.pool.address]));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1443,7 +1434,7 @@ Peer.prototype._handleAddr = function _handleAddr(addrs) {
|
||||
var i, addr;
|
||||
|
||||
for (i = 0; i < addrs.length; i++) {
|
||||
addr = new NetworkAddress(addrs[i]);
|
||||
addr = addrs[i];
|
||||
this.addrFilter.add(addr.host, 'ascii');
|
||||
hosts.push(addr);
|
||||
}
|
||||
@ -1866,17 +1857,23 @@ Peer.prototype.inspect = function inspect() {
|
||||
*/
|
||||
|
||||
function NetworkAddress(options) {
|
||||
var host, ts, now;
|
||||
|
||||
if (!(this instanceof NetworkAddress))
|
||||
return new NetworkAddress(options);
|
||||
|
||||
now = utils.now();
|
||||
host = options.host;
|
||||
ts = options.ts;
|
||||
this.id = NetworkAddress.uid++;
|
||||
this.host = '0.0.0.0';
|
||||
this.port = 0;
|
||||
this.services = 0;
|
||||
this.ts = 0;
|
||||
|
||||
if (ts <= 100000000 || ts > now + 10 * 60)
|
||||
ts = now - 5 * 24 * 60 * 60;
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
}
|
||||
|
||||
NetworkAddress.uid = 0;
|
||||
|
||||
NetworkAddress.prototype.fromOptions = function fromOptions(options) {
|
||||
var host = options.host;
|
||||
|
||||
if (IP.version(host) !== -1)
|
||||
host = IP.normalize(host);
|
||||
@ -1886,14 +1883,17 @@ function NetworkAddress(options) {
|
||||
assert(typeof options.services === 'number');
|
||||
assert(typeof options.ts === 'number');
|
||||
|
||||
this.id = NetworkAddress.uid++;
|
||||
this.host = host;
|
||||
this.port = options.port;
|
||||
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.
|
||||
@ -1962,18 +1962,63 @@ NetworkAddress.prototype.inspect = function inspect() {
|
||||
* @returns {NetworkAddress}
|
||||
*/
|
||||
|
||||
NetworkAddress.fromHostname = function fromHostname(hostname, network) {
|
||||
NetworkAddress.prototype.fromHostname = function fromHostname(hostname, network) {
|
||||
var address = IP.parseHost(hostname);
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
return new NetworkAddress({
|
||||
host: address.host,
|
||||
port: address.port || network.port,
|
||||
version: constants.VERSION,
|
||||
services: constants.services.NETWORK
|
||||
| constants.services.BLOOM
|
||||
| constants.services.WITNESS,
|
||||
ts: utils.now()
|
||||
});
|
||||
|
||||
this.host = address.host;
|
||||
this.port = address.port || network.port;
|
||||
this.version = constants.VERSION;
|
||||
this.services = constants.services.NETWORK
|
||||
| constants.services.BLOOM
|
||||
| constants.services.WITNESS;
|
||||
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.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.destroyed = false;
|
||||
@ -326,7 +331,7 @@ Pool.prototype._init = function _init() {
|
||||
bcoin.error(err);
|
||||
|
||||
if (ip) {
|
||||
self.host = ip;
|
||||
self.address.host = 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));
|
||||
};
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* @param {VersionPacket} options
|
||||
@ -446,8 +418,8 @@ Framer.version = function version(options, writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
var agent = options.agent || constants.USER_AGENT;
|
||||
var services = options.services;
|
||||
var remote = options.remote || {};
|
||||
var local = options.local || {};
|
||||
var remote = options.remote || new bcoin.networkaddress();
|
||||
var local = options.local || new bcoin.networkaddress();
|
||||
var nonce = options.nonce;
|
||||
|
||||
if (services == null)
|
||||
@ -462,8 +434,8 @@ Framer.version = function version(options, writer) {
|
||||
p.write32(options.version || constants.VERSION);
|
||||
p.writeU64(services);
|
||||
p.write64(options.ts || bcoin.now());
|
||||
Framer.address(remote, false, p);
|
||||
Framer.address(local, false, p);
|
||||
remote.toRaw(false, p);
|
||||
local.toRaw(false, p);
|
||||
p.writeU64(nonce);
|
||||
p.writeVarString(agent, 'ascii');
|
||||
p.write32(options.height || 0);
|
||||
@ -765,7 +737,7 @@ Framer.reject = function reject(details, writer) {
|
||||
|
||||
/**
|
||||
* Create an addr packet (without a header).
|
||||
* @param {NakedNetworkAddress[]} hosts
|
||||
* @param {NetworkAddress[]} hosts
|
||||
* @param {BufferWriter?} writer - A buffer writer to continue writing from.
|
||||
* @returns {Buffer} Returns a BufferWriter if `writer` was passed in.
|
||||
*/
|
||||
@ -777,7 +749,7 @@ Framer.addr = function addr(hosts, writer) {
|
||||
p.writeVarint(hosts.length);
|
||||
|
||||
for (i = 0; i < hosts.length; i++)
|
||||
Framer.address(hosts[i], true, p);
|
||||
hosts[i].toRaw(true, p);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
@ -481,10 +481,10 @@ Parser.parseVersion = function parseVersion(p) {
|
||||
version = p.read32();
|
||||
services = p.readU53();
|
||||
ts = p.read53();
|
||||
recv = Parser.parseAddress(p, false);
|
||||
recv = bcoin.networkaddress.fromRaw(p, false);
|
||||
|
||||
if (p.left() > 0) {
|
||||
from = Parser.parseAddress(p, false);
|
||||
from = bcoin.networkaddress.fromRaw(p, false);
|
||||
nonce = p.readU64();
|
||||
} else {
|
||||
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.
|
||||
* @param {Buffer|BufferReader} p
|
||||
* @returns {NakedNetworkAddress[]}
|
||||
* @returns {NetworkAddress[]}
|
||||
*/
|
||||
|
||||
Parser.parseAddr = function parseAddr(p) {
|
||||
@ -767,7 +737,7 @@ Parser.parseAddr = function parseAddr(p) {
|
||||
assert(count <= 10000, 'Too many addresses.');
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
addrs.push(Parser.parseAddress(p, true));
|
||||
addrs.push(bcoin.networkaddress.fromRaw(p, true));
|
||||
|
||||
return addrs;
|
||||
};
|
||||
|
||||
@ -2771,7 +2771,7 @@ Script.prototype.isWitnessProgram = function isWitnessProgram() {
|
||||
* @returns {Program|null}
|
||||
*/
|
||||
|
||||
Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
||||
Script.prototype.toProgram = function toProgram() {
|
||||
var version, data, type;
|
||||
|
||||
if (!this.isWitnessProgram())
|
||||
@ -2780,23 +2780,7 @@ Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
||||
version = Script.getSmall(this.raw[0]);
|
||||
data = this.raw.slice(2);
|
||||
|
||||
if (version > 0) {
|
||||
// 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
|
||||
};
|
||||
return new Program(version, data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3819,7 +3803,7 @@ Script.getWitnessSigops = function getWitnessSigops(input, output, witness, flag
|
||||
assert((flags & constants.flags.VERIFY_P2SH) !== 0);
|
||||
|
||||
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
|
||||
// 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()) {
|
||||
redeem = input.getRedeem();
|
||||
if (redeem && redeem.isWitnessProgram())
|
||||
return Script.witnessSigops(redeem.getWitnessProgram(), witness, flags);
|
||||
return Script.witnessSigops(redeem.toProgram(), witness, flags);
|
||||
}
|
||||
|
||||
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) {
|
||||
var program = output.getWitnessProgram();
|
||||
var program = output.toProgram();
|
||||
var stack = witness.toStack();
|
||||
var witnessScript, redeem, j;
|
||||
|
||||
@ -4505,6 +4489,47 @@ Opcode.isOpcode = function isOpcode(obj) {
|
||||
&& (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
|
||||
*/
|
||||
|
||||
@ -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.agent, agent);
|
||||
assert.equal(payload.height, 0);
|
||||
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.agent, agent);
|
||||
assert.equal(payload.height, 10);
|
||||
@ -49,18 +73,18 @@ describe('Protocol', function() {
|
||||
});
|
||||
|
||||
var hosts = [
|
||||
{
|
||||
new bcoin.networkaddress({
|
||||
services: constants.LOCAL_SERVICES,
|
||||
host: '127.0.0.1',
|
||||
port: 8333,
|
||||
ts: Date.now() / 1000 | 0
|
||||
},
|
||||
{
|
||||
}),
|
||||
new bcoin.networkaddress({
|
||||
services: constants.LOCAL_SERVICES,
|
||||
host: '::123:456:789a',
|
||||
port: 18333,
|
||||
ts: Date.now() / 1000 | 0
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
packetTest('addr', hosts, function(payload) {
|
||||
|
||||
@ -105,9 +105,9 @@ describe('Wallet', function() {
|
||||
assert.ifError(err);
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.parseBase58(w.getAddress()).type === 'witnesspubkeyhash');
|
||||
assert(bcoin.address.fromBase58(w.getAddress()).type === 'witnesspubkeyhash');
|
||||
else
|
||||
assert(bcoin.address.parseBase58(w.getAddress()).type === 'pubkeyhash');
|
||||
assert(bcoin.address.fromBase58(w.getAddress()).type === 'pubkeyhash');
|
||||
|
||||
var src = bcoin.mtx({
|
||||
outputs: [{
|
||||
@ -606,9 +606,9 @@ describe('Wallet', function() {
|
||||
var addr = w1.getAddress();
|
||||
|
||||
if (witness)
|
||||
assert(bcoin.address.parseBase58(addr).type === 'witnessscripthash');
|
||||
assert(bcoin.address.fromBase58(addr).type === 'witnessscripthash');
|
||||
else
|
||||
assert(bcoin.address.parseBase58(addr).type === 'scripthash');
|
||||
assert(bcoin.address.fromBase58(addr).type === 'scripthash');
|
||||
|
||||
assert.equal(w1.getAddress(), addr);
|
||||
assert.equal(w2.getAddress(), addr);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user