@@ -278,9 +278,14 @@ pub fn standardize_bitcoin_block(
278
278
ctx. try_log ( |logger| slog:: debug!( logger, "Standardizing Bitcoin transaction {txid}" ) ) ;
279
279
280
280
let mut stacks_operations = vec ! [ ] ;
281
- if let Some ( op) =
282
- try_parse_stacks_operation ( & tx. vout , & pox_config, & expected_magic_bytes, ctx)
283
- {
281
+ if let Some ( op) = try_parse_stacks_operation (
282
+ block_height,
283
+ & tx. vin ,
284
+ & tx. vout ,
285
+ & pox_config,
286
+ & expected_magic_bytes,
287
+ ctx,
288
+ ) {
284
289
stacks_operations. push ( op) ;
285
290
}
286
291
@@ -440,6 +445,8 @@ fn try_parse_ordinal_operation(
440
445
}
441
446
442
447
fn try_parse_stacks_operation (
448
+ block_height : u64 ,
449
+ inputs : & Vec < BitcoinTransactionInputFullBreakdown > ,
443
450
outputs : & Vec < BitcoinTransactionOutputFullBreakdown > ,
444
451
pox_config : & PoxConfig ,
445
452
expected_magic_bytes : & [ u8 ; 2 ] ,
@@ -492,34 +499,100 @@ fn try_parse_stacks_operation(
492
499
}
493
500
StacksOpcodes :: BlockCommit => {
494
501
let res = try_parse_block_commit_op ( & op_return_output[ 5 ..] ) ?;
502
+ let mut pox_sats_burnt = 0 ;
503
+ let mut pox_sats_transferred = vec ! [ ] ;
504
+
495
505
// We need to determine wether the transaction was a PoB or a Pox commitment
496
- // if pox_config.is_consensus_rewarding_participants_at_block_height(block_height) {
497
- if outputs. len ( ) < 1 + pox_config. rewarded_addresses_per_block {
498
- return None ;
499
- }
500
- let mut rewards = vec ! [ ] ;
501
- for output in outputs[ 1 ..pox_config. rewarded_addresses_per_block ] . into_iter ( ) {
502
- rewards. push ( PoxReward {
503
- recipient : format ! ( "0x{}" , hex:: encode( & output. script_pub_key. hex) ) ,
504
- amount : output. value . to_sat ( ) ,
505
- } ) ;
506
+ let mining_output_index = if pox_config
507
+ . is_consensus_rewarding_participants_at_block_height ( block_height)
508
+ {
509
+ // Output 0 is OP_RETURN
510
+ // Output 1 is rewarding Address 1
511
+ let pox_output_1 = outputs
512
+ . get ( 1 )
513
+ . ok_or ( format ! ( "expected pox output 1 not found" ) )
514
+ . ok ( ) ?;
515
+ let pox_script_1 = pox_output_1
516
+ . script_pub_key
517
+ . script ( )
518
+ . map_err ( |_e| format ! ( "expected pox output 1 corrupted" ) )
519
+ . ok ( ) ?;
520
+ let pox_address_1 = Address :: from_script ( & pox_script_1, bitcoin:: Network :: Bitcoin )
521
+ . map_err ( |_e| format ! ( "expected pox output 1 corrupted" ) )
522
+ . ok ( ) ?;
523
+ if pox_address_1. to_string ( ) . eq ( & pox_config. get_burn_address ( ) ) {
524
+ pox_sats_burnt += pox_output_1. value . to_sat ( ) ;
525
+ } else {
526
+ pox_sats_transferred. push ( PoxReward {
527
+ recipient_address : pox_address_1. to_string ( ) ,
528
+ amount : pox_output_1. value . to_sat ( ) ,
529
+ } ) ;
530
+ }
531
+ // Output 2 is rewarding Address 2
532
+ let pox_output_2 = outputs
533
+ . get ( 2 )
534
+ . ok_or ( format ! ( "expected pox output 2 not found" ) )
535
+ . ok ( ) ?;
536
+ let pox_script_2 = pox_output_2
537
+ . script_pub_key
538
+ . script ( )
539
+ . map_err ( |_e| format ! ( "expected pox output 2 corrupted" ) )
540
+ . ok ( ) ?;
541
+ let pox_address_2 = Address :: from_script ( & pox_script_2, bitcoin:: Network :: Bitcoin )
542
+ . map_err ( |_e| format ! ( "expected pox output 2 corrupted" ) )
543
+ . ok ( ) ?;
544
+ if pox_address_2. to_string ( ) . eq ( & pox_config. get_burn_address ( ) ) {
545
+ pox_sats_burnt += pox_output_2. value . to_sat ( ) ;
546
+ } else {
547
+ pox_sats_transferred. push ( PoxReward {
548
+ recipient_address : pox_address_2. to_string ( ) ,
549
+ amount : pox_output_2. value . to_sat ( ) ,
550
+ } ) ;
551
+ }
552
+ // Output 3 is used for miner chained commitments
553
+ 3
554
+ } else {
555
+ // Output 0 is OP_RETURN
556
+ // Output 1 should be a Burn Address
557
+ let burn_output = outputs
558
+ . get ( 1 )
559
+ . ok_or ( format ! ( "expected burn address not found" ) )
560
+ . ok ( ) ?;
561
+ // Todo: Ensure that we're looking at a burn address
562
+ pox_sats_burnt += burn_output. value . to_sat ( ) ;
563
+ // Output 2 is used for miner chained commitments
564
+ 2
565
+ } ;
566
+
567
+ let mut mining_sats_left = 0 ;
568
+ let mut mining_address_post_commit = None ;
569
+ if let Some ( mining_post_commit) = outputs. get ( mining_output_index) {
570
+ mining_sats_left = mining_post_commit. value . to_sat ( ) ;
571
+ mining_address_post_commit = match mining_post_commit. script_pub_key . script ( ) {
572
+ Ok ( script) => Address :: from_script ( & script, bitcoin:: Network :: Bitcoin )
573
+ . and_then ( |a| Ok ( a. to_string ( ) ) )
574
+ . ok ( ) ,
575
+ Err ( _) => None ,
576
+ } ;
506
577
}
507
- StacksBaseChainOperation :: BlockCommitted ( StacksBlockCommitmentData {
508
- signers : vec ! [ ] , // todo(lgalabru)
509
- stacks_block_hash : res. stacks_block_hash . clone ( ) ,
510
- rewards,
511
- } )
512
- // } else {
513
- // if outputs.len() < 2 {
514
- // return None;
515
578
// }
516
- // let amount = outputs[1].value;
517
- // StacksBaseChainOperation::BlockCommitted(StacksBlockCommitmentData {
518
- // signers: vec![], // todo(lgalabru)
519
- // stacks_block_hash: res.stacks_block_hash.clone(),
520
- // amount: amount.to_sat(),
521
- // })
522
579
// }
580
+
581
+ let pox_cycle_id = pox_config. get_pox_cycle_id ( block_height) ;
582
+ let pox_cycle_len = pox_config. get_pox_cycle_len ( ) ;
583
+ let pox_cycle_pos = pox_config. get_pos_in_pox_cycle ( block_height) ;
584
+
585
+ StacksBaseChainOperation :: BlockCommitted ( StacksBlockCommitmentData {
586
+ block_hash : res. stacks_block_hash ,
587
+ pox_cycle_id,
588
+ pox_cycle_len,
589
+ pox_cycle_pos,
590
+ pox_sats_burnt,
591
+ pox_sats_transferred,
592
+ mining_address_pre_commit : None ,
593
+ mining_address_post_commit,
594
+ mining_sats_left,
595
+ } )
523
596
}
524
597
} ;
525
598
0 commit comments