Skip to content

Commit

Permalink
Remove tests from sequencer/src/state.rs
Browse files Browse the repository at this point in the history
These tests are duplicated in `espresso-types`.
  • Loading branch information
tbro committed Oct 10, 2024
1 parent a877a04 commit 3d0f8ef
Showing 1 changed file with 0 additions and 225 deletions.
225 changes: 0 additions & 225 deletions sequencer/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,228 +305,3 @@ impl<T> SequencerStateUpdate for T where
+ ChainConfigPersistence
{
}

#[cfg(test)]
mod test {
use espresso_types::{
v0_3::IterableFeeInfo, validate_proposal, BlockSize, FeeAccount, FeeAccountProof,
FeeAmount, FeeError, FeeInfo, FeeMerkleProof, Leaf, ProposalValidationError,
};
use ethers::{abi::Address, types::U256};
use hotshot_types::{
traits::signature_key::BuilderSignatureKey,
vid::{vid_scheme, VidSchemeType},
};
use jf_merkle_tree::{ForgetableMerkleTreeScheme, MerkleTreeError};
use jf_vid::VidScheme;
use sequencer_utils::{ser::FromStringOrInteger, test_utils::setup_test};

use super::*;

#[test]
fn test_fee_proofs() {
setup_test();

let mut tree = ValidatedState::default().fee_merkle_tree;
let account1 = Address::random();
let account2 = Address::default();
tracing::info!(%account1, %account2);

let balance1 = U256::from(100);
tree.update(FeeAccount(account1), FeeAmount(balance1))
.unwrap();

// Membership proof.
let (proof1, balance) = FeeAccountProof::prove(&tree, account1).unwrap();
tracing::info!(?proof1, %balance);
assert_eq!(balance, balance1);
assert!(matches!(proof1.proof, FeeMerkleProof::Presence(_)));
assert_eq!(proof1.verify(&tree.commitment()).unwrap(), balance1);

// Non-membership proof.
let (proof2, balance) = FeeAccountProof::prove(&tree, account2).unwrap();
tracing::info!(?proof2, %balance);
assert_eq!(balance, 0.into());
assert!(matches!(proof2.proof, FeeMerkleProof::Absence(_)));
assert_eq!(proof2.verify(&tree.commitment()).unwrap(), 0.into());

// Test forget/remember. We cannot generate proofs in a completely sparse tree:
let mut tree = FeeMerkleTree::from_commitment(tree.commitment());
assert!(FeeAccountProof::prove(&tree, account1).is_none());
assert!(FeeAccountProof::prove(&tree, account2).is_none());
// After remembering the proofs, we can generate proofs again:
proof1.remember(&mut tree).unwrap();
proof2.remember(&mut tree).unwrap();
FeeAccountProof::prove(&tree, account1).unwrap();
FeeAccountProof::prove(&tree, account2).unwrap();
}

#[async_std::test]
async fn test_validation_max_block_size() {
setup_test();

const MAX_BLOCK_SIZE: usize = 10;
let payload = [0; 2 * MAX_BLOCK_SIZE];
let vid_common = vid_scheme(1).disperse(payload).unwrap().common;

let state = ValidatedState::default();
let instance = NodeState::mock().with_chain_config(ChainConfig {
max_block_size: (MAX_BLOCK_SIZE as u64).into(),
base_fee: 0.into(),
..Default::default()
});
let parent = Leaf::genesis(&instance.genesis_state, &instance).await;
let header = parent.block_header();

// Validation fails because the proposed block exceeds the maximum block size.
let err = validate_proposal(&state, instance.chain_config, &parent, header, &vid_common)
.unwrap_err();

tracing::info!(%err, "task failed successfully");
assert_eq!(
ProposalValidationError::MaxBlockSizeExceeded {
max_block_size: instance.chain_config.max_block_size,
block_size: BlockSize::from_integer(
VidSchemeType::get_payload_byte_len(&vid_common).into()
)
.unwrap()
},
err
);
}

#[async_std::test]
async fn test_validation_base_fee() {
setup_test();

let max_block_size = 10;
let payload = [0; 1];
let vid_common = vid_scheme(1).disperse(payload).unwrap().common;

let state = ValidatedState::default();
let instance = NodeState::mock().with_chain_config(ChainConfig {
base_fee: 1000.into(), // High base fee
max_block_size: max_block_size.into(),
..Default::default()
});
let parent = Leaf::genesis(&instance.genesis_state, &instance).await;
let header = parent.block_header();

// Validation fails because the genesis fee (0) is too low.
let err = validate_proposal(&state, instance.chain_config, &parent, header, &vid_common)
.unwrap_err();

tracing::info!(%err, "task failed successfully");
assert_eq!(
ProposalValidationError::InsufficientFee {
max_block_size: instance.chain_config.max_block_size,
base_fee: instance.chain_config.base_fee,
proposed_fee: header.fee_info().amount().unwrap()
},
err
);
}

#[test]
fn test_charge_fee() {
setup_test();

let src = FeeAccount::generated_from_seed_indexed([0; 32], 0).0;
let dst = FeeAccount::generated_from_seed_indexed([0; 32], 1).0;
let amt = FeeAmount::from(1);

let fee_info = FeeInfo::new(src, amt);

let new_state = || {
let mut state = ValidatedState::default();
state.prefund_account(src, amt);
state
};

tracing::info!("test successful fee");
let mut state = new_state();
state.charge_fee(fee_info, dst).unwrap();
assert_eq!(state.balance(src), Some(0.into()));
assert_eq!(state.balance(dst), Some(amt));

tracing::info!("test insufficient balance");
let err = state.charge_fee(fee_info, dst).unwrap_err();
assert_eq!(state.balance(src), Some(0.into()));
assert_eq!(state.balance(dst), Some(amt));
assert_eq!(
FeeError::InsufficientFunds {
balance: None,
amount: amt
},
err
);

tracing::info!("test src not in memory");
let mut state = new_state();
state.fee_merkle_tree.forget(src).expect_ok().unwrap();
assert_eq!(
FeeError::MerkleTreeError(MerkleTreeError::ForgottenLeaf),
state.charge_fee(fee_info, dst).unwrap_err()
);

tracing::info!("test dst not in memory");
let mut state = new_state();
state.prefund_account(dst, amt);
state.fee_merkle_tree.forget(dst).expect_ok().unwrap();
assert_eq!(
FeeError::MerkleTreeError(MerkleTreeError::ForgottenLeaf),
state.charge_fee(fee_info, dst).unwrap_err()
);
}

#[test]
fn test_fee_amount_serde_json_as_decimal() {
let amt = FeeAmount::from(123);
let serialized = serde_json::to_string(&amt).unwrap();

// The value is serialized as a decimal string.
assert_eq!(serialized, "\"123\"");

// Deserialization produces the original value
let deserialized: FeeAmount = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized, amt);
}

#[test]
fn test_fee_amount_from_units() {
for (unit, multiplier) in [
("wei", 1),
("gwei", 1_000_000_000),
("eth", 1_000_000_000_000_000_000),
] {
let amt: FeeAmount = serde_json::from_str(&format!("\"1 {unit}\"")).unwrap();
assert_eq!(amt, multiplier.into());
}
}

#[test]
fn test_fee_amount_serde_json_from_hex() {
// For backwards compatibility, fee amounts can also be deserialized from a 0x-prefixed hex
// string.
let amt: FeeAmount = serde_json::from_str("\"0x123\"").unwrap();
assert_eq!(amt, FeeAmount::from(0x123));
}

#[test]
fn test_fee_amount_serde_json_from_number() {
// For convenience, fee amounts can also be deserialized from a JSON number.
let amt: FeeAmount = serde_json::from_str("123").unwrap();
assert_eq!(amt, FeeAmount::from(123));
}

#[test]
fn test_fee_amount_serde_bincode_unchanged() {
// For non-human-readable formats, FeeAmount just serializes as the underlying U256.
let n = U256::from(123);
let amt = FeeAmount(n);
assert_eq!(
bincode::serialize(&n).unwrap(),
bincode::serialize(&amt).unwrap(),
);
}
}

0 comments on commit 3d0f8ef

Please sign in to comment.