wallet/buffer/rpc: fix serialization and buffer writes. import keys.
This commit is contained in:
parent
4b008540e0
commit
d6e4978baf
@ -3073,19 +3073,55 @@ RPC.prototype.getwalletinfo = function getwalletinfo(args, callback) {
|
||||
};
|
||||
|
||||
RPC.prototype.importprivkey = function importprivkey(args, callback) {
|
||||
var self = this;
|
||||
var secret, label, rescan, key;
|
||||
|
||||
if (args.help || args.length < 1 || args.length > 3) {
|
||||
return callback(new RPCError('importprivkey'
|
||||
+ ' "bitcoinprivkey" ( "label" rescan )'));
|
||||
}
|
||||
// Impossible to implement in bcoin.
|
||||
callback(new Error('Not implemented.'));
|
||||
|
||||
secret = toString(args[0]);
|
||||
|
||||
if (args.length > 1)
|
||||
label = toString(args[1]);
|
||||
|
||||
if (args.length > 2)
|
||||
rescan = toBool(args[2]);
|
||||
|
||||
if (rescan && this.chain.db.options.prune)
|
||||
return callback(new RPCError('Cannot rescan when pruned.'));
|
||||
|
||||
key = bcoin.keyring.fromSecret(secret);
|
||||
|
||||
this.wallet.importKey(0, key, null, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!rescan)
|
||||
return callback(null, null);
|
||||
|
||||
self.walletdb.rescan(self.chain.db, 0, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
callback(null, null);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.importwallet = function importwallet(args, callback) {
|
||||
var file, data;
|
||||
|
||||
if (args.help || args.length !== 1)
|
||||
return callback(new RPCError('importwallet "filename"'));
|
||||
// Impossible to implement in bcoin.
|
||||
callback(new Error('Not implemented.'));
|
||||
|
||||
file = toString(args[0]),
|
||||
|
||||
fs.readFile(file, 'utf8', function(err, data) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.importaddress = function importaddress(args, callback) {
|
||||
@ -3098,10 +3134,43 @@ RPC.prototype.importaddress = function importaddress(args, callback) {
|
||||
};
|
||||
|
||||
RPC.prototype.importpubkey = function importpubkey(args, callback) {
|
||||
var self = this;
|
||||
var pubkey, label, rescan, key;
|
||||
|
||||
if (args.help || args.length < 1 || args.length > 4)
|
||||
return callback(new RPCError('importpubkey "pubkey" ( "label" rescan )'));
|
||||
// Impossible to implement in bcoin.
|
||||
callback(new Error('Not implemented.'));
|
||||
|
||||
pubkey = toString(args[0]);
|
||||
|
||||
if (!utils.isHex(pubkey))
|
||||
return callback(new RPCError('Invalid paremeter.'));
|
||||
|
||||
if (args.length > 1)
|
||||
label = toString(args[1]);
|
||||
|
||||
if (args.length > 2)
|
||||
rescan = toBool(args[2]);
|
||||
|
||||
if (rescan && this.chain.db.options.prune)
|
||||
return callback(new RPCError('Cannot rescan when pruned.'));
|
||||
|
||||
pubkey = new Buffer(pubkey, 'hex');
|
||||
|
||||
key = bcoin.keyring.fromPublic(pubkey, this.network);
|
||||
|
||||
this.wallet.importKey(0, key, null, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
if (!rescan)
|
||||
return callback(null, null);
|
||||
|
||||
self.walletdb.rescan(self.chain.db, 0, function(err) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
callback(null, null);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
RPC.prototype.keypoolrefill = function keypoolrefill(args, callback) {
|
||||
|
||||
@ -11,6 +11,7 @@ var bcoin = require('./env');
|
||||
var constants = bcoin.protocol.constants;
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var network = bcoin.protocol.network;
|
||||
var BufferReader = require('./reader');
|
||||
var BufferWriter = require('./writer');
|
||||
var scriptTypes = constants.scriptTypes;
|
||||
@ -79,9 +80,6 @@ KeyRing.prototype.fromOptions = function fromOptions(options, network) {
|
||||
this.witness = options.witness;
|
||||
}
|
||||
|
||||
if (options.keys)
|
||||
return this.fromKeys(key, options.m, options.n, options.keys, this.network);
|
||||
|
||||
if (options.script)
|
||||
return this.fromScript(key, options.script, this.network);
|
||||
|
||||
@ -148,12 +146,11 @@ KeyRing.prototype.fromPublic = function fromPublic(publicKey, network) {
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.generate = function(witness, network) {
|
||||
KeyRing.generate = function(network) {
|
||||
var key = new KeyRing();
|
||||
key.network = bcoin.network.get(network);
|
||||
key.privateKey = bcoin.ec.generatePrivateKey();
|
||||
key.publicKey = bcoin.ec.publicKeyCreate(key.privateKey, true);
|
||||
key.witness = !!witness;
|
||||
return key;
|
||||
};
|
||||
|
||||
@ -196,36 +193,6 @@ KeyRing.fromKey = function fromKey(key, network) {
|
||||
return new KeyRing().fromKey(key, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject data from public key.
|
||||
* @private
|
||||
* @param {Buffer} key
|
||||
* @param {Number} m
|
||||
* @param {Number} n
|
||||
* @param {Buffer[]} keys
|
||||
* @param {(NetworkType|Network}) network
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromKeys = function fromKeys(key, m, n, keys, network) {
|
||||
var script = bcoin.script.fromMultisig(m, n, keys);
|
||||
this.fromScript(key, script, network);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate keyring from keys.
|
||||
* @param {Buffer} key
|
||||
* @param {Number} m
|
||||
* @param {Number} n
|
||||
* @param {Buffer[]} keys
|
||||
* @param {(NetworkType|Network}) network
|
||||
* @returns {KeyRing}
|
||||
*/
|
||||
|
||||
KeyRing.fromKeys = function fromKeys(key, m, n, keys, network) {
|
||||
return new KeyRing().fromKeys(key, m, n, keys, network);
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject data from script.
|
||||
* @private
|
||||
@ -259,17 +226,12 @@ KeyRing.fromScript = function fromScript(key, script, network) {
|
||||
* @returns {Base58String}
|
||||
*/
|
||||
|
||||
KeyRing.prototype.toSecret = function toSecret(network) {
|
||||
KeyRing.prototype.toSecret = function toSecret() {
|
||||
var p = new BufferWriter();
|
||||
|
||||
assert(this.privateKey, 'Cannot serialize without private key.');
|
||||
|
||||
if (!network)
|
||||
network = this.network;
|
||||
|
||||
network = bcoin.network.get(network);
|
||||
|
||||
p.writeU8(network.keyPrefix.privkey);
|
||||
p.writeU8(this.network.keyPrefix.privkey);
|
||||
p.writeBytes(this.privateKey);
|
||||
|
||||
p.writeU8(1);
|
||||
@ -691,8 +653,10 @@ KeyRing.prototype.verify = function verify(msg, sig) {
|
||||
KeyRing.prototype.getType = function getType() {
|
||||
if (this.program)
|
||||
return this.program.getType();
|
||||
|
||||
if (this.script)
|
||||
return this.script.getType();
|
||||
|
||||
return scriptTypes.PUBKEYHASH;
|
||||
};
|
||||
|
||||
@ -766,7 +730,7 @@ KeyRing.prototype.toJSON = function toJSON() {
|
||||
return {
|
||||
network: this.network.type,
|
||||
witness: this.witness,
|
||||
key: this.publicKey.toString('hex'),
|
||||
publicKey: this.publicKey.toString('hex'),
|
||||
script: this.script ? this.script.toRaw().toString('hex') : null,
|
||||
type: constants.scriptTypesByVal[this.type].toLowerCase(),
|
||||
wid: this.path ? this.path.wid : undefined,
|
||||
@ -793,13 +757,6 @@ KeyRing.prototype.fromJSON = function fromJSON(json) {
|
||||
assert(typeof json.publicKey === 'string');
|
||||
assert(!json.script || typeof json.script === 'string');
|
||||
|
||||
assert(!json.wid || utils.isNumber(json.wid));
|
||||
assert(!json.id || utils.isName(json.id));
|
||||
assert(!json.name || utils.isName(json.name));
|
||||
assert(utils.isNumber(json.account));
|
||||
assert(utils.isNumber(json.change));
|
||||
assert(utils.isNumber(json.index));
|
||||
|
||||
this.nework = bcoin.network.get(json.network);
|
||||
this.witness = json.witness;
|
||||
this.publicKey = new Buffer(json.publicKey, 'hex');
|
||||
@ -807,12 +764,6 @@ KeyRing.prototype.fromJSON = function fromJSON(json) {
|
||||
if (json.script)
|
||||
this.script = new Buffer(json.script, 'hex');
|
||||
|
||||
this.wid = json.wid;
|
||||
this.name = json.name;
|
||||
this.account = json.account;
|
||||
this.change = json.change;
|
||||
this.index = json.index;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -859,10 +810,11 @@ KeyRing.prototype.toRaw = function toRaw(writer) {
|
||||
* @param {Buffer} data
|
||||
*/
|
||||
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data) {
|
||||
KeyRing.prototype.fromRaw = function fromRaw(data, network) {
|
||||
var p = new BufferReader(data);
|
||||
var i, count, key;
|
||||
|
||||
this.network = bcoin.network.get(network);
|
||||
this.witness = p.readU8() === 1;
|
||||
|
||||
key = p.readVarBytes();
|
||||
|
||||
@ -1253,7 +1253,7 @@ Wallet.prototype.getOutputPaths = function getOutputPaths(tx, callback) {
|
||||
* This is used for deriving new addresses when
|
||||
* a confirmed transaction is seen.
|
||||
* @param {PathInfo} info
|
||||
* @param {Function} callback - Returns [Errr, Boolean]
|
||||
* @param {Function} callback - Returns [Error, Boolean]
|
||||
* (true if new addresses were allocated).
|
||||
*/
|
||||
|
||||
@ -1273,6 +1273,9 @@ Wallet.prototype.syncOutputDepth = function syncOutputDepth(info, callback) {
|
||||
for (i = 0; i < info.paths.length; i++) {
|
||||
path = info.paths[i];
|
||||
|
||||
if (path.index === -1)
|
||||
continue;
|
||||
|
||||
if (!accounts[path.account])
|
||||
accounts[path.account] = [];
|
||||
|
||||
@ -2578,7 +2581,7 @@ Account.prototype.derivePath = function derivePath(path, master) {
|
||||
// Imported key.
|
||||
if (path.index === -1) {
|
||||
assert(path.imported);
|
||||
assert(this.n === 1);
|
||||
assert(this.type === Account.types.PUBKEYHASH);
|
||||
|
||||
raw = path.imported;
|
||||
|
||||
@ -2588,7 +2591,7 @@ Account.prototype.derivePath = function derivePath(path, master) {
|
||||
if (!raw)
|
||||
return;
|
||||
|
||||
ring = bcoin.keyring.fromRaw(raw);
|
||||
ring = bcoin.keyring.fromRaw(raw, this.network);
|
||||
ring.path = path;
|
||||
|
||||
return ring;
|
||||
|
||||
@ -92,7 +92,8 @@ var layout = {
|
||||
var len = Buffer.byteLength(id, 'utf8');
|
||||
var key = new Buffer(1 + len);
|
||||
key[0] = 0x6c;
|
||||
key.write(id, 1, 'utf8');
|
||||
if (len > 0)
|
||||
key.write(id, 1, 'utf8');
|
||||
return key;
|
||||
},
|
||||
ll: function(key) {
|
||||
@ -110,7 +111,8 @@ var layout = {
|
||||
var key = new Buffer(5 + len);
|
||||
key[0] = 0x69;
|
||||
key.writeUInt32BE(wid, 1, true);
|
||||
key.write(name, 5, 'utf8');
|
||||
if (len > 0)
|
||||
key.write(name, 5, 'utf8');
|
||||
return key;
|
||||
},
|
||||
ii: function ii(key) {
|
||||
@ -1110,16 +1112,24 @@ WalletDB.prototype.getWallets = function getWallets(callback) {
|
||||
* @param {Function} callback
|
||||
*/
|
||||
|
||||
WalletDB.prototype.rescan = function rescan(chaindb, callback) {
|
||||
WalletDB.prototype.rescan = function rescan(chaindb, height, callback) {
|
||||
var self = this;
|
||||
|
||||
if (typeof height === 'function') {
|
||||
callback = height;
|
||||
height = null;
|
||||
}
|
||||
|
||||
if (height == null)
|
||||
height = self.height;
|
||||
|
||||
this.getAddressHashes(function(err, hashes) {
|
||||
if (err)
|
||||
return callback(err);
|
||||
|
||||
self.logger.info('Scanning for %d addresses.', hashes.length);
|
||||
|
||||
chaindb.scan(self.height, hashes, function(block, txs, next) {
|
||||
chaindb.scan(height, hashes, function(block, txs, next) {
|
||||
self.addBlock(block, txs, next);
|
||||
}, callback);
|
||||
});
|
||||
@ -1624,7 +1634,7 @@ Path.prototype.fromRaw = function fromRaw(data) {
|
||||
case 0:
|
||||
this.change = p.readU32();
|
||||
this.index = p.readU32();
|
||||
if (p.left() > 0)
|
||||
if (p.readU8() === 1)
|
||||
this.script = p.readVarBytes();
|
||||
break;
|
||||
case 1:
|
||||
@ -1638,12 +1648,9 @@ Path.prototype.fromRaw = function fromRaw(data) {
|
||||
break;
|
||||
}
|
||||
|
||||
this.version = p.readU8();
|
||||
this.version = p.read8();
|
||||
this.type = p.readU8();
|
||||
|
||||
if (this.version === 0xff)
|
||||
this.version = -1;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -1670,11 +1677,16 @@ Path.prototype.toRaw = function toRaw(writer) {
|
||||
p.writeU32(this.account);
|
||||
|
||||
if (this.index !== -1) {
|
||||
assert(!this.imported);
|
||||
p.writeU8(0);
|
||||
p.writeU32(this.change);
|
||||
p.writeU32(this.index);
|
||||
if (this.script)
|
||||
if (this.script) {
|
||||
p.writeU8(1);
|
||||
p.writeVarBytes(this.script);
|
||||
} else {
|
||||
p.writeU8(0);
|
||||
}
|
||||
} else {
|
||||
assert(this.imported);
|
||||
p.writeU8(1);
|
||||
@ -1682,7 +1694,7 @@ Path.prototype.toRaw = function toRaw(writer) {
|
||||
p.writeVarBytes(this.imported);
|
||||
}
|
||||
|
||||
p.writeU8(this.version === -1 ? 0xff : this.version);
|
||||
p.write8(this.version);
|
||||
p.writeU8(this.type);
|
||||
|
||||
if (!writer)
|
||||
@ -1718,10 +1730,6 @@ Path.prototype.fromAccount = function fromAccount(account, ring, change, index)
|
||||
return this;
|
||||
};
|
||||
|
||||
Path.fromAccount = function fromAccount(account, ring, change, index) {
|
||||
return new Path().fromAccount(account, ring, change, index);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate path from keyring.
|
||||
* @param {WalletID} wid
|
||||
@ -1729,8 +1737,8 @@ Path.fromAccount = function fromAccount(account, ring, change, index) {
|
||||
* @returns {Path}
|
||||
*/
|
||||
|
||||
Path.fromKeyRing = function fromKeyRing(ring) {
|
||||
return new Path().fromKeyRing(ring);
|
||||
Path.fromAccount = function fromAccount(account, ring, change, index) {
|
||||
return new Path().fromAccount(account, ring, change, index);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1749,8 +1757,8 @@ Path.prototype.toPath = function toPath() {
|
||||
* @returns {Address}
|
||||
*/
|
||||
|
||||
Path.prototype.toAddress = function toAddress() {
|
||||
return bcoin.address.fromHash(this.hash, this.type, this.version);
|
||||
Path.prototype.toAddress = function toAddress(network) {
|
||||
return bcoin.address.fromHash(this.hash, this.type, this.version, network);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -393,7 +393,12 @@ BufferWriter.prototype.writeVarBytes = function writeVarBytes(value) {
|
||||
BufferWriter.prototype.writeString = function writeString(value, enc) {
|
||||
if (typeof value !== 'string')
|
||||
return this.writeBytes(value);
|
||||
|
||||
this.written += Buffer.byteLength(value, enc);
|
||||
|
||||
if (value.length === 0)
|
||||
return;
|
||||
|
||||
this.data.push([STR, value, enc]);
|
||||
};
|
||||
|
||||
@ -424,6 +429,10 @@ BufferWriter.prototype.writeVarString = function writeVarString(value, enc) {
|
||||
this.written += size;
|
||||
|
||||
this.data.push([VARINT, size]);
|
||||
|
||||
if (value.length === 0)
|
||||
return;
|
||||
|
||||
this.data.push([STR, value, enc]);
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user