Transaction: use hash Buffer instead of hex string

This commit is contained in:
Daniel Cousens 2014-06-15 00:03:17 +10:00
parent 2f56e63491
commit 5551c38812
5 changed files with 44 additions and 33 deletions

View file

@ -55,11 +55,16 @@ Transaction.prototype.addInput = function(tx, outIndex) {
var hash
if (typeof tx === 'string') {
hash = tx
hash = new Buffer(tx, 'hex')
assert.equal(hash.length, 32, 'Invalid TX hash')
// TxHash hex is big-endian, we need little-endian
Array.prototype.reverse.call(hash)
} else {
assert(tx instanceof Transaction, 'Unexpected input: ' + tx)
hash = tx.getId()
assert(tx instanceof Transaction, 'Expected Transaction, got ' + tx)
hash = crypto.hash256(tx.toBuffer())
}
this.ins.push(new TransactionIn({
@ -142,13 +147,8 @@ Transaction.prototype.toBuffer = function () {
writeUInt32(this.version)
writeVarInt(this.ins.length)
this.ins.forEach(function(txin) {
var hash = new Buffer(txin.outpoint.hash, 'hex') // FIXME: Performance: convert on tx.addInput instead
// TxHash hex is big-endian, we need little-endian
Array.prototype.reverse.call(hash)
writeSlice(hash)
this.ins.forEach(function(txin, i) {
writeSlice(txin.outpoint.hash)
writeUInt32(txin.outpoint.index)
writeVarInt(txin.script.buffer.length)
writeSlice(txin.script.buffer)
@ -240,9 +240,6 @@ Transaction.prototype.clone = function () {
}
Transaction.fromBuffer = function(buffer) {
// Copy because we mutate (reverse TxOutHashs)
buffer = new Buffer(buffer)
var offset = 0
function readSlice(n) {
offset += n
@ -272,10 +269,6 @@ Transaction.fromBuffer = function(buffer) {
for (var i = 0; i < vinLen; ++i) {
var hash = readSlice(32)
// TxHash is little-endian, we want big-endian hex
Array.prototype.reverse.call(hash)
var vout = readUInt32()
var scriptLen = readVarInt()
var script = readSlice(scriptLen)
@ -283,7 +276,7 @@ Transaction.fromBuffer = function(buffer) {
ins.push(new TransactionIn({
outpoint: {
hash: hash.toString('hex'),
hash: hash,
index: vout
},
script: Script.fromBuffer(script),

View file

@ -169,9 +169,15 @@ function Wallet(seed, network) {
}
})
tx.ins.forEach(function(txIn, i){
tx.ins.forEach(function(txIn, i) {
var op = txIn.outpoint
var output = op.hash + ':' + op.index
// copy and convert to big-endian hex
var txinHash = new Buffer(op.hash)
Array.prototype.reverse.call(txinHash)
txinHash = txinHash.toString('hex')
var output = txinHash + ':' + op.index
if(me.outputs[output]) delete me.outputs[output]
})

View file

@ -147,7 +147,12 @@ describe('Bitcoin-core', function() {
var prevOutIndex = input[1]
// var prevOutScriptPubKey = input[2] // TODO: we don't have a ASM parser
assert.equal(txin.outpoint.hash, prevOutHash)
var actualHash = txin.outpoint.hash
// Test data is big-endian
Array.prototype.reverse.call(actualHash)
assert.equal(actualHash.toString('hex'), prevOutHash)
// we read UInt32, not Int32
assert.equal(txin.outpoint.index & 0xffffffff, prevOutIndex)
@ -184,7 +189,7 @@ describe('Bitcoin-core', function() {
}
if (actualHash != undefined) {
// BigEndian test data
// Test data is big-endian
Array.prototype.reverse.call(actualHash)
assert.equal(actualHash.toString('hex'), expectedHash)

View file

@ -59,7 +59,7 @@ describe('Transaction', function() {
assert.equal(input.sequence, 4294967295)
assert.equal(input.outpoint.index, 0)
assert.equal(input.outpoint.hash, "69d02fc05c4e0ddc87e796eee42693c244a3112fffe1f762c3fb61ffcb304634")
assert.equal(input.outpoint.hash.toString('hex'), "344630cbff61fbc362f7e1ff2f11a344c29326e4ee96e787dc0d4e5cc02fd069")
assert.equal(b2h(input.script.buffer),
"493046022100ef89701f460e8660c80808a162bbf2d676f40a331a243592c36d6bd1f81d6bdf022100d29c072f1b18e59caba6e1f0b8cadeb373fd33a25feded746832ec179880c23901")
@ -120,7 +120,7 @@ describe('Transaction', function() {
assert.equal(input.sequence, 4294967295)
assert.equal(input.outpoint.index, 0)
assert.equal(input.outpoint.hash, "0cb859105100ebc3344f749c835c7af7d7103ec0d8cbc3d8ccbd5d28c3c36b57")
assert.equal(input.outpoint.hash.toString('hex'), "576bc3c3285dbdccd8c3cbd8c03e10d7f77a5c839c744f34c3eb00511059b80c")
assert.equal(input.script, Script.EMPTY)
}

View file

@ -14,7 +14,15 @@ var fixtureTx1Hex = fixtureTxes.prevTx
var fixtureTx2Hex = fixtureTxes.tx
function fakeTxHash(i) {
return "efefefefefefefefefefefefefefefefefefefefefefefefefefefefefefefe" + i
var hash = new Buffer(32)
hash.fill(i)
return hash
}
function fakeTxId(i) {
var hash = fakeTxHash(i)
Array.prototype.reverse.call(hash)
return hash.toString('hex')
}
describe('Wallet', function() {
@ -263,12 +271,11 @@ describe('Wallet', function() {
})
describe('processConfirmedTx', function(){
it('does not fail on scripts with no corresponding Address', function() {
var pubKey = wallet.getPrivateKey(0).pub
var script = scripts.pubKeyOutput(pubKey)
var tx2 = new Transaction()
tx2.addInput(fakeTxHash(1), 0)
tx2.addInput(fakeTxId(1), 0)
// FIXME: Transaction doesn't support custom ScriptPubKeys... yet
// So for now, we hijack the script with our own, and undefine the cached address
@ -365,19 +372,19 @@ describe('Wallet', function() {
// set up 3 utxo
utxo = [
{
"hash": fakeTxHash(1),
"hash": fakeTxId(1),
"outputIndex": 0,
"address" : address1,
"value": 400000 // not enough for value
},
{
"hash": fakeTxHash(2),
"hash": fakeTxId(2),
"outputIndex": 1,
"address" : address1,
"value": 500000 // enough for only value
},
{
"hash": fakeTxHash(3),
"hash": fakeTxId(3),
"outputIndex": 0,
"address" : address2,
"value": 520000 // enough for value and fee
@ -415,7 +422,7 @@ describe('Wallet', function() {
it('ignores pending outputs', function(){
utxo.push(
{
"hash": fakeTxHash(4),
"hash": fakeTxId(4),
"outputIndex": 0,
"address" : address2,
"value": 530000,
@ -437,7 +444,7 @@ describe('Wallet', function() {
var address = wallet.generateAddress()
wallet.setUnspentOutputs([{
hash: fakeTxHash(0),
hash: fakeTxId(0),
outputIndex: 0,
address: address,
value: value
@ -459,7 +466,7 @@ describe('Wallet', function() {
var address = wallet.generateAddress()
wallet.setUnspentOutputs([{
hash: fakeTxHash(0),
hash: fakeTxId(0),
outputIndex: 0,
address: address,
value: value