Skip to content

Commit d00a976

Browse files
committed
add test for key contract send
1 parent ac21ff7 commit d00a976

File tree

7 files changed

+88
-6
lines changed

7 files changed

+88
-6
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ __pycache__/
3535

3636
# Rust bindings for smart contracts
3737
timeboost-contract/src/bindings
38+
39+
# env var files that may contains secrets
40+
.env*
41+
!.env*.example

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/src/KeyManager.sol

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,21 @@ contract KeyManager is Initializable, OwnableUpgradeable, UUPSUpgradeable {
196196
return nextCommitteeId - 1;
197197
}
198198

199+
/**
200+
* @notice This function is used to get the committee members.
201+
* @dev We need this because alloy binding for `.committees(id)` getter doesn't include dynamic array pointer
202+
* @dev Reverts if the id is greater than the length of the committees mapping.
203+
* @dev Reverts if the id is less than the head committee id.
204+
* @param id The id of the committee.
205+
* @return members The committee members.
206+
*/
207+
function getMembersById(uint64 id) external view virtual returns (CommitteeMember[] memory members) {
208+
if (id < _oldestStoredCommitteeId || committees[id].id != id) {
209+
revert CommitteeIdDoesNotExist(id);
210+
}
211+
return committees[id].members;
212+
}
213+
199214
/**
200215
* @notice This function is used to get the committee by id.
201216
* @dev Reverts if the id is greater than the length of the committees mapping.

timeboost-contract/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ rust-version.workspace = true
99
alloy = { workspace = true }
1010
anyhow = { workspace = true }
1111
dotenvy = "0.15"
12+
rand = { workspace = true }
1213
tracing = { workspace = true }
1314
tokio = { workspace = true }
1415

timeboost-contract/src/deployer.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ pub async fn deploy_key_manager_contract(
4545

4646
#[cfg(test)]
4747
mod tests {
48-
use alloy::providers::WalletProvider;
48+
use alloy::{providers::WalletProvider, sol_types::SolValue};
49+
use rand::prelude::*;
4950

50-
use crate::KeyManager;
51+
use crate::{CommitteeMemberSol, KeyManager};
5152

5253
#[tokio::test]
5354
async fn test_key_manager_deployment() {
@@ -57,5 +58,42 @@ mod tests {
5758

5859
// try read from the contract storage
5960
assert_eq!(contract.manager().call().await.unwrap(), manager);
61+
62+
// try write to the contract storage
63+
let rng = &mut rand::rng();
64+
let members = (0..5)
65+
.map(|_| CommitteeMemberSol::random())
66+
.collect::<Vec<_>>();
67+
let timestamp = rng.random::<u64>();
68+
69+
let _tx_receipt = contract
70+
.setNextCommittee(timestamp, members.clone())
71+
.send()
72+
.await
73+
.unwrap()
74+
.get_receipt()
75+
.await
76+
.unwrap();
77+
78+
// make sure next committee is correctly registered
79+
assert_eq!(contract.nextCommitteeId().call().await.unwrap(), 1);
80+
assert_eq!(
81+
contract
82+
.committees(0)
83+
.call()
84+
.await
85+
.unwrap()
86+
.effectiveTimestamp,
87+
timestamp
88+
);
89+
assert_eq!(
90+
contract
91+
.getMembersById(0)
92+
.call()
93+
.await
94+
.unwrap()
95+
.abi_encode_sequence(),
96+
members.abi_encode_sequence()
97+
);
6098
}
6199
}

timeboost-contract/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ use anyhow::Result;
1111

1212
// Include the generated contract bindings
1313
// The build script auto-detects contracts and generates bindings in src/bindings/
14-
pub mod bindings;
14+
mod bindings;
1515
pub mod deployer;
1616
pub mod provider;
17+
mod sol_types;
1718

18-
// We manually re-export the type here carefully due to alloy's lack of shared type:
19-
// tracking issue: https://github.com/foundry-rs/foundry/issues/10153
20-
pub use bindings::{erc1967proxy::ERC1967Proxy, keymanager::KeyManager};
2119
use provider::{HttpProviderWithWallet, TestProviderWithWallet, build_provider};
20+
pub use sol_types::*;
2221

2322
/// Connect to a real blockchain, deploy the KeyManager contract, set the
2423
/// `TIMEBOOST_KEY_MANAGER_MNEMONIC` as the manager.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Solidity types for contract interaction
2+
3+
use alloy::primitives::Bytes;
4+
use rand::prelude::*;
5+
6+
// We manually re-export the type here carefully due to alloy's lack of shared type:
7+
// tracking issue: https://github.com/foundry-rs/foundry/issues/10153
8+
pub use crate::bindings::{
9+
erc1967proxy::ERC1967Proxy,
10+
keymanager::KeyManager,
11+
keymanager::KeyManager::{Committee as CommitteeSol, CommitteeMember as CommitteeMemberSol},
12+
};
13+
14+
impl CommitteeMemberSol {
15+
pub fn random() -> Self {
16+
let mut rng = rand::rng();
17+
CommitteeMemberSol {
18+
sigKey: Bytes::from(rng.random::<[u8; 32]>()),
19+
dhKey: Bytes::from(rng.random::<[u8; 32]>()),
20+
dkgKey: Bytes::from(rng.random::<[u8; 32]>()),
21+
networkAddress: format!("127.0.0.1:{}", rng.random::<u16>()),
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)