some more stuff...not complete yet
This commit is contained in:
parent
32c690f52b
commit
ebddafcaa7
54
Block.js
54
Block.js
|
@ -1,17 +1,17 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
var Util = b.Util || require('../ext/util');
|
var util = b.util || require('./util/util');
|
||||||
var Debug1 = b.Debug1 || function() {};
|
var Debug1 = b.Debug1 || function() {};
|
||||||
var Script = b.Script || require('./script').class();
|
var Script = b.Script || require('./Script').class();
|
||||||
var Bignum = b.Bignum || require('bignum');
|
var Bignum = b.Bignum || require('bignum');
|
||||||
var Put = b.Put || require('bufferput');
|
var Put = b.Put || require('bufferput');
|
||||||
var Step = b.Step || require('step');
|
var Step = b.Step || require('step');
|
||||||
var Transaction = b.Transaction || require('./transaction');
|
var Transaction = b.Transaction || require('./transaction').class();
|
||||||
var TransactionIn = b.TransactionIn || require('./transactionIn');
|
var TransactionIn = Transaction.In;
|
||||||
var TransactionOut = b.TransactionOut || require('./transactionOut');
|
var TransactionOut = Transaction.Out;
|
||||||
var COINBASE_OP = Transaction.COINBASE_OP;
|
var COINBASE_OP = Transaction.COINBASE_OP;
|
||||||
var VerificationError = b.VerificationError || require('../ext/error').VerificationError;
|
var VerificationError = b.VerificationError || require('./util/error').VerificationError;
|
||||||
var BlockRules = {
|
var BlockRules = {
|
||||||
maxTimeOffset: 2 * 60 * 60, // How far block timestamps can be into the future
|
maxTimeOffset: 2 * 60 * 60, // How far block timestamps can be into the future
|
||||||
largestHash: Bignum(2).pow(256)
|
largestHash: Bignum(2).pow(256)
|
||||||
|
@ -23,8 +23,8 @@ function spec(b) {
|
||||||
data = {};
|
data = {};
|
||||||
}
|
}
|
||||||
this.hash = data.hash || null;
|
this.hash = data.hash || null;
|
||||||
this.prev_hash = data.prev_hash || Util.NULL_HASH;
|
this.prev_hash = data.prev_hash || util.NULL_HASH;
|
||||||
this.merkle_root = data.merkle_root || Util.NULL_HASH;
|
this.merkle_root = data.merkle_root || util.NULL_HASH;
|
||||||
this.timestamp = data.timestamp || 0;
|
this.timestamp = data.timestamp || 0;
|
||||||
this.bits = data.bits || 0;
|
this.bits = data.bits || 0;
|
||||||
this.nonce = data.nonce || 0;
|
this.nonce = data.nonce || 0;
|
||||||
|
@ -32,7 +32,7 @@ function spec(b) {
|
||||||
this.height = data.height || 0;
|
this.height = data.height || 0;
|
||||||
this.size = data.size || 0;
|
this.size = data.size || 0;
|
||||||
this.active = data.active || false;
|
this.active = data.active || false;
|
||||||
this.chainWork = data.chainWork || Util.EMPTY_BUFFER;
|
this.chainWork = data.chainWork || util.EMPTY_BUFFER;
|
||||||
this.txs = data.txs || [];
|
this.txs = data.txs || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ function spec(b) {
|
||||||
Block.prototype.calcHash = function calcHash() {
|
Block.prototype.calcHash = function calcHash() {
|
||||||
var header = this.getHeader();
|
var header = this.getHeader();
|
||||||
|
|
||||||
return Util.twoSha256(header);
|
return util.twoSha256(header);
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.checkHash = function checkHash() {
|
Block.prototype.checkHash = function checkHash() {
|
||||||
|
@ -65,7 +65,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.checkProofOfWork = function checkProofOfWork() {
|
Block.prototype.checkProofOfWork = function checkProofOfWork() {
|
||||||
var target = Util.decodeDiffBits(this.bits);
|
var target = util.decodeDiffBits(this.bits);
|
||||||
|
|
||||||
// TODO: Create a compare method in node-buffertools that uses the correct
|
// TODO: Create a compare method in node-buffertools that uses the correct
|
||||||
// endian so we don't have to reverse both buffers before comparing.
|
// endian so we don't have to reverse both buffers before comparing.
|
||||||
|
@ -89,7 +89,7 @@ function spec(b) {
|
||||||
* of all possible hashes would mean that 20 "work" is required to meet it.
|
* of all possible hashes would mean that 20 "work" is required to meet it.
|
||||||
*/
|
*/
|
||||||
Block.prototype.getWork = function getWork() {
|
Block.prototype.getWork = function getWork() {
|
||||||
var target = Util.decodeDiffBits(this.bits, true);
|
var target = util.decodeDiffBits(this.bits, true);
|
||||||
return BlockRules.largestHash.div(target.add(1));
|
return BlockRules.largestHash.div(target.add(1));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ function spec(b) {
|
||||||
// This function is a direct translation of CBlock::BuildMerkleTree().
|
// This function is a direct translation of CBlock::BuildMerkleTree().
|
||||||
|
|
||||||
if (txs.length == 0) {
|
if (txs.length == 0) {
|
||||||
return [Util.NULL_HASH.slice(0)];
|
return [util.NULL_HASH.slice(0)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start by adding all the hashes of the transactions as leaves of the tree.
|
// Start by adding all the hashes of the transactions as leaves of the tree.
|
||||||
|
@ -157,7 +157,7 @@ function spec(b) {
|
||||||
var i2 = Math.min(i + 1, size - 1);
|
var i2 = Math.min(i + 1, size - 1);
|
||||||
var a = tree[j + i];
|
var a = tree[j + i];
|
||||||
var b = tree[j + i2];
|
var b = tree[j + i2];
|
||||||
tree.push(Util.twoSha256(a.concat(b)));
|
tree.push(util.twoSha256(a.concat(b)));
|
||||||
}
|
}
|
||||||
j += size;
|
j += size;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.getBlockValue = function getBlockValue(height) {
|
Block.getBlockValue = function getBlockValue(height) {
|
||||||
var subsidy = Bignum(50).mul(Util.COIN);
|
var subsidy = Bignum(50).mul(util.COIN);
|
||||||
subsidy = subsidy.div(Bignum(2).pow(Math.floor(height / 210000)));
|
subsidy = subsidy.div(Bignum(2).pow(Math.floor(height / 210000)));
|
||||||
return subsidy;
|
return subsidy;
|
||||||
};
|
};
|
||||||
|
@ -209,7 +209,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.toString = function toString() {
|
Block.prototype.toString = function toString() {
|
||||||
return "<Block " + Util.formatHashAlt(this.hash) + " height="+this.height+">";
|
return "<Block " + util.formatHashAlt(this.hash) + " height="+this.height+">";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,7 +251,7 @@ function spec(b) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var powLimit = blockChain.getMinDiff();
|
var powLimit = blockChain.getMinDiff();
|
||||||
var powLimitTarget = Util.decodeDiffBits(powLimit, true);
|
var powLimitTarget = util.decodeDiffBits(powLimit, true);
|
||||||
|
|
||||||
var targetTimespan = blockChain.getTargetTimespan();
|
var targetTimespan = blockChain.getTargetTimespan();
|
||||||
var targetSpacing = blockChain.getTargetSpacing();
|
var targetSpacing = blockChain.getTargetSpacing();
|
||||||
|
@ -327,7 +327,7 @@ function spec(b) {
|
||||||
actualTimespan = targetTimespan*4;
|
actualTimespan = targetTimespan*4;
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldTarget = Util.decodeDiffBits(self.bits, true);
|
var oldTarget = util.decodeDiffBits(self.bits, true);
|
||||||
var newTarget = oldTarget.mul(actualTimespan).div(targetTimespan);
|
var newTarget = oldTarget.mul(actualTimespan).div(targetTimespan);
|
||||||
|
|
||||||
if (newTarget.cmp(powLimitTarget) > 0) {
|
if (newTarget.cmp(powLimitTarget) > 0) {
|
||||||
|
@ -339,7 +339,7 @@ function spec(b) {
|
||||||
Debug1('Before: '+oldTarget.toBuffer().toString('hex'));
|
Debug1('Before: '+oldTarget.toBuffer().toString('hex'));
|
||||||
Debug1('After: '+newTarget.toBuffer().toString('hex'));
|
Debug1('After: '+newTarget.toBuffer().toString('hex'));
|
||||||
|
|
||||||
callback(null, Util.encodeDiffBits(newTarget));
|
callback(null, util.encodeDiffBits(newTarget));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
}
|
}
|
||||||
|
@ -426,12 +426,12 @@ function spec(b) {
|
||||||
{
|
{
|
||||||
var tx = new Transaction();
|
var tx = new Transaction();
|
||||||
tx.ins.push(new TransactionIn({
|
tx.ins.push(new TransactionIn({
|
||||||
s: Util.EMPTY_BUFFER,
|
s: util.EMPTY_BUFFER,
|
||||||
q: 0xffffffff,
|
q: 0xffffffff,
|
||||||
o: COINBASE_OP
|
o: COINBASE_OP
|
||||||
}));
|
}));
|
||||||
tx.outs.push(new TransactionOut({
|
tx.outs.push(new TransactionOut({
|
||||||
v: Util.bigIntToValue(this.getBlockValue()),
|
v: util.bigIntToValue(this.getBlockValue()),
|
||||||
s: Script.createPubKeyOut(beneficiary).getBuffer()
|
s: Script.createPubKeyOut(beneficiary).getBuffer()
|
||||||
}));
|
}));
|
||||||
return tx;
|
return tx;
|
||||||
|
@ -518,7 +518,7 @@ function spec(b) {
|
||||||
|
|
||||||
Block.prototype.solve = function solve(miner, callback) {
|
Block.prototype.solve = function solve(miner, callback) {
|
||||||
var header = this.getHeader();
|
var header = this.getHeader();
|
||||||
var target = Util.decodeDiffBits(this.bits);
|
var target = util.decodeDiffBits(this.bits);
|
||||||
miner.solve(header, target, callback);
|
miner.solve(header, target, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -529,10 +529,10 @@ function spec(b) {
|
||||||
function getStandardizedObject(txs)
|
function getStandardizedObject(txs)
|
||||||
{
|
{
|
||||||
var block = {
|
var block = {
|
||||||
hash: Util.formatHashFull(this.getHash()),
|
hash: util.formatHashFull(this.getHash()),
|
||||||
version: this.version,
|
version: this.version,
|
||||||
prev_block: Util.formatHashFull(this.prev_hash),
|
prev_block: util.formatHashFull(this.prev_hash),
|
||||||
mrkl_root: Util.formatHashFull(this.merkle_root),
|
mrkl_root: util.formatHashFull(this.merkle_root),
|
||||||
time: this.timestamp,
|
time: this.timestamp,
|
||||||
bits: this.bits,
|
bits: this.bits,
|
||||||
nonce: this.nonce,
|
nonce: this.nonce,
|
||||||
|
@ -542,13 +542,13 @@ function spec(b) {
|
||||||
|
|
||||||
if (txs) {
|
if (txs) {
|
||||||
var mrkl_tree = this.getMerkleTree(txs).map(function (buffer) {
|
var mrkl_tree = this.getMerkleTree(txs).map(function (buffer) {
|
||||||
return Util.formatHashFull(buffer);
|
return util.formatHashFull(buffer);
|
||||||
});
|
});
|
||||||
block.mrkl_root = mrkl_tree[mrkl_tree.length - 1];
|
block.mrkl_root = mrkl_tree[mrkl_tree.length - 1];
|
||||||
|
|
||||||
block.n_tx = txs.length;
|
block.n_tx = txs.length;
|
||||||
var totalSize = 80; // Block header
|
var totalSize = 80; // Block header
|
||||||
totalSize += Util.getVarIntSize(txs.length); // txn_count
|
totalSize += util.getVarIntSize(txs.length); // txn_count
|
||||||
txs = txs.map(function (tx) {
|
txs = txs.map(function (tx) {
|
||||||
tx = tx.getStandardizedObject();
|
tx = tx.getStandardizedObject();
|
||||||
totalSize += tx.size;
|
totalSize += tx.size;
|
||||||
|
|
|
@ -2,6 +2,7 @@ require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
var config = b.config || require('./config');
|
var config = b.config || require('./config');
|
||||||
|
var log = b.log || require('./util/log')(config);
|
||||||
var network = b.network || require('./networks')[config.network];
|
var network = b.network || require('./networks')[config.network];
|
||||||
|
|
||||||
var MAX_RECEIVE_BUFFER = 10000000;
|
var MAX_RECEIVE_BUFFER = 10000000;
|
||||||
|
@ -11,13 +12,12 @@ function spec(b) {
|
||||||
var Put = b.Put || require('bufferput');
|
var Put = b.Put || require('bufferput');
|
||||||
var Buffers = b.Buffers || require('buffers');
|
var Buffers = b.Buffers || require('buffers');
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var log = b.log || require('bitpay/log');
|
var util = b.util || require('./util/util');
|
||||||
var Parser = b.Parser || require('./util/BinaryParser').class();
|
var Parser = b.Parser || require('./util/BinaryParser').class();
|
||||||
var util = require('./util/util');
|
|
||||||
var doubleSha256 = b.doubleSha256 || util.twoSha256;
|
var doubleSha256 = b.doubleSha256 || util.twoSha256;
|
||||||
var nonce = util.generateNonce();
|
var nonce = util.generateNonce();
|
||||||
|
|
||||||
var Block = require('../model/block').class();
|
var Block = require('./Block').class();
|
||||||
|
|
||||||
var BIP0031_VERSION = 60000;
|
var BIP0031_VERSION = 60000;
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ function spec(b) {
|
||||||
Connection.prototype.sendVersion = function () {
|
Connection.prototype.sendVersion = function () {
|
||||||
var subversion = '/BitcoinX:0.1/';
|
var subversion = '/BitcoinX:0.1/';
|
||||||
|
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
put.word32le(PROTOCOL_VERSION); // version
|
put.word32le(PROTOCOL_VERSION); // version
|
||||||
put.word64le(1); // services
|
put.word64le(1); // services
|
||||||
put.word64le(Math.round(new Date().getTime()/1000)); // timestamp
|
put.word64le(Math.round(new Date().getTime()/1000)); // timestamp
|
||||||
|
@ -185,7 +185,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendGetBlocks = function (starts, stop) {
|
Connection.prototype.sendGetBlocks = function (starts, stop) {
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
put.word32le(this.sendVer);
|
put.word32le(this.sendVer);
|
||||||
|
|
||||||
put.varint(starts.length);
|
put.varint(starts.length);
|
||||||
|
@ -208,7 +208,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendGetData = function (invs) {
|
Connection.prototype.sendGetData = function (invs) {
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
put.varint(invs.length);
|
put.varint(invs.length);
|
||||||
for (var i = 0; i < invs.length; i++) {
|
for (var i = 0; i < invs.length; i++) {
|
||||||
put.word32le(invs[i].type);
|
put.word32le(invs[i].type);
|
||||||
|
@ -218,13 +218,13 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendGetAddr = function (invs) {
|
Connection.prototype.sendGetAddr = function (invs) {
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
this.sendMessage('getaddr', put.buffer());
|
this.sendMessage('getaddr', put.buffer());
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendInv = function(data) {
|
Connection.prototype.sendInv = function(data) {
|
||||||
if(!Array.isArray(data)) data = [data];
|
if(!Array.isArray(data)) data = [data];
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
put.varint(data.length);
|
put.varint(data.length);
|
||||||
data.forEach(function (value) {
|
data.forEach(function (value) {
|
||||||
if (value instanceof Block) {
|
if (value instanceof Block) {
|
||||||
|
@ -240,7 +240,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendHeaders = function (headers) {
|
Connection.prototype.sendHeaders = function (headers) {
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
put.varint(headers.length);
|
put.varint(headers.length);
|
||||||
headers.forEach(function (header) {
|
headers.forEach(function (header) {
|
||||||
put.put(header);
|
put.put(header);
|
||||||
|
@ -256,7 +256,7 @@ function spec(b) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.sendBlock = function (block, txs) {
|
Connection.prototype.sendBlock = function (block, txs) {
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
|
|
||||||
// Block header
|
// Block header
|
||||||
put.put(block.getHeader());
|
put.put(block.getHeader());
|
||||||
|
@ -283,7 +283,7 @@ function spec(b) {
|
||||||
checksum = new Buffer([]);
|
checksum = new Buffer([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = Put(); // -- HEADER --
|
var message = new Put(); // -- HEADER --
|
||||||
message.put(magic); // magic bytes
|
message.put(magic); // magic bytes
|
||||||
message.put(commandBuf); // command name
|
message.put(commandBuf); // command name
|
||||||
message.pad(12 - commandBuf.length); // zero-padded
|
message.pad(12 - commandBuf.length); // zero-padded
|
||||||
|
|
|
@ -2,11 +2,11 @@ require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
var config = b.config || require('./config');
|
var config = b.config || require('./config');
|
||||||
|
var log = b.log || require('./util/log')(config);
|
||||||
var network = b.network || require('./networks')[config.network];
|
var network = b.network || require('./networks')[config.network];
|
||||||
var Connection = b.Connection || require('./Connection').createClass({config: config});
|
var Connection = b.Connection || require('./Connection').createClass({config: config});
|
||||||
var Peer = b.Peer || require('./Peer').class();
|
var Peer = b.Peer || require('./Peer').class();
|
||||||
var noop = function() {};
|
var noop = function() {};
|
||||||
var log = b.log || {info: noop, warn: noop, err: noop};
|
|
||||||
|
|
||||||
GetAdjustedTime = b.GetAdjustedTime || function () {
|
GetAdjustedTime = b.GetAdjustedTime || function () {
|
||||||
// TODO: Implement actual adjustment
|
// TODO: Implement actual adjustment
|
||||||
|
@ -31,16 +31,14 @@ function spec(b) {
|
||||||
|
|
||||||
PeerManager.Connection = Connection;
|
PeerManager.Connection = Connection;
|
||||||
|
|
||||||
PeerManager.prototype.start = function()
|
PeerManager.prototype.start = function() {
|
||||||
{
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
if(!this.timer) {
|
if(!this.timer) {
|
||||||
this.timer = setInterval(this.checkStatus.bind(this), this.interval);
|
this.timer = setInterval(this.checkStatus.bind(this), this.interval);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerManager.prototype.stop = function ()
|
PeerManager.prototype.stop = function() {
|
||||||
{
|
|
||||||
this.active = false;
|
this.active = false;
|
||||||
if(this.timer) {
|
if(this.timer) {
|
||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
|
@ -63,8 +61,7 @@ function spec(b) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PeerManager.prototype.checkStatus = function checkStatus()
|
PeerManager.prototype.checkStatus = function checkStatus() {
|
||||||
{
|
|
||||||
// Make sure we are connected to all forcePeers
|
// Make sure we are connected to all forcePeers
|
||||||
if(this.peers.length) {
|
if(this.peers.length) {
|
||||||
var peerIndex = {};
|
var peerIndex = {};
|
||||||
|
|
22
Script.js
22
Script.js
|
@ -1,6 +1,9 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
|
var config = b.config || require('./config');
|
||||||
|
var log = b.log || require('./util/log')(config);
|
||||||
|
|
||||||
var Opcode = require('./opcode').class();
|
var Opcode = require('./opcode').class();
|
||||||
|
|
||||||
// Make opcodes available as pseudo-constants
|
// Make opcodes available as pseudo-constants
|
||||||
|
@ -8,16 +11,15 @@ function spec(b) {
|
||||||
eval(i + " = " + Opcode.map[i] + ";");
|
eval(i + " = " + Opcode.map[i] + ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
var logger = b.logger || require('../ext/logger');
|
var util = b.util || require('./util/util');
|
||||||
var Util = b.Util || require('../ext/util');
|
var Parser = b.Parser || require('./util/BinaryParser').class();
|
||||||
var Parser = b.Parser || require('../ext/binaryParser').class();
|
|
||||||
var Put = b.Put || require('bufferput');
|
var Put = b.Put || require('bufferput');
|
||||||
|
|
||||||
function Script(buffer) {
|
function Script(buffer) {
|
||||||
if(buffer) {
|
if(buffer) {
|
||||||
this.buffer = buffer;
|
this.buffer = buffer;
|
||||||
} else {
|
} else {
|
||||||
this.buffer = Util.EMPTY_BUFFER;
|
this.buffer = util.EMPTY_BUFFER;
|
||||||
}
|
}
|
||||||
this.chunks = [];
|
this.chunks = [];
|
||||||
this.parse();
|
this.parse();
|
||||||
|
@ -84,10 +86,10 @@ function spec(b) {
|
||||||
case 'Address':
|
case 'Address':
|
||||||
return this.chunks[2];
|
return this.chunks[2];
|
||||||
case 'Pubkey':
|
case 'Pubkey':
|
||||||
return Util.sha256ripe160(this.chunks[0]);
|
return util.sha256ripe160(this.chunks[0]);
|
||||||
default:
|
default:
|
||||||
logger.scrdbg("Encountered non-standard scriptPubKey");
|
log.debug("Encountered non-standard scriptPubKey");
|
||||||
logger.scrdbg("Strange script was: " + this.toString());
|
log.debug("Strange script was: " + this.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -114,8 +116,8 @@ function spec(b) {
|
||||||
case 'Pubkey':
|
case 'Pubkey':
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
logger.scrdbg("Encountered non-standard scriptSig");
|
log.debug("Encountered non-standard scriptSig");
|
||||||
logger.scrdbg("Strange script was: " + this.toString());
|
log.debug("Strange script was: " + this.toString());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -144,7 +146,7 @@ function spec(b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Buffer.isBuffer(chunk)) {
|
if (Buffer.isBuffer(chunk)) {
|
||||||
script += "0x"+Util.formatBuffer(chunk, truncate ? null : 0);
|
script += "0x"+util.formatBuffer(chunk, truncate ? null : 0);
|
||||||
} else {
|
} else {
|
||||||
script += Opcode.reverseMap[chunk];
|
script += Opcode.reverseMap[chunk];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
|
var config = b.config || require('./config');
|
||||||
|
var log = b.log || require('./util/log')(config);
|
||||||
|
|
||||||
var Opcode = require('./opcode').class();
|
var Opcode = require('./opcode').class();
|
||||||
|
|
||||||
// Make opcodes available as pseudo-constants
|
// Make opcodes available as pseudo-constants
|
||||||
|
@ -9,8 +12,7 @@ function spec(b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var bignum = b.bignum || require('bignum');
|
var bignum = b.bignum || require('bignum');
|
||||||
var logger = b.logger || require('../ext/logger');
|
var Util = b.Util || require('./util/util');
|
||||||
var Util = b.Util || require('../ext/util');
|
|
||||||
var Script = require('./script').class();
|
var Script = require('./script').class();
|
||||||
|
|
||||||
function ScriptInterpreter() {
|
function ScriptInterpreter() {
|
||||||
|
@ -717,7 +719,7 @@ function spec(b) {
|
||||||
executeStep.call(this, cb);
|
executeStep.call(this, cb);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.scrdbg("Script aborted: "+
|
log.debug("Script aborted: "+
|
||||||
(e.message ? e : e));
|
(e.message ? e : e));
|
||||||
cb(e);
|
cb(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
require('classtool');
|
require('classtool');
|
||||||
|
|
||||||
function spec(b) {
|
function spec(b) {
|
||||||
var Script = b.Script || require('./script').class();
|
var config = b.config || require('./config');
|
||||||
var ScriptInterpreter = b.ScriptInterpreter || require('./scriptInterpreter').class();
|
var log = b.log || require('./util/log')(config);
|
||||||
var util = b.util || require('../ext/util');
|
var Script = b.Script || require('./Script').class();
|
||||||
|
var ScriptInterpreter = b.ScriptInterpreter || require('./ScriptInterpreter').class();
|
||||||
|
var util = b.util || require('./util/util');
|
||||||
var bignum = b.bignum || require('bignum');
|
var bignum = b.bignum || require('bignum');
|
||||||
var Put = b.Put || require('bufferput');
|
var Put = b.Put || require('bufferput');
|
||||||
var error = b.error || require('../ext/error');
|
var Parser = b.Parser || require('./util/BinaryParser').class();
|
||||||
var logger = b.logger || require('../ext/logger');
|
|
||||||
var Step = b.Step || require('step');
|
var Step = b.Step || require('step');
|
||||||
var Parser = b.Parser || require('../ext/binaryParser').class();
|
|
||||||
|
|
||||||
|
var error = b.error || require('./util/error');
|
||||||
var VerificationError = error.VerificationError;
|
var VerificationError = error.VerificationError;
|
||||||
var MissingSourceError = error.MissingSourceError;
|
var MissingSourceError = error.MissingSourceError;
|
||||||
|
|
||||||
|
@ -265,9 +266,9 @@ function spec(b) {
|
||||||
for (var i = 0, l = results.length; i < l; i++) {
|
for (var i = 0, l = results.length; i < l; i++) {
|
||||||
if (!results[i]) {
|
if (!results[i]) {
|
||||||
var txout = getTxOut(self.ins[i]);
|
var txout = getTxOut(self.ins[i]);
|
||||||
logger.scrdbg('Script evaluated to false');
|
log.debug('Script evaluated to false');
|
||||||
logger.scrdbg('|- scriptSig', ""+self.ins[i].getScript());
|
log.debug('|- scriptSig', ""+self.ins[i].getScript());
|
||||||
logger.scrdbg('`- scriptPubKey', ""+txout.getScript());
|
log.debug('`- scriptPubKey', ""+txout.getScript());
|
||||||
throw new VerificationError('Script for input '+i+' evaluated to false');
|
throw new VerificationError('Script for input '+i+' evaluated to false');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +303,7 @@ function spec(b) {
|
||||||
blockChain.getConflictingTransactions(outpoints, function (err, results) {
|
blockChain.getConflictingTransactions(outpoints, function (err, results) {
|
||||||
if (results.length) {
|
if (results.length) {
|
||||||
if (results[0].getHash().compare(self.getHash()) == 0) {
|
if (results[0].getHash().compare(self.getHash()) == 0) {
|
||||||
logger.warn("Detected tx re-add (recoverable db corruption): "
|
log.warn("Detected tx re-add (recoverable db corruption): "
|
||||||
+ util.formatHashAlt(results[0].getHash()));
|
+ util.formatHashAlt(results[0].getHash()));
|
||||||
// TODO: Needs to return an error for the memory pool case?
|
// TODO: Needs to return an error for the memory pool case?
|
||||||
callback(null, fees);
|
callback(null, fees);
|
||||||
|
@ -360,7 +361,7 @@ function spec(b) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// It's not our job to validate, so we just ignore any errors and issue
|
// It's not our job to validate, so we just ignore any errors and issue
|
||||||
// a very low level log message.
|
// a very low level log message.
|
||||||
logger.debug("Unable to determine affected pubkeys: " +
|
log.debug("Unable to determine affected pubkeys: " +
|
||||||
(err.stack ? err.stack : ""+err));
|
(err.stack ? err.stack : ""+err));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -395,7 +396,7 @@ function spec(b) {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// It's not our job to validate, so we just ignore any errors and issue
|
// It's not our job to validate, so we just ignore any errors and issue
|
||||||
// a very low level log message.
|
// a very low level log message.
|
||||||
logger.debug("Unable to determine affected pubkeys: " +
|
log.debug("Unable to determine affected pubkeys: " +
|
||||||
(err.stack ? err.stack : ""+err));
|
(err.stack ? err.stack : ""+err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,7 +708,7 @@ function spec(b) {
|
||||||
cb.apply(null, args);
|
cb.apply(null, args);
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error("Callback error after connecting tx inputs: "+
|
log.err("Callback error after connecting tx inputs: "+
|
||||||
(err.stack ? err.stack : err.toString()));
|
(err.stack ? err.stack : err.toString()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
network: 'livenet'
|
network: 'livenet',
|
||||||
|
logging: 'normal' // none, normal, debug
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,9 +28,12 @@
|
||||||
"classtool": ">=1.0.0",
|
"classtool": ">=1.0.0",
|
||||||
"base58-native": ">=0.1.1",
|
"base58-native": ">=0.1.1",
|
||||||
"bindings": "1.1.0",
|
"bindings": "1.1.0",
|
||||||
"bufferput": ">=0.1.1"
|
"bufferput": ">=0.1.1",
|
||||||
//"bignum"
|
"bignum": "0.6.1",
|
||||||
//"binary"
|
"binary": "0.3.0",
|
||||||
|
"step": "0.0.4",
|
||||||
|
"buffers": "0.0.1",
|
||||||
|
"buffertools": "1.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used during transcation verification when a source txout is missing.
|
||||||
|
*
|
||||||
|
* When a transaction is being verified by the memory pool this error causes
|
||||||
|
* it to be added to the orphan pool instead of being discarded.
|
||||||
|
*/
|
||||||
|
function MissingSourceError(msg, missingTxHash) {
|
||||||
|
// TODO: Since this happens in normal operation, perhaps we should
|
||||||
|
// avoid generating a whole stack trace.
|
||||||
|
Error.call(this);
|
||||||
|
Error.captureStackTrace(this, arguments.callee);
|
||||||
|
this.message = msg;
|
||||||
|
this.missingTxHash = missingTxHash;
|
||||||
|
this.name = 'MissingSourceError';
|
||||||
|
};
|
||||||
|
|
||||||
|
MissingSourceError.prototype.__proto__ = Error.prototype;
|
||||||
|
|
||||||
|
exports.MissingSourceError = MissingSourceError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in several places to indicate invalid data.
|
||||||
|
*
|
||||||
|
* We want to distinguish invalid data errors from program errors, so we use
|
||||||
|
* this exception to indicate the former.
|
||||||
|
*/
|
||||||
|
function VerificationError(msg, missingTxHash) {
|
||||||
|
// TODO: Since this happens in normal operation, perhaps we should
|
||||||
|
// avoid generating a whole stack trace.
|
||||||
|
Error.call(this);
|
||||||
|
Error.captureStackTrace(this, arguments.callee);
|
||||||
|
this.message = msg;
|
||||||
|
this.missingTxHash = missingTxHash;
|
||||||
|
this.name = 'VerificationError';
|
||||||
|
};
|
||||||
|
|
||||||
|
VerificationError.prototype.__proto__ = Error.prototype;
|
||||||
|
|
||||||
|
exports.VerificationError = VerificationError;
|
|
@ -0,0 +1,14 @@
|
||||||
|
var noop = function() {};
|
||||||
|
|
||||||
|
var loggers = {
|
||||||
|
none: {info: noop, warn: noop, err: noop, debug: noop},
|
||||||
|
normal: {info: console.log, warn: console.log, err: console.log, debug: noop},
|
||||||
|
debug: {info: console.log, warn: console.log, err: console.log, debug: console.log},
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = function(config) {
|
||||||
|
config = config || {};
|
||||||
|
if(config.log) return config.log;
|
||||||
|
if(config.loggers) return config.loggers[config.logging || 'normal'];
|
||||||
|
return loggers[config.logging || 'normal'];
|
||||||
|
};
|
39
util/util.js
39
util/util.js
|
@ -2,14 +2,7 @@ require('buffertools');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
var bignum = require('bignum');
|
var bignum = require('bignum');
|
||||||
var Binary = require('binary');
|
var Binary = require('binary');
|
||||||
var Put = require('put');
|
var Put = require('bufferput');
|
||||||
//var logger = require('./logger');
|
|
||||||
|
|
||||||
var ccmodule = require('bindings')('nativetools');
|
|
||||||
|
|
||||||
exports.ccmodule = ccmodule;
|
|
||||||
|
|
||||||
exports.BitcoinKey = ccmodule.BitcoinKey;
|
|
||||||
|
|
||||||
var sha256 = exports.sha256 = function (data) {
|
var sha256 = exports.sha256 = function (data) {
|
||||||
return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
|
return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
|
||||||
|
@ -31,8 +24,6 @@ var sha256ripe160 = exports.sha256ripe160 = function (data) {
|
||||||
return ripe160(sha256(data));
|
return ripe160(sha256(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
var sha256midstate = exports.sha256midstate = ccmodule.sha256_midstate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format a block hash like the official client does.
|
* Format a block hash like the official client does.
|
||||||
*/
|
*/
|
||||||
|
@ -119,7 +110,7 @@ var formatValue = exports.formatValue = function (valueBuffer) {
|
||||||
var pubKeyHashToAddress = exports.pubKeyHashToAddress = function (pubKeyHash, addressVersion) {
|
var pubKeyHashToAddress = exports.pubKeyHashToAddress = function (pubKeyHash, addressVersion) {
|
||||||
if (!pubKeyHash) return "";
|
if (!pubKeyHash) return "";
|
||||||
|
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
// Version
|
// Version
|
||||||
if(addressVersion) {
|
if(addressVersion) {
|
||||||
put.word8le(addressVersion);
|
put.word8le(addressVersion);
|
||||||
|
@ -139,7 +130,6 @@ var addressToPubKeyHash = exports.addressToPubKeyHash = function (address) {
|
||||||
|
|
||||||
// Check sanity
|
// Check sanity
|
||||||
if (!address.match(/^[1-9A-HJ-NP-Za-km-z]{27,35}$/)) {
|
if (!address.match(/^[1-9A-HJ-NP-Za-km-z]{27,35}$/)) {
|
||||||
//logger.warn("Not a valid Bitcoin address");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +145,6 @@ var addressToPubKeyHash = exports.addressToPubKeyHash = function (address) {
|
||||||
// Check checksum
|
// Check checksum
|
||||||
var checksum = twoSha256(buffer.slice(0, 21)).slice(0, 4);
|
var checksum = twoSha256(buffer.slice(0, 21)).slice(0, 4);
|
||||||
if (checksum.compare(parser.vars.checksum) !== 0) {
|
if (checksum.compare(parser.vars.checksum) !== 0) {
|
||||||
//logger.warn("Checksum comparison failed");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +273,7 @@ var reverseBytes32 = exports.reverseBytes32 = function (data) {
|
||||||
if (data.length % 4) {
|
if (data.length % 4) {
|
||||||
throw new Error("Util.reverseBytes32(): Data length must be multiple of 4");
|
throw new Error("Util.reverseBytes32(): Data length must be multiple of 4");
|
||||||
}
|
}
|
||||||
var put = Put();
|
var put = new Put();
|
||||||
var parser = Binary.parse(data);
|
var parser = Binary.parse(data);
|
||||||
while (!parser.eof()) {
|
while (!parser.eof()) {
|
||||||
var word = parser.word32le('word').vars.word;
|
var word = parser.word32le('word').vars.word;
|
||||||
|
@ -311,19 +300,13 @@ var getVarIntSize = exports.getVarIntSize = function getVarIntSize(i) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initializations
|
// Initializations
|
||||||
try {
|
exports.NULL_HASH = new Buffer(32).fill(0);
|
||||||
var NULL_HASH = exports.NULL_HASH = new Buffer(32).fill(0);
|
exports.EMPTY_BUFFER = new Buffer(0);
|
||||||
var EMPTY_BUFFER = exports.EMPTY_BUFFER = new Buffer(0);
|
exports.ZERO_VALUE = new Buffer(8).fill(0);
|
||||||
var ZERO_VALUE = exports.ZERO_VALUE = new Buffer(8).fill(0);
|
INT64_MAX = new Buffer('ffffffffffffffff', 'hex');
|
||||||
var INT64_MAX = exports.INT64_MAX = decodeHex("ffffffffffffffff");
|
|
||||||
|
|
||||||
// How much of Bitcoin's internal integer coin representation
|
// How much of Bitcoin's internal integer coin representation
|
||||||
// makes 1 BTC
|
// makes 1 BTC
|
||||||
var COIN = exports.COIN = 100000000;
|
exports.COIN = 100000000;
|
||||||
|
|
||||||
var MAX_TARGET = exports.MAX_TARGET = decodeHex('00000000FFFF0000000000000000000000000000000000000000000000000000');
|
exports.MAX_TARGET = new Buffer('00000000FFFF0000000000000000000000000000000000000000000000000000', 'hex');
|
||||||
} catch (e) {
|
|
||||||
//logger.error("Error while generating utility constants:\n" +
|
|
||||||
// (e.stack ? e.stack : e.toString()));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue