@@ -3,24 +3,47 @@ mod blocks_pool;
3
3
use std:: time:: Duration ;
4
4
5
5
use crate :: chainhooks:: types:: {
6
- get_canonical_magic_bytes, get_canonical_pox_config, PoxConfig , StacksOpcodes ,
6
+ get_canonical_pox_config, get_ordinal_canonical_magic_bytes, get_stacks_canonical_magic_bytes,
7
+ PoxConfig , StacksOpcodes ,
7
8
} ;
8
9
use crate :: indexer:: IndexerConfig ;
9
10
use crate :: observer:: BitcoinConfig ;
10
11
use crate :: utils:: Context ;
11
- use bitcoincore_rpc:: bitcoin:: Block ;
12
+ use bitcoincore_rpc:: bitcoin;
13
+ use bitcoincore_rpc_json:: { GetRawTransactionResult , GetRawTransactionResultVout } ;
12
14
pub use blocks_pool:: BitcoinBlockPool ;
13
15
use chainhook_types:: bitcoin:: { OutPoint , TxIn , TxOut } ;
14
16
use chainhook_types:: {
15
17
BitcoinBlockData , BitcoinBlockMetadata , BitcoinTransactionData , BitcoinTransactionMetadata ,
16
- BlockCommitmentData , BlockIdentifier , KeyRegistrationData , LockSTXData , PobBlockCommitmentData ,
17
- PoxBlockCommitmentData , PoxReward , StacksBaseChainOperation , TransactionIdentifier ,
18
- TransferSTXData ,
18
+ BlockCommitmentData , BlockIdentifier , KeyRegistrationData , LockSTXData ,
19
+ OrdinalInscriptionRevealData , OrdinalOperation , PobBlockCommitmentData , PoxBlockCommitmentData ,
20
+ PoxReward , StacksBaseChainOperation , TransactionIdentifier , TransferSTXData ,
19
21
} ;
20
22
use clarity_repl:: clarity:: util:: hash:: { hex_bytes, to_hex} ;
21
23
use hiro_system_kit:: slog;
22
24
use rocket:: serde:: json:: Value as JsonValue ;
23
25
26
+ #[ derive( Clone , PartialEq , Debug , Deserialize , Serialize ) ]
27
+ #[ serde( rename_all = "camelCase" ) ]
28
+ pub struct Block {
29
+ pub hash : bitcoin:: BlockHash ,
30
+ pub confirmations : i32 ,
31
+ pub size : usize ,
32
+ pub strippedsize : Option < usize > ,
33
+ pub weight : usize ,
34
+ pub height : usize ,
35
+ pub version : i32 ,
36
+ pub merkleroot : bitcoin:: TxMerkleNode ,
37
+ pub tx : Vec < GetRawTransactionResult > ,
38
+ pub time : usize ,
39
+ pub mediantime : Option < usize > ,
40
+ pub nonce : u32 ,
41
+ pub bits : String ,
42
+ pub difficulty : f64 ,
43
+ pub n_tx : usize ,
44
+ pub previousblockhash : bitcoin:: BlockHash ,
45
+ }
46
+
24
47
#[ derive( Deserialize ) ]
25
48
pub struct NewBitcoinBlock {
26
49
pub burn_block_hash : String ,
@@ -51,13 +74,13 @@ pub async fn retrieve_full_block(
51
74
"jsonrpc" : "1.0" ,
52
75
"id" : "chainhook-cli" ,
53
76
"method" : "getblock" ,
54
- "params" : [ block_hash, 0 ]
77
+ "params" : [ block_hash, 2 ]
55
78
} ) ;
56
79
let http_client = HttpClient :: builder ( )
57
80
. timeout ( Duration :: from_secs ( 20 ) )
58
81
. build ( )
59
82
. expect ( "Unable to build http client" ) ;
60
- let response_hex = http_client
83
+ let block = http_client
61
84
. post ( & bitcoin_config. rpc_url )
62
85
. basic_auth ( & bitcoin_config. username , Some ( & bitcoin_config. password ) )
63
86
. header ( "Content-Type" , "application/json" )
@@ -69,15 +92,9 @@ pub async fn retrieve_full_block(
69
92
. json :: < bitcoincore_rpc:: jsonrpc:: Response > ( )
70
93
. await
71
94
. map_err ( |e| format ! ( "unable to parse response ({})" , e) ) ?
72
- . result :: < String > ( )
95
+ . result :: < Block > ( )
73
96
. map_err ( |e| format ! ( "unable to parse response ({})" , e) ) ?;
74
97
75
- let bytes = hex_bytes ( & response_hex)
76
- . map_err ( |e| format ! ( "unable to retrieve bytes from response ({})" , e) ) ?;
77
-
78
- let block = bitcoincore_rpc:: bitcoin:: consensus:: encode:: deserialize ( & bytes)
79
- . map_err ( |e| format ! ( "unable to deserialize bitcoin block ({})" , e) ) ?;
80
-
81
98
let block_height = partial_block. burn_block_height ;
82
99
Ok ( ( block_height, block) )
83
100
}
@@ -96,16 +113,26 @@ pub fn standardize_bitcoin_block(
96
113
for mut tx in block. txdata . into_iter ( ) {
97
114
let txid = tx. txid ( ) . to_string ( ) ;
98
115
let mut inputs = vec ! [ ] ;
99
- for input in tx. input . drain ( ..) {
116
+ for input in tx. vin . drain ( ..) {
117
+ if input. is_coinbase ( ) {
118
+ continue ;
119
+ }
100
120
inputs. push ( TxIn {
101
121
previous_output : OutPoint {
102
- txid : input. previous_output . txid . to_string ( ) ,
103
- vout : input. previous_output . vout ,
122
+ txid : input
123
+ . txid
124
+ . expect ( "not provided for coinbase txs" )
125
+ . to_string ( ) ,
126
+ vout : input. vout . expect ( "not provided for coinbase txs" ) ,
104
127
} ,
105
- script_sig : to_hex ( input. script_sig . as_bytes ( ) ) ,
106
- sequence : input. sequence . 0 ,
128
+ script_sig : format ! (
129
+ "0x{}" ,
130
+ to_hex( & input. script_sig. expect( "not provided for coinbase txs" ) . hex)
131
+ ) ,
132
+ sequence : input. sequence ,
107
133
witness : input
108
- . witness
134
+ . txinwitness
135
+ . unwrap_or ( vec ! [ ] )
109
136
. to_vec ( )
110
137
. iter ( )
111
138
. map ( |w| format ! ( "0x{}" , to_hex( w) ) )
@@ -125,11 +152,10 @@ pub fn standardize_bitcoin_block(
125
152
) {
126
153
stacks_operations. push ( op) ;
127
154
}
128
-
129
- for output in tx. output . drain ( ..) {
155
+ for output in tx. vout . drain ( ..) {
130
156
outputs. push ( TxOut {
131
- value : output. value ,
132
- script_pubkey : to_hex ( output. script_pubkey . as_bytes ( ) ) ,
157
+ value : output. value . to_sat ( ) ,
158
+ script_pubkey : format ! ( "0x{}" , to_hex( & output. script_pub_key . hex ) ) ,
133
159
} ) ;
134
160
}
135
161
@@ -150,21 +176,21 @@ pub fn standardize_bitcoin_block(
150
176
151
177
Ok ( BitcoinBlockData {
152
178
block_identifier : BlockIdentifier {
153
- hash : format ! ( "0x{}" , block. header . block_hash ( ) . to_string ( ) ) ,
179
+ hash : format ! ( "0x{}" , block. hash ) ,
154
180
index : block_height,
155
181
} ,
156
182
parent_block_identifier : BlockIdentifier {
157
- hash : format ! ( "0x{}" , block. header . prev_blockhash . to_string ( ) ) ,
183
+ hash : format ! ( "0x{}" , block. previousblockhash ) ,
158
184
index : block_height - 1 ,
159
185
} ,
160
- timestamp : block. header . time ,
186
+ timestamp : block. time as u32 ,
161
187
metadata : BitcoinBlockMetadata { } ,
162
188
transactions,
163
189
} )
164
190
}
165
191
166
192
fn try_parse_stacks_operation (
167
- outputs : & Vec < bitcoincore_rpc :: bitcoin :: TxOut > ,
193
+ outputs : & Vec < GetRawTransactionResultVout > ,
168
194
pox_config : & PoxConfig ,
169
195
expected_magic_bytes : & [ u8 ; 2 ] ,
170
196
block_height : u64 ,
@@ -174,12 +200,8 @@ fn try_parse_stacks_operation(
174
200
return None ;
175
201
}
176
202
177
- if !outputs[ 0 ] . script_pubkey . is_op_return ( ) {
178
- return None ;
179
- }
180
-
181
203
// Safely parsing the first 2 bytes (following OP_RETURN + PUSH_DATA)
182
- let op_return_output = outputs[ 0 ] . script_pubkey . as_bytes ( ) ;
204
+ let op_return_output = & outputs[ 0 ] . script_pub_key . hex ;
183
205
if op_return_output. len ( ) < 7 {
184
206
return None ;
185
207
}
@@ -229,8 +251,8 @@ fn try_parse_stacks_operation(
229
251
let mut rewards = vec ! [ ] ;
230
252
for output in outputs[ 1 ..pox_config. rewarded_addresses_per_block ] . into_iter ( ) {
231
253
rewards. push ( PoxReward {
232
- recipient : output. script_pubkey . to_string ( ) ,
233
- amount : output. value ,
254
+ recipient : format ! ( "0x{}" , to_hex ( & output. script_pub_key . hex ) ) ,
255
+ amount : output. value . to_sat ( ) ,
234
256
} ) ;
235
257
}
236
258
StacksBaseChainOperation :: PoxBlockCommitment ( PoxBlockCommitmentData {
@@ -246,7 +268,7 @@ fn try_parse_stacks_operation(
246
268
StacksBaseChainOperation :: PobBlockCommitment ( PobBlockCommitmentData {
247
269
signers : vec ! [ ] , // todo(lgalabru)
248
270
stacks_block_hash : res. stacks_block_hash . clone ( ) ,
249
- amount,
271
+ amount : amount . to_sat ( ) ,
250
272
} )
251
273
}
252
274
}
0 commit comments