tempo_bench/cmd/max_tps/
mpp.rs1use super::*;
2use alloy::{
3 primitives::keccak256,
4 sol,
5 sol_types::{SolCall, SolValue},
6};
7use tempo_alloy::{primitives::transaction::Call, rpc::TempoTransactionRequest};
8
9sol! {
10 #[sol(rpc)]
11 #[allow(clippy::too_many_arguments)]
12 interface ITempoStreamChannel {
13 function open(
14 address payee,
15 address token,
16 uint128 deposit,
17 bytes32 salt,
18 address authorizedSigner
19 ) external returns (bytes32 channelId);
20
21 function close(
22 bytes32 channelId,
23 uint128 cumulativeAmount,
24 bytes calldata signature
25 ) external;
26 }
27}
28
29pub(super) fn compute_channel_id(
33 payer: Address,
34 payee: Address,
35 token: Address,
36 salt: B256,
37 authorized_signer: Address,
38 channel_address: Address,
39 chain_id: u64,
40) -> B256 {
41 keccak256(
42 (
43 payer,
44 payee,
45 token,
46 salt,
47 authorized_signer,
48 channel_address,
49 U256::from(chain_id),
50 )
51 .abi_encode(),
52 )
53}
54
55pub(super) fn build_open_and_close(
59 channel_address: Address,
60 payer: Address,
61 token: Address,
62 salt: B256,
63 channel_id: B256,
64) -> TempoTransactionRequest {
65 let open_call = Call {
66 to: channel_address.into(),
67 input: ITempoStreamChannel::openCall {
68 payee: payer,
69 token,
70 deposit: 1,
71 salt,
72 authorizedSigner: Address::ZERO,
73 }
74 .abi_encode()
75 .into(),
76 value: U256::ZERO,
77 };
78
79 let close_call = Call {
80 to: channel_address.into(),
81 input: ITempoStreamChannel::closeCall {
82 channelId: channel_id,
83 cumulativeAmount: 0,
84 signature: Default::default(),
85 }
86 .abi_encode()
87 .into(),
88 value: U256::ZERO,
89 };
90
91 TempoTransactionRequest {
92 calls: vec![open_call, close_call],
93 ..Default::default()
94 }
95}
96
97pub(super) async fn setup(
99 signer_providers: &[(Secp256k1Signer, DynProvider<TempoNetwork>)],
100 channel_address: Address,
101 fee_token: Address,
102 max_concurrent_requests: usize,
103 max_concurrent_transactions: usize,
104) -> eyre::Result<()> {
105 info!(%channel_address, "Checking MPP channel token approvals");
106
107 let approvals: Vec<_> = stream::iter(signer_providers.iter())
109 .filter_map(|(signer, provider)| {
110 let provider = provider.clone();
111 let owner = signer.address();
112 async move {
113 let token = ITIP20Instance::new(fee_token, provider);
114 let allowance = token.allowance(owner, channel_address).call().await.ok()?;
115 if allowance == U256::ZERO {
116 Some(Box::pin(
117 async move { token.approve(channel_address, U256::MAX).send().await },
118 ) as BoxFuture<'static, _>)
119 } else {
120 None
121 }
122 }
123 })
124 .collect::<Vec<_>>()
125 .await;
126
127 if approvals.is_empty() {
128 info!("All signers already have approvals");
129 return Ok(());
130 }
131
132 info!(count = approvals.len(), "Approving signers");
133
134 join_all(
135 approvals.into_iter().progress(),
136 max_concurrent_requests,
137 max_concurrent_transactions,
138 )
139 .await
140 .context("Failed to approve MPP channel contract")?;
141
142 Ok(())
143}