Skip to content

Commit

Permalink
Merge pull request #240 from chainbound/naman/test-data
Browse files Browse the repository at this point in the history
chore(sidecar): update constraint api
  • Loading branch information
merklefruit authored Sep 26, 2024
2 parents 5cbf944 + 166f764 commit 107f098
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 23 deletions.
18 changes: 9 additions & 9 deletions bolt-sidecar/src/builder/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl BlockTemplate {
/// Returns the cloned list of transactions from the constraints.
#[inline]
pub fn transactions(&self) -> Vec<FullTransaction> {
self.signed_constraints_list.iter().flat_map(|sc| sc.message.constraints.clone()).collect()
self.signed_constraints_list.iter().flat_map(|sc| sc.message.transactions.clone()).collect()
}

/// Converts the list of signed constraints into a list of signed transactions. Use this when
Expand All @@ -52,7 +52,7 @@ impl BlockTemplate {
self.signed_constraints_list
.iter()
.flat_map(|sc| {
sc.message.constraints.iter().map(|c| c.clone().into_inner().into_transaction())
sc.message.transactions.iter().map(|c| c.clone().into_inner().into_transaction())
})
.collect()
}
Expand All @@ -64,7 +64,7 @@ impl BlockTemplate {
let (commitments, proofs, blobs) =
self.signed_constraints_list
.iter()
.flat_map(|sc| sc.message.constraints.iter())
.flat_map(|sc| sc.message.transactions.iter())
.filter_map(|c| c.blob_sidecar())
.fold(
(Vec::new(), Vec::new(), Vec::new()),
Expand All @@ -90,22 +90,22 @@ impl BlockTemplate {
/// Returns the length of the transactions in the block template.
#[inline]
pub fn transactions_len(&self) -> usize {
self.signed_constraints_list.iter().fold(0, |acc, sc| acc + sc.message.constraints.len())
self.signed_constraints_list.iter().fold(0, |acc, sc| acc + sc.message.transactions.len())
}

/// Returns the committed gas in the block template.
#[inline]
pub fn committed_gas(&self) -> u64 {
self.signed_constraints_list.iter().fold(0, |acc, sc| {
acc + sc.message.constraints.iter().fold(0, |acc, c| acc + c.gas_limit())
acc + sc.message.transactions.iter().fold(0, |acc, c| acc + c.gas_limit())
})
}

/// Returns the blob count of the block template.
#[inline]
pub fn blob_count(&self) -> usize {
self.signed_constraints_list.iter().fold(0, |mut acc, sc| {
acc += sc.message.constraints.iter().fold(0, |acc, c| {
acc += sc.message.transactions.iter().fold(0, |acc, c| {
acc + c.as_eip4844().map(|tx| tx.blob_versioned_hashes.len()).unwrap_or(0)
});

Expand All @@ -115,7 +115,7 @@ impl BlockTemplate {

/// Adds a list of constraints to the block template and updates the state diff.
pub fn add_constraints(&mut self, constraints: SignedConstraints) {
for constraint in constraints.message.constraints.iter() {
for constraint in constraints.message.transactions.iter() {
let max_cost = max_transaction_cost(constraint);
self.state_diff
.diffs
Expand All @@ -134,7 +134,7 @@ impl BlockTemplate {
fn remove_constraints_at_index(&mut self, index: usize) {
let constraints = self.signed_constraints_list.remove(index);

for constraint in constraints.message.constraints.iter() {
for constraint in constraints.message.transactions.iter() {
self.state_diff
.diffs
.entry(*constraint.sender().expect("recovered sender"))
Expand All @@ -155,7 +155,7 @@ impl BlockTemplate {
.signed_constraints_list
.iter()
.enumerate()
.map(|(idx, c)| (idx, &c.message.constraints))
.map(|(idx, c)| (idx, &c.message.transactions))
.filter(|(_idx, c)| c.iter().any(|c| c.sender().expect("recovered sender") == &address))
.map(|(idx, c)| {
(
Expand Down
2 changes: 1 addition & 1 deletion bolt-sidecar/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl<C: StateFetcher, BLS: SignerBLS, ECDSA: SignerECDSA> SidecarDriver<C, BLS,
};

// Track the number of transactions preconfirmed considering their type
signed_constraints.message.constraints.iter().for_each(|full_tx| {
signed_constraints.message.transactions.iter().for_each(|full_tx| {
ApiMetrics::increment_transactions_preconfirmed(full_tx.tx_type());
});
self.execution.add_constraint(slot, signed_constraints);
Expand Down
20 changes: 10 additions & 10 deletions bolt-sidecar/src/primitives/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl SignableECDSA for ConstraintsMessage {
data.extend_from_slice(&self.slot.to_le_bytes());

let mut constraint_bytes = Vec::new();
for constraint in &self.constraints {
for constraint in &self.transactions {
constraint_bytes.extend_from_slice(&constraint.envelope_encoded().0);
}
data.extend_from_slice(&constraint_bytes);
Expand Down Expand Up @@ -60,15 +60,15 @@ pub struct ConstraintsMessage {
pub top: bool,
/// The constraints that need to be signed.
#[serde(deserialize_with = "deserialize_txs", serialize_with = "serialize_txs")]
pub constraints: Vec<FullTransaction>,
pub transactions: Vec<FullTransaction>,
}

impl ConstraintsMessage {
/// Builds a constraints message from an inclusion request and metadata
pub fn build(pubkey: BlsPublicKey, request: InclusionRequest) -> Self {
let constraints = request.txs;
let transactions = request.txs;

Self { pubkey, slot: request.slot, top: false, constraints }
Self { pubkey, slot: request.slot, top: false, transactions }
}
}

Expand All @@ -79,8 +79,8 @@ impl SignableBLS for ConstraintsMessage {
hasher.update(self.slot.to_le_bytes());
hasher.update((self.top as u8).to_le_bytes());

for constraint in &self.constraints {
hasher.update(constraint.hash());
for tx in &self.transactions {
hasher.update(tx.hash());
}

hasher.finalize().into()
Expand Down Expand Up @@ -114,10 +114,10 @@ mod tests {
let pubkey = BlsPublicKey::default();
let slot = 0;
let top = false;
let constraints = random_constraints(1); // Generate 'n' random constraints
let transactions = random_constraints(1); // Generate 'n' random constraints

// Create a random `ConstraintsMessage`
let message = ConstraintsMessage { pubkey, slot, top, constraints };
let message = ConstraintsMessage { pubkey, slot, top, transactions };

// Compute tree hash root
let digest = SignableBLS::digest(&message);
Expand All @@ -134,10 +134,10 @@ mod tests {
let pubkey = BlsPublicKey::default();
let slot = random_u64(&mut rng);
let top = false;
let constraints = random_constraints(2); // Generate 'n' random constraints
let transactions = random_constraints(2); // Generate 'n' random constraints

// Create a random `ConstraintsMessage`
let message = ConstraintsMessage { pubkey, slot, top, constraints };
let message = ConstraintsMessage { pubkey, slot, top, transactions };

// Serialize the `ConstraintsMessage` to JSON
let json = serde_json::to_string(&message).unwrap();
Expand Down
27 changes: 26 additions & 1 deletion bolt-sidecar/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use std::{
sync::{atomic::AtomicU64, Arc},
};

use alloy::primitives::{Address, U256};
use alloy::{
primitives::{Address, U256},
signers::k256::sha2::{Digest, Sha256},
};
use ethereum_consensus::{
crypto::KzgCommitment,
deneb::{
Expand Down Expand Up @@ -36,6 +39,8 @@ pub mod constraint;
pub use constraint::{BatchedSignedConstraints, ConstraintsMessage, SignedConstraints};
use tracing::{error, info};

use crate::crypto::SignableBLS;

/// An alias for a Beacon Chain slot number
pub type Slot = u64;

Expand Down Expand Up @@ -430,6 +435,16 @@ pub struct DelegationMessage {
pub delegatee_pubkey: BlsPublicKey,
}

impl SignableBLS for DelegationMessage {
fn digest(&self) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(&self.validator_pubkey.to_vec());
hasher.update(&self.delegatee_pubkey.to_vec());

hasher.finalize().into()
}
}

#[derive(Debug, Clone, Serialize)]
pub struct SignedRevocation {
pub message: RevocationMessage,
Expand All @@ -441,3 +456,13 @@ pub struct RevocationMessage {
pub validator_pubkey: BlsPublicKey,
pub delegatee_pubkey: BlsPublicKey,
}

impl SignableBLS for RevocationMessage {
fn digest(&self) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(&self.validator_pubkey.to_vec());
hasher.update(&self.delegatee_pubkey.to_vec());

hasher.finalize().into()
}
}
109 changes: 107 additions & 2 deletions bolt-sidecar/src/test_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ use alloy::{
};
use alloy_node_bindings::{Anvil, AnvilInstance};
use blst::min_pk::SecretKey;
use ethereum_consensus::crypto::{PublicKey, Signature};
use rand::Rng;
use reth_primitives::PooledTransactionsElement;
use secp256k1::Message;
use tracing::warn;

use crate::{
crypto::{ecdsa::SignableECDSA, SignableBLS},
primitives::{CommitmentRequest, FullTransaction, InclusionRequest},
crypto::{bls::Signer as BlsSigner, ecdsa::SignableECDSA, SignableBLS, SignerBLS},
primitives::{
CommitmentRequest, ConstraintsMessage, DelegationMessage, FullTransaction,
InclusionRequest, RevocationMessage, SignedConstraints, SignedDelegation, SignedRevocation,
},
Config,
};

Expand Down Expand Up @@ -170,3 +175,103 @@ pub(crate) async fn create_signed_commitment_request(

Ok(CommitmentRequest::Inclusion(request))
}

fn random_constraints(count: usize) -> Vec<FullTransaction> {
// Random inclusion request
let json_req = r#"{
"slot": 10,
"txs": [
"0x02f86c870c72dd9d5e883e4d0183408f2382520894d2e2adf7177b7a8afddbc12d1634cf23ea1a71020180c001a08556dcfea479b34675db3fe08e29486fe719c2b22f6b0c1741ecbbdce4575cc6a01cd48009ccafd6b9f1290bbe2ceea268f94101d1d322c787018423ebcbc87ab4",
"0x02f9017b8501a2140cff8303dec685012a05f2008512a05f2000830249f094843669e5220036eddbaca89d8c8b5b82268a0fc580b901040cc7326300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000022006292538e66f0000000000000000000000005ba38f2c245618e39f6fa067bf1dec304e73ff3c00000000000000000000000092f0ee29e6e1bf0f7c668317ada78f5774a6cb7f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000003fac6482aee49bf58515be2d3fb58378a8497cc9000000000000000000000000c6cc140787b02ae479a10e41169607000c0d44f6c080a00cf74c45dbe9ee1fb923118ec5ce9db8f88cd651196ed3f9d4f8f2a65827e611a04a6bc1d49a7e18b7c92e8f3614cae116b1832ceb311c81d54b2c87de1545f68f",
"0x02f8708501a2140cff82012f800782520894b6c402298fcb88039bbfde70f5ace791f18cfac88707131d70870dc880c080a03aab1b17ecf28f85de43c7733611759b87d25ba885babacb6b4c625d715415eea03fb52cb7744ccb885906e42f6b9cf82e74b47a4b4b4072af2aa52a8dc472236e"
]
}"#;

let req: InclusionRequest = serde_json::from_str(json_req).unwrap();

req.txs.iter().cloned().take(count).collect()
}

#[tokio::test]
async fn generate_test_data() {
let sk = test_bls_secret_key();
let pk = sk.sk_to_pk();
let signer = BlsSigner::new(sk);

println!("Validator Public Key: {}", hex::encode(pk.to_bytes()));

// Generate a delegatee's BLS secret key and public key
let delegatee_ikm: [u8; 32] = rand::thread_rng().gen();
let delegatee_sk =
SecretKey::key_gen(&delegatee_ikm, &[]).expect("Failed to generate delegatee secret key");
let delegatee_pk = delegatee_sk.sk_to_pk();

// Prepare a Delegation message
let delegation_msg = DelegationMessage {
validator_pubkey: PublicKey::try_from(pk.to_bytes().as_slice())
.expect("Failed to convert validator public key"),
delegatee_pubkey: PublicKey::try_from(delegatee_pk.to_bytes().as_slice())
.expect("Failed to convert delegatee public key"),
};

let digest = SignableBLS::digest(&delegation_msg);

// Sign the Delegation message
let delegation_signature = SignerBLS::sign(&signer, &digest).await.unwrap();

// Create SignedDelegation
let signed_delegation = SignedDelegation {
message: delegation_msg,
signature: Signature::try_from(delegation_signature.as_ref())
.expect("Failed to convert delegation signature"),
};

// Output SignedDelegation
println!("{}", serde_json::to_string_pretty(&signed_delegation).unwrap());

// Prepare a revocation message
let revocation_msg = RevocationMessage {
validator_pubkey: PublicKey::try_from(pk.to_bytes().as_slice())
.expect("Failed to convert validator public key"),
delegatee_pubkey: PublicKey::try_from(delegatee_pk.to_bytes().as_slice())
.expect("Failed to convert delegatee public key"),
};

let digest = SignableBLS::digest(&revocation_msg);

// Sign the Revocation message
let revocation_signature = SignerBLS::sign(&signer, &digest).await.unwrap();

// Create SignedRevocation
let signed_revocation = SignedRevocation {
message: revocation_msg,
signature: Signature::try_from(revocation_signature.as_ref())
.expect("Failed to convert revocation signature"),
};

// Output SignedRevocation
println!("{}", serde_json::to_string_pretty(&signed_revocation).unwrap());

let transactions = random_constraints(1);

// Prepare a ConstraintsMessage
let constraints_msg = ConstraintsMessage {
pubkey: PublicKey::try_from(pk.to_bytes().as_slice())
.expect("Failed to convert validator public key"),
slot: 32,
top: true,
transactions,
};

let digest = SignableBLS::digest(&constraints_msg);

// Sign the ConstraintsMessage
let constraints_signature = SignerBLS::sign(&signer, &digest).await.unwrap();

// Create SignedConstraints
let signed_constraints =
SignedConstraints { message: constraints_msg, signature: constraints_signature };

// Output SignedConstraints
println!("{}", serde_json::to_string_pretty(&signed_constraints).unwrap());
}

0 comments on commit 107f098

Please sign in to comment.