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 return value == undefined
} }
// Processes a transaction object this.processTx = function(tx) {
// If "verified" is true, then we trust the transaction as "final"
this.processTx = function(tx, verified) {
var txhash = convert.bytesToHex(tx.getHash()) 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) { tx.outs.forEach(function(txOut, i){
me.outputs[txhash+':'+i] = { var address = txOut.address.toString()
output: txhash+':'+i, if (isMyAddress(address)) {
value: tx.outs[i].value, var output = txhash+':'+i
address: tx.outs[i].address.toString(), me.outputs[output] = {
timestamp: new Date().getTime() / 1000, output: output,
pending: true 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] var o = me.outputs[op.hash+':'+op.index]
if (o) { if (o) {
o.spend = txhash+':'+i o.spend = txhash+':'+i
o.spendpending = true // o.spendpending = true
o.timestamp = new Date().getTime() / 1000 // o.timestamp = new Date().getTime() / 1000
} }
} })
} }
// Processes an output from an external source of the form // Processes an output from an external source of the form
// { output: txhash:index, value: integer, address: address } // { output: txhash:index, value: integer, address: address }
// Excellent compatibility with SX and pybitcointools // 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.') 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; 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 Wallet = require('../src/wallet.js')
var HDNode = require('../src/hdwallet.js') var HDNode = require('../src/hdwallet.js')
var Transaction = require('../src/transaction.js').Transaction
var convert = require('../src/convert.js') var convert = require('../src/convert.js')
var assert = require('assert') var assert = require('assert')
var SHA256 = require('crypto-js/sha256') var SHA256 = require('crypto-js/sha256')
var Crypto = require('crypto-js') var Crypto = require('crypto-js')
var fixtureTxes = require('./fixtures/mainnet_tx')
var fixtureTx1Hex = fixtureTxes.prevTx
var fixtureTx2Hex = fixtureTxes.tx
describe('Wallet', function() { describe('Wallet', function() {
var seed, wallet; var seed, wallet;
beforeEach(function(){ 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){ function assertEqual(obj1, obj2){
assert.equal(obj1.toString(), obj2.toString()) assert.equal(obj1.toString(), obj2.toString())
} }

Loading…
Cancel
Save