@@ -30,15 +30,12 @@ var TransactionSchema = new Schema({
3030 index : true ,
3131 unique : true ,
3232 } ,
33- processed : {
34- type : Boolean ,
35- default : false ,
36- index : true ,
37- } ,
33+ /* TODO?
3834 orphaned: {
3935 type: Boolean,
4036 default: false,
4137 },
38+ */
4239 time : Number ,
4340} ) ;
4441
@@ -71,18 +68,18 @@ TransactionSchema.statics.fromIdWithInfo = function(txid, cb) {
7168 tx = new That ( ) ;
7269
7370 tx . txid = txid ;
74- tx . queryInfo ( function ( err , txInfo ) {
71+ tx . fillInfo ( function ( err , txInfo ) {
7572
7673 if ( ! txInfo )
77- return cb ( new Error ( 'TX not found1 ' ) ) ;
74+ return cb ( new Error ( 'TX not found ' ) ) ;
7875
7976 tx . save ( function ( err ) {
8077 return cb ( err , tx ) ;
8178 } ) ;
8279 } ) ;
8380 }
8481 else {
85- tx . queryInfo ( function ( err ) {
82+ tx . fillInfo ( function ( err ) {
8683 return cb ( err , tx ) ;
8784 } ) ;
8885 }
@@ -94,75 +91,79 @@ TransactionSchema.statics.createFromArray = function(txs, next) {
9491 var that = this ;
9592 if ( ! txs ) return next ( ) ;
9693 var mongo_txs = [ ] ;
97- async . forEach ( txs ,
98- function ( tx , cb ) {
99- var now = Math . round ( new Date ( ) . getTime ( ) / 1000 ) ;
100- that . create ( { txid : tx , time : now } , function ( err , new_tx ) {
101- if ( err ) {
102- if ( err . toString ( ) . match ( / E 1 1 0 0 0 / ) ) {
103- return cb ( ) ;
104- }
105- return cb ( err ) ;
106- }
107- mongo_txs . push ( new_tx ) ;
94+ var now = Math . round ( new Date ( ) . getTime ( ) / 1000 ) ;
95+
96+ async . forEachLimit ( txs , CONCURRENCY , function ( txid , cb ) {
97+
98+ that . explodeTransactionItems ( txid , function ( err ) {
99+
100+ that . create ( { txid : txid , time : now } , function ( err , new_tx ) {
101+
102+ //console.log("created:", err, new_tx);
103+
104+ if ( err && ! err . toString ( ) . match ( / E 1 1 0 0 0 / ) ) return cb ( err ) ;
105+
106+ if ( new_tx ) mongo_txs . push ( new_tx ) ;
108107 return cb ( ) ;
109108 } ) ;
110- } ,
111- function ( err ) {
112- return next ( err , mongo_txs ) ;
113- }
114- ) ;
109+ } )
110+ } ,
111+ function ( err ) {
112+ return next ( err , mongo_txs ) ;
113+ } ) ;
115114} ;
116115
117116
118117TransactionSchema . statics . explodeTransactionItems = function ( txid , cb ) {
119118
120- this . fromIdWithInfo ( txid , function ( err , t ) {
121- if ( err || ! t ) return cb ( err ) ;
119+ this . queryInfo ( txid , function ( err , info ) {
120+
121+ //console.log("INFO",info);
122+ if ( err || ! info ) return cb ( err ) ;
122123
123124 var index = 0 ;
124- t . info . vin . forEach ( function ( i ) {
125+ info . vin . forEach ( function ( i ) {
125126 i . n = index ++ ;
126127 } ) ;
127128
128- async . forEachLimit ( t . info . vin , CONCURRENCY , function ( i , next_in ) {
129+ async . forEachLimit ( info . vin , CONCURRENCY , function ( i , next_in ) {
129130 if ( i . addr && i . value ) {
130131
131132//console.log("Creating IN %s %d", i.addr, i.valueSat);
132133 TransactionItem . create ( {
133- txid : t . txid ,
134+ txid : txid ,
134135 value_sat : - 1 * i . valueSat ,
135136 addr : i . addr ,
136137 index : i . n ,
137- ts : t . info . time ,
138+ ts : info . time ,
138139 } , next_in ) ;
139140 }
140141 else {
141142 if ( ! i . coinbase ) {
142- console . log ( 'TX: %s,%d could not parse INPUT' , t . txid , i . n ) ;
143+ console . log ( 'TX: %s,%d could not parse INPUT' , txid , i . n ) ;
143144 }
144145 return next_in ( ) ;
145146 }
146147 } ,
147148 function ( err ) {
148149 if ( err ) console . log ( err ) ;
149- async . forEachLimit ( t . info . vout , CONCURRENCY , function ( o , next_out ) {
150+ async . forEachLimit ( info . vout , CONCURRENCY , function ( o , next_out ) {
150151
151152 /*
152153 * TODO Support multisigs
153154 */
154155 if ( o . value && o . scriptPubKey && o . scriptPubKey . addresses && o . scriptPubKey . addresses [ 0 ] ) {
155156//console.log("Creating OUT %s %d", o.scriptPubKey.addresses[0], o.valueSat);
156157 TransactionItem . create ( {
157- txid : t . txid ,
158+ txid : txid ,
158159 value_sat : o . valueSat ,
159160 addr : o . scriptPubKey . addresses [ 0 ] ,
160161 index : o . n ,
161- ts : t . info . time ,
162+ ts : info . time ,
162163 } , next_out ) ;
163164 }
164165 else {
165- console . log ( 'TX: %s,%d could not parse OUTPUT' , t . txid , o . n ) ;
166+ console . log ( 'TX: %s,%d could not parse OUTPUT' , txid , o . n ) ;
166167 return next_out ( ) ;
167168 }
168169 } ,
@@ -175,22 +176,21 @@ TransactionSchema.statics.explodeTransactionItems = function(txid, cb) {
175176
176177
177178
178- TransactionSchema . methods . fillInputValues = function ( tx , next ) {
179+ TransactionSchema . statics . getOutpoints = function ( tx , next ) {
179180
180181 if ( tx . isCoinBase ( ) ) return next ( ) ;
181182
182- if ( ! this . rpc ) this . rpc = new RpcClient ( config . bitcoind ) ;
183+ var rpc = new RpcClient ( config . bitcoind ) ;
183184 var network = ( config . network === 'testnet' ) ? networks . testnet : networks . livenet ;
184185
185- var that = this ;
186186 async . forEachLimit ( tx . ins , CONCURRENCY , function ( i , cb ) {
187187
188188 var outHash = i . getOutpointHash ( ) ;
189189 var outIndex = i . getOutpointIndex ( ) ;
190190 var outHashBase64 = outHash . reverse ( ) . toString ( 'hex' ) ;
191191
192192 var c = 0 ;
193- that . rpc . getRawTransaction ( outHashBase64 , function ( err , txdata ) {
193+ rpc . getRawTransaction ( outHashBase64 , function ( err , txdata ) {
194194 var txin = new Transaction ( ) ;
195195 if ( err || ! txdata . result ) return cb ( new Error ( 'Input TX ' + outHashBase64 + ' not found' ) ) ;
196196
@@ -229,42 +229,40 @@ TransactionSchema.methods.fillInputValues = function (tx, next) {
229229 ) ;
230230} ;
231231
232- TransactionSchema . methods . queryInfo = function ( next ) {
233232
234- var that = this ;
233+ TransactionSchema . statics . queryInfo = function ( txid , cb ) {
234+ var that = this ;
235235 var network = ( config . network === 'testnet' ) ? networks . testnet : networks . livenet ;
236- this . rpc = new RpcClient ( config . bitcoind ) ;
237-
236+ var rpc = new RpcClient ( config . bitcoind ) ;
238237
239- this . rpc . getRawTransaction ( this . txid , 1 , function ( err , txInfo ) {
240- if ( err ) return next ( err ) ;
238+ rpc . getRawTransaction ( txid , 1 , function ( err , txInfo ) {
239+ if ( err ) return cb ( err ) ;
241240
242- that . info = txInfo . result ;
241+ var info = txInfo . result ;
243242
244243 // Transaction parsing
245244 var b = new Buffer ( txInfo . result . hex , 'hex' ) ;
246245 var tx = new Transaction ( ) ;
247246 tx . parse ( b ) ;
248247
249- that . fillInputValues ( tx , function ( err ) {
248+ that . getOutpoints ( tx , function ( err ) {
249+ if ( err ) return cb ( err ) ;
250250
251251 // Copy TX relevant values to .info
252252
253253 var c = 0 ;
254-
255-
256254 var valueIn = bignum ( 0 ) ;
257255 var valueOut = bignum ( 0 ) ;
258256
259257 if ( tx . isCoinBase ( ) ) {
260- that . info . isCoinBase = true ;
258+ info . isCoinBase = true ;
261259 }
262260 else {
263261 tx . ins . forEach ( function ( i ) {
264262 if ( i . value ) {
265- that . info . vin [ c ] . value = util . formatValue ( i . value ) ;
263+ info . vin [ c ] . value = util . formatValue ( i . value ) ;
266264 var n = util . valueToBigInt ( i . value ) . toNumber ( ) ;
267- that . info . vin [ c ] . valueSat = n ;
265+ info . vin [ c ] . valueSat = n ;
268266 valueIn = valueIn . add ( n ) ;
269267
270268 var scriptSig = i . getScript ( ) ;
@@ -275,11 +273,11 @@ TransactionSchema.methods.queryInfo = function (next) {
275273 var pubKeyHash = util . sha256ripe160 ( pubKey ) ;
276274 var addr = new Address ( network . addressPubkey , pubKeyHash ) ;
277275 var addrStr = addr . toString ( ) ;
278- that . info . vin [ c ] . addr = addrStr ;
276+ info . vin [ c ] . addr = addrStr ;
279277 }
280278 else {
281279 if ( i . addrFromOutput )
282- that . info . vin [ c ] . addr = i . addrFromOutput ;
280+ info . vin [ c ] . addr = i . addrFromOutput ;
283281 }
284282 }
285283 else {
@@ -294,33 +292,42 @@ TransactionSchema.methods.queryInfo = function (next) {
294292 var n = util . valueToBigInt ( i . v ) . toNumber ( ) ;
295293 valueOut = valueOut . add ( n ) ;
296294
297- that . info . vout [ c ] . valueSat = n ;
295+ info . vout [ c ] . valueSat = n ;
298296 c ++ ;
299297 } ) ;
300298
301- that . info . valueOut = valueOut / util . COIN ;
299+ info . valueOut = valueOut / util . COIN ;
302300
303301 if ( ! tx . isCoinBase ( ) ) {
304- that . info . valueIn = valueIn / util . COIN ;
305- that . info . feeds = ( valueIn - valueOut ) / util . COIN ;
302+ info . valueIn = valueIn / util . COIN ;
303+ info . feeds = ( valueIn - valueOut ) / util . COIN ;
306304 }
307305 else {
308- var reward = BitcoreBlock . getBlockValue ( that . info . height ) / util . COIN ;
309- that . info . vin [ 0 ] . reward = reward ;
310- that . info . valueIn = reward ;
306+ var reward = BitcoreBlock . getBlockValue ( info . height ) / util . COIN ;
307+ info . vin [ 0 ] . reward = reward ;
308+ info . valueIn = reward ;
311309 }
312310
311+ info . size = b . length ;
313312
314- that . info . size = b . length ;
313+ return cb ( null , info ) ;
314+ } ) ;
315+ } ) ;
316+ } ;
315317
316318
317319
318- return next ( err , that . info ) ;
319- } ) ;
320+ TransactionSchema . methods . fillInfo = function ( next ) {
321+ var that = this ;
322+
323+ mongoose . model ( 'Transaction' , TransactionSchema ) . queryInfo ( that . txid , function ( err , info ) {
324+ if ( err ) return next ( err ) ;
325+
326+ that . info = info ;
327+ return next ( ) ;
320328 } ) ;
321329} ;
322330
323331
324332
325-
326333module . exports = mongoose . model ( 'Transaction' , TransactionSchema ) ;
0 commit comments