Browse Source

add tests and refactor wallet.processTx

hk-custom-address
Wei Lu 11 years ago
parent
commit
dbb5681366
  1. 50
      src/wallet.js
  2. 4
      test/fixtures/mainnet_tx.json
  3. 80
      test/wallet.js

50
src/wallet.js

@ -135,31 +135,35 @@ var Wallet = function (seed, options) {
return value == undefined
}
// Processes a transaction object
// If "verified" is true, then we trust the transaction as "final"
this.processTx = function(tx, verified) {
this.processTx = function(tx) {
var txhash = convert.bytesToHex(tx.getHash())
for (var i = 0; i < tx.outs.length; i++) {
if (this.addresses.indexOf(tx.outs[i].address.toString()) >= 0) {
me.outputs[txhash+':'+i] = {
output: txhash+':'+i,
value: tx.outs[i].value,
address: tx.outs[i].address.toString(),
timestamp: new Date().getTime() / 1000,
pending: true
tx.outs.forEach(function(txOut, i){
var address = txOut.address.toString()
if (isMyAddress(address)) {
var output = txhash+':'+i
me.outputs[output] = {
output: output,
value: txOut.value,
address: address,
scriptPubKey: convert.bytesToHex(txOut.script.buffer) //TODO: txOut.scriptPubKey()
// timestamp: new Date().getTime() / 1000,
// pending: true
}
}
}
for (var i = 0; i < tx.ins.length; i++) {
var op = tx.ins[i].outpoint
})
tx.ins.forEach(function(txIn, i){
var op = txIn.outpoint
var o = me.outputs[op.hash+':'+op.index]
if (o) {
o.spend = txhash+':'+i
o.spendpending = true
o.timestamp = new Date().getTime() / 1000
// o.spendpending = true
// o.timestamp = new Date().getTime() / 1000
}
}
})
}
// Processes an output from an external source of the form
// { output: txhash:index, value: integer, address: address }
// Excellent compatibility with SX and pybitcointools
@ -276,6 +280,18 @@ var Wallet = function (seed, options) {
throw new Error('Unknown address. Make sure the address is from the keychain and has been generated.')
}
}
function isReceiveAddress(address){
return me.addresses.indexOf(address) > -1
}
function isChangeAddress(address){
return me.changeAddresses.indexOf(address) > -1
}
function isMyAddress(address) {
return isReceiveAddress(address) || isChangeAddress(address)
}
};
module.exports = Wallet;

4
test/fixtures/mainnet_tx.json

@ -0,0 +1,4 @@
{
"prevTx": "0100000001e0214ebebb0fd3414d3fdc0dbf3b0f4b247a296cafc984558622c3041b0fcc9b010000008b48304502206becda98cecf7a545d1a640221438ff8912d9b505ede67e0138485111099f696022100ccd616072501310acba10feb97cecc918e21c8e92760cd35144efec7622938f30141040cd2d2ce17a1e9b2b3b2cb294d40eecf305a25b7e7bfdafae6bb2639f4ee399b3637706c3d377ec4ab781355add443ae864b134c5e523001c442186ea60f0eb8ffffffff03a0860100000000001976a91400ea3576c8fcb0bc8392f10e23a3425ae24efea888ac40420f00000000001976a91477890e8ec967c5fd4316c489d171fd80cf86997188acf07cd210000000001976a9146fb93c557ee62b109370fd9003e456917401cbfa88ac00000000",
"tx": "0100000001576bc3c3285dbdccd8c3cbd8c03e10d7f77a5c839c744f34c3eb00511059b80c000000006b483045022100a82a31607b837c1ae510ae3338d1d3c7cbd57c15e322ab6e5dc927d49bffa66302205f0db6c90f1fae3c8db4ebfa753d7da1b2343d653ce0331aa94ed375e6ba366c0121020497bfc87c3e97e801414fed6a0db4b8c2e01c46e2cf9dff59b406b52224a76bffffffff02409c0000000000001976a9143443bc45c560866cfeabf1d52f50a6ed358c69f288ac50c30000000000001976a91477890e8ec967c5fd4316c489d171fd80cf86997188ac00000000"
}

80
test/wallet.js

@ -1,10 +1,15 @@
var Wallet = require('../src/wallet.js')
var HDNode = require('../src/hdwallet.js')
var Transaction = require('../src/transaction.js').Transaction
var convert = require('../src/convert.js')
var assert = require('assert')
var SHA256 = require('crypto-js/sha256')
var Crypto = require('crypto-js')
var fixtureTxes = require('./fixtures/mainnet_tx')
var fixtureTx1Hex = fixtureTxes.prevTx
var fixtureTx2Hex = fixtureTxes.tx
describe('Wallet', function() {
var seed, wallet;
beforeEach(function(){
@ -234,6 +239,81 @@ describe('Wallet', function() {
})
})
describe('processTx', function(){
var tx;
beforeEach(function(){
tx = Transaction.deserialize(fixtureTx1Hex)
})
describe("when tx outs contains an address owned by the wallet, an 'output' gets added to wallet.outputs", function(){
it("works for receive address", function(){
var totalOuts = outputCount()
wallet.addresses = [tx.outs[0].address.toString()]
wallet.processTx(tx)
assert.equal(outputCount(), totalOuts + 1)
verifyOutputAdded(0)
})
it("works for change address", function(){
var totalOuts = outputCount()
wallet.changeAddresses = [tx.outs[1].address.toString()]
wallet.processTx(tx)
assert.equal(outputCount(), totalOuts + 1)
verifyOutputAdded(1)
})
function outputCount(){
return Object.keys(wallet.outputs).length
}
function verifyOutputAdded(index) {
var txOut = tx.outs[index]
var key = convert.bytesToHex(tx.getHash()) + ":" + index
var output = wallet.outputs[key]
assert.equal(output.output, key)
assert.equal(output.value, txOut.value)
assert.equal(output.address, txOut.address)
assert.equal(output.scriptPubKey, convert.bytesToHex(txOut.script.buffer))
}
})
describe("when tx ins outpoint contains a known txhash:i, the corresponding 'output' gets updated", function(){
beforeEach(function(){
wallet.addresses = [tx.outs[0].address.toString()] // the address fixtureTx2 is spending from
wallet.processTx(tx)
tx = Transaction.deserialize(fixtureTx2Hex)
})
it("does not add to wallet.outputs", function(){
var outputs = wallet.outputs
wallet.processTx(tx)
assert.deepEqual(wallet.outputs, outputs)
})
it("sets spend with the transaction hash and input index", function(){
wallet.processTx(tx)
var txIn = tx.ins[0]
var key = txIn.outpoint.hash + ":" + txIn.outpoint.index
var output = wallet.outputs[key]
assert.equal(output.spend, convert.bytesToHex(tx.getHash()) + ':' + 0)
})
})
it("does nothing when none of the involved addresses belong to the wallet", function(){
var outputs = wallet.outputs
wallet.processTx(tx)
assert.deepEqual(wallet.outputs, outputs)
})
})
function assertEqual(obj1, obj2){
assert.equal(obj1.toString(), obj2.toString())
}

Loading…
Cancel
Save