Skip to content

Commit

Permalink
feat: add various new nakamoto block fields to /new_block ingestion…
Browse files Browse the repository at this point in the history
… and `StacksPayload`
  • Loading branch information
zone117x committed Oct 22, 2024
1 parent 6c1dfa9 commit 6627606
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::scan::stacks::{Record, RecordKind};
use crate::service::tests::helpers::mock_bitcoin_rpc::TipData;
use chainhook_sdk::indexer::bitcoin::NewBitcoinBlock;
use chainhook_sdk::indexer::stacks::{NewBlock, NewEvent, NewTransaction};
use chainhook_sdk::indexer::stacks::{NewBlock, NewEvent, NewTransaction, RewardSet, RewardSetSigner};
use chainhook_sdk::types::{
FTBurnEventData, FTMintEventData, FTTransferEventData, NFTBurnEventData, NFTMintEventData,
NFTTransferEventData, STXBurnEventData, STXLockEventData, STXMintEventData,
Expand Down Expand Up @@ -260,6 +260,26 @@ pub fn create_stacks_new_block(
transactions: (0..4).map(create_stacks_new_transaction).collect(),
events,
matured_miner_rewards: vec![],
block_time: Some(12345),
signer_bitvec: Some("000800000001ff".to_owned()),
signer_signature: Some(vec!["1234".to_owned(), "2345".to_owned()]),
cycle_number: Some(1),
reward_set: Some(RewardSet {
pox_ustx_threshold: "50000".to_owned(),
rewarded_addresses: vec![],
signers: Some(vec![
RewardSetSigner {
signing_key: "0123".to_owned(),
weight: 123,
stacked_amt: "555555".to_owned(),
},
RewardSetSigner {
signing_key: "2345".to_owned(),
weight: 234,
stacked_amt: "6677777".to_owned(),
},
]),
}),
}
}

Expand Down
53 changes: 53 additions & 0 deletions components/chainhook-sdk/src/indexer/stacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,36 @@ pub struct NewBlock {
pub transactions: Vec<NewTransaction>,
pub events: Vec<NewEvent>,
pub matured_miner_rewards: Vec<MaturedMinerReward>,

#[serde(skip_serializing_if = "Option::is_none")]
pub block_time: Option<u64>,

#[serde(skip_serializing_if = "Option::is_none")]
pub signer_bitvec: Option<String>,

#[serde(skip_serializing_if = "Option::is_none")]
pub signer_signature: Option<Vec<String>>,

#[serde(skip_serializing_if = "Option::is_none")]
pub cycle_number: Option<u64>,

#[serde(skip_serializing_if = "Option::is_none")]
pub reward_set: Option<RewardSet>,
}

#[derive(Deserialize, Serialize)]
pub struct RewardSet {
pub pox_ustx_threshold: String,
pub rewarded_addresses: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signers: Option<Vec<RewardSetSigner>>,
}

#[derive(Deserialize, Serialize)]
pub struct RewardSetSigner {
pub signing_key: String,
pub weight: u32,
pub stacked_amt: String,
}

#[derive(Deserialize, Serialize, Default, Clone)]
Expand Down Expand Up @@ -432,6 +462,29 @@ pub fn standardize_stacks_block(
pox_cycle_length: pox_cycle_length.try_into().unwrap(),
confirm_microblock_identifier,
stacks_block_hash: block.block_hash.clone(),

block_time: block.block_time,
// TODO: decode `signer_bitvec` into an easy to use bit string representation (e.g. "01010101")
signer_bitvec: block.signer_bitvec.clone(),
signer_signature: block.signer_signature.clone(),

cycle_number: block.cycle_number,
reward_set: block.reward_set.as_ref().and_then(|r| {
Some(StacksBlockMetadataRewardSet {
pox_ustx_threshold: r.pox_ustx_threshold.clone(),
rewarded_addresses: r.rewarded_addresses.clone(),
signers: r.signers.as_ref().map(|signers| {
signers
.into_iter()
.map(|signer| StacksBlockMetadataRewardSetSigner {
signing_key: signer.signing_key.clone(),
weight: signer.weight,
stacked_amt: signer.stacked_amt.clone(),
})
.collect()
}),
})
}),
},
transactions,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::BlockEvent;
use chainhook_types::{
BlockIdentifier, StacksBlockData, StacksBlockMetadata, StacksTransactionData,
BlockIdentifier, StacksBlockData, StacksBlockMetadata, StacksBlockMetadataRewardSet, StacksBlockMetadataRewardSetSigner, StacksTransactionData
};

pub fn generate_test_stacks_block(
Expand Down Expand Up @@ -72,6 +72,26 @@ pub fn generate_test_stacks_block(
pox_cycle_length: 100,
confirm_microblock_identifier,
stacks_block_hash: String::new(),
block_time: Some(12345),
signer_bitvec: Some("1010101010101".to_owned()),
signer_signature: Some(vec!["1234".to_owned(), "2345".to_owned()]),
cycle_number: Some(1),
reward_set: Some(StacksBlockMetadataRewardSet {
pox_ustx_threshold: "50000".to_owned(),
rewarded_addresses: vec![],
signers: Some(vec![
StacksBlockMetadataRewardSetSigner {
signing_key: "0123".to_owned(),
weight: 123,
stacked_amt: "555555".to_owned(),
},
StacksBlockMetadataRewardSetSigner {
signing_key: "2345".to_owned(),
weight: 234,
stacked_amt: "6677777".to_owned(),
},
]),
}),
},
})
}
Expand Down
17 changes: 17 additions & 0 deletions components/chainhook-types-js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,23 @@ export interface StacksBlockMetadata {
* @memberof StacksBlockMetadata
*/
pox_cycle_length: number;

block_time?: number | null;
signer_bitvec?: string | null;
signer_signature?: string[] | null;
cycle_number?: number | null;
reward_set?: {
pox_ustx_threshold: string;
rewarded_addresses: string[];
signers?: {
signing_key: string;
weight: number;
stacked_amt: string;
}[] | null;
start_cycle_state: {
missed_reward_slots: [];
};
} | null;
}

/**
Expand Down
23 changes: 23 additions & 0 deletions components/chainhook-types-rs/src/rosetta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,29 @@ pub struct StacksBlockMetadata {
pub pox_cycle_length: u32,
pub confirm_microblock_identifier: Option<BlockIdentifier>,
pub stacks_block_hash: String,

// Fields included in Nakamoto block headers
pub block_time: Option<u64>,
pub signer_bitvec: Option<String>,
pub signer_signature: Option<Vec<String>>,

// Available starting in epoch3, only included in blocks where the pox cycle rewards are first calculated
pub cycle_number: Option<u64>,
pub reward_set: Option<StacksBlockMetadataRewardSet>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StacksBlockMetadataRewardSet {
pub pox_ustx_threshold: String,
pub rewarded_addresses: Vec<String>,
pub signers: Option<Vec<StacksBlockMetadataRewardSetSigner>>,
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct StacksBlockMetadataRewardSetSigner {
pub signing_key: String,
pub weight: u32,
pub stacked_amt: String,
}

/// BitcoinBlock contain an array of Transactions that occurred at a particular
Expand Down
23 changes: 23 additions & 0 deletions components/client/typescript/src/schemas/stacks/payload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,29 @@ export const StacksEventMetadataSchema = Type.Object({
pox_cycle_length: Type.Integer(),
pox_cycle_position: Type.Integer(),
stacks_block_hash: Type.String(),

// Fields included in Nakamoto block headers
block_time: Nullable(Type.Integer()),
signer_bitvec: Nullable(Type.String()),
signer_signature: Nullable(Type.Array(Type.String())),

// Available starting in epoch3, only included in blocks where the pox cycle rewards are first calculated
cycle_number: Nullable(Type.Integer()),
reward_set: Nullable(
Type.Object({
pox_ustx_threshold: Type.String(),
rewarded_addresses: Type.Array(Type.String()),
signers: Nullable(
Type.Array(
Type.Object({
signing_key: Type.String(),
weight: Type.Integer(),
stacked_amt: Type.String(),
})
)
),
})
),
});
export type StacksEventMetadata = Static<typeof StacksEventMetadataSchema>;

Expand Down

0 comments on commit 6627606

Please sign in to comment.