Skip to content

Instantly share code, notes, and snippets.

@abrkn
Created November 27, 2012 18:39
Show Gist options
  • Save abrkn/4156125 to your computer and use it in GitHub Desktop.
Save abrkn/4156125 to your computer and use it in GitHub Desktop.
var config = require('../config')
, bitcoin = new (require('bitcoin').Client)(config('BTC'))
, async = require('async')
, db = require('./db')
, num = require('num')
, minHeight = 209848
var oldHeight, height, hash, block
function nextBlock() {
async.series({
'find last height in db': function(next) {
var client = db()
client.query('SELECT MAX(height) height FROM btc_block', function(err, res) {
client.end()
if (err) return next(err)
oldHeight = res.rows[0].height || minHeight
next()
})
},
'find current height': function(next) {
bitcoin.getBlockCount(function(err, count) {
if (err) return next(err)
height = count
if (oldHeight >= height - 3) {
return console.log('nothing to do')
}
next()
})
},
'find the block hash': function(next) {
bitcoin.getBlockHash(oldHeight + 1, function(err, h) {
if (err) return next(err)
hash = h
console.log('old height + 1 found with hash ', hash)
next()
})
},
'get the block': function(next) {
bitcoin.getBlock(hash, function(err, b) {
if (err) return next(err)
block = b
next()
})
},
'enumerate the transactions': function(next) {
console.log('enumerating', block.tx.length, ' tx in the block')
// todo: para
async.forEachLimit(block.tx, 10, function(txid, next) {
console.log('analyzing tx', txid)
var rawtxt, tx
async.series({
'get the raw tx': function(next) {
bitcoin.getRawTransaction(txid, function(err, r) {
if (err) return next(err)
rawtx = r
next()
})
},
'decode the raw transaction': function(next) {
bitcoin.decodeRawTransaction(rawtx, function(err, t) {
if (err) return next(err)
tx = t
next()
})
},
'enumerate outputs': function(next) {
//console.log('enumerating', tx.vout.length, 'outputs')
async.forEachLimit(tx.vout, 10, function(o, next) {
if (!o.scriptPubKey) throw new Error('scriptPubKey missing')
if (!o.scriptPubKey.addresses) throw new Error('addresses missing')
if (o.scriptPubKey.addresses.length !== 1) throw new Error(o.scriptPubKey.addresses.length + ' addresses')
var address = o.scriptPubKey.addresses[0]
//console.log('output of', o.value, 'to', address, 'found')
var client = db()
client.query({
text: 'SELECT COUNT(*) count FROM btc_deposit_address WHERE address = $1',
values: [address]
}, function(err, res) {
client.end()
if (err) return next(err)
if (res.rows[0].count === 0) {
//console.log('address', address, 'does not belong to us')
return next()
}
var satoshi = o.value * 1e8
client = db()
client.query({
text: 'SELECT btc_credit($1, $2, $3) tid',
values: [txid, address, satoshi]
}, function(err, res) {
client.end()
if (err) {
if (err.code === '23505') {
console.log('*** duplicate credit, probably from resuming')
return next()
}
return next(err)
}
console.log('credited transaction (internal id ' + res.rows[0].tid + ')')
next()
})
})
}, next)
}
}, next)
}, next)
}
}, function(err) {
if (err) return panic(err)
var client = db()
client.query({
text: 'INSERT INTO btc_block (hash, height) VALUES ($1, $2)',
values: [hash, oldHeight + 1]
}, function(err, res) {
if (err) return panic(err)
console.log('-------- ', (oldHeight + 1), ' completed -----------')
nextBlock()
})
})
}
function panic(err) {
console.error(err)
return setTimeout(process.exit, 1000)
}
nextBlock()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment