|
14 | 14 | // You should have received a copy of the GNU General Public License |
15 | 15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 |
|
17 | | -use std::collections::VecDeque; |
| 17 | +use std::collections::{HashMap, VecDeque}; |
18 | 18 | use std::convert::{TryFrom, TryInto}; |
19 | 19 | use std::time::Duration; |
20 | 20 |
|
21 | 21 | use burnchains::{ |
22 | 22 | db::{BurnchainBlockData, BurnchainDB}, |
23 | | - Burnchain, BurnchainBlockHeader, BurnchainHeaderHash, Error as BurnchainError, Txid, |
| 23 | + Address, Burnchain, BurnchainBlockHeader, BurnchainHeaderHash, Error as BurnchainError, Txid, |
24 | 24 | }; |
25 | 25 | use chainstate::burn::{ |
26 | 26 | db::sortdb::{PoxId, SortitionDB, SortitionId}, |
27 | 27 | operations::leader_block_commit::RewardSetInfo, |
| 28 | + operations::BlockstackOperationType, |
28 | 29 | BlockHeaderHash, BlockSnapshot, ConsensusHash, |
29 | 30 | }; |
30 | 31 | use chainstate::stacks::{ |
31 | 32 | boot::STACKS_BOOT_CODE_CONTRACT_ADDRESS, |
32 | | - db::{ClarityTx, StacksChainState, StacksHeaderInfo}, |
| 33 | + db::{accounts::MinerReward, ClarityTx, MinerRewardInfo, StacksChainState, StacksHeaderInfo}, |
33 | 34 | events::StacksTransactionReceipt, |
34 | 35 | Error as ChainstateError, StacksAddress, StacksBlock, StacksBlockHeader, StacksBlockId, |
35 | 36 | }; |
@@ -108,6 +109,19 @@ pub trait BlockEventDispatcher { |
108 | 109 | receipts: Vec<StacksTransactionReceipt>, |
109 | 110 | parent: &StacksBlockId, |
110 | 111 | winner_txid: Txid, |
| 112 | + matured_rewards: Vec<MinerReward>, |
| 113 | + matured_rewards_info: Option<MinerRewardInfo>, |
| 114 | + ); |
| 115 | + |
| 116 | + /// called whenever a burn block is about to be |
| 117 | + /// processed for sortition. note, in the event |
| 118 | + /// of PoX forks, this will be called _multiple_ |
| 119 | + /// times for the same burnchain header hash. |
| 120 | + fn announce_burn_block( |
| 121 | + &self, |
| 122 | + burn_block: &BurnchainHeaderHash, |
| 123 | + rewards: Vec<(StacksAddress, u64)>, |
| 124 | + burns: u64, |
111 | 125 | ); |
112 | 126 |
|
113 | 127 | fn dispatch_boot_receipts(&mut self, receipts: Vec<StacksTransactionReceipt>); |
@@ -426,6 +440,33 @@ pub fn get_reward_cycle_info<U: RewardSetProvider>( |
426 | 440 | } |
427 | 441 | } |
428 | 442 |
|
| 443 | +fn dispatcher_announce_burn_ops<T: BlockEventDispatcher>( |
| 444 | + dispatcher: &T, |
| 445 | + burn_header: &BurnchainBlockHeader, |
| 446 | + ops: &[BlockstackOperationType], |
| 447 | +) { |
| 448 | + let mut reward_recipients: HashMap<_, u64> = HashMap::new(); |
| 449 | + let mut burn_amt = 0; |
| 450 | + for op in ops.iter() { |
| 451 | + if let BlockstackOperationType::LeaderBlockCommit(commit) = op { |
| 452 | + let amt_per_address = commit.burn_fee / (commit.commit_outs.len() as u64); |
| 453 | + for addr in commit.commit_outs.iter() { |
| 454 | + if addr.is_burn() { |
| 455 | + burn_amt += amt_per_address; |
| 456 | + } else { |
| 457 | + if let Some(prior_amt) = reward_recipients.get_mut(addr) { |
| 458 | + *prior_amt += amt_per_address; |
| 459 | + } else { |
| 460 | + reward_recipients.insert(addr.clone(), amt_per_address); |
| 461 | + } |
| 462 | + } |
| 463 | + } |
| 464 | + } |
| 465 | + } |
| 466 | + let reward_recipients_vec = reward_recipients.into_iter().collect(); |
| 467 | + dispatcher.announce_burn_block(&burn_header.block_hash, reward_recipients_vec, burn_amt); |
| 468 | +} |
| 469 | + |
429 | 470 | impl<'a, T: BlockEventDispatcher, N: CoordinatorNotices, U: RewardSetProvider> |
430 | 471 | ChainsCoordinator<'a, T, N, U> |
431 | 472 | { |
@@ -475,6 +516,10 @@ impl<'a, T: BlockEventDispatcher, N: CoordinatorNotices, U: RewardSetProvider> |
475 | 516 | for unprocessed_block in sortitions_to_process.drain(..) { |
476 | 517 | let BurnchainBlockData { header, ops } = unprocessed_block; |
477 | 518 |
|
| 519 | + if let Some(dispatcher) = self.dispatcher { |
| 520 | + dispatcher_announce_burn_ops(dispatcher, &header, &ops); |
| 521 | + } |
| 522 | + |
478 | 523 | let sortition_tip_snapshot = SortitionDB::get_block_snapshot( |
479 | 524 | self.sortition_db.conn(), |
480 | 525 | &canonical_sortition_tip, |
@@ -621,6 +666,8 @@ impl<'a, T: BlockEventDispatcher, N: CoordinatorNotices, U: RewardSetProvider> |
621 | 666 | block_receipt.tx_receipts, |
622 | 667 | &parent, |
623 | 668 | winner_txid, |
| 669 | + block_receipt.matured_rewards, |
| 670 | + block_receipt.matured_rewards_info, |
624 | 671 | ); |
625 | 672 | } |
626 | 673 |
|
|
0 commit comments