| 90 | } |
| 91 | |
| 92 | async fn run<C>(provider: &Provider<C>, opts: &Options) -> anyhow::Result<()> |
| 93 | where |
| 94 | C: JsonRpcClient + Clone + 'static, |
| 95 | { |
| 96 | let from = TestAccount::new(&opts.secret_key)?; |
| 97 | |
| 98 | tracing::info!(from = ?from.eth_addr, "ethereum address"); |
| 99 | tracing::info!("deploying QueryBlockhash"); |
| 100 | |
| 101 | let bytecode = |
| 102 | Bytes::from(hex::decode(QUERYBLOCKHASH_HEX).context("failed to decode contract hex")?); |
| 103 | let abi: Abi = QUERYBLOCKHASH_ABI.clone(); |
| 104 | |
| 105 | let chain_id = provider.get_chainid().await?; |
| 106 | |
| 107 | let mw = make_middleware(provider.clone(), chain_id.as_u64(), &from) |
| 108 | .context("failed to create middleware")?; |
| 109 | |
| 110 | let mw = Arc::new(mw); |
| 111 | |
| 112 | let factory = ContractFactory::new(abi, bytecode.clone(), mw.clone()); |
| 113 | let deployer = factory.deploy(())?; |
| 114 | |
| 115 | let (contract, deploy_receipt): (_, TransactionReceipt) = deployer |
| 116 | .send_with_receipt() |
| 117 | .await |
| 118 | .context("failed to send deployment")?; |
| 119 | |
| 120 | tracing::info!(addr = ?contract.address(), "QueryBlockhash deployed"); |
| 121 | |
| 122 | let contract = QueryBlockhash::new(contract.address(), contract.client()); |
| 123 | |
| 124 | // check the deploy_height so we don't risk asking for blocks that had |
| 125 | // been removed from the chainmetadata state (it has a relatively short |
| 126 | // lookback length of 256) |
| 127 | let deploy_height = deploy_receipt |
| 128 | .block_number |
| 129 | .expect("deploy height should be set") |
| 130 | .as_u64(); |
| 131 | tracing::info!("deploy_height: {:?}", deploy_height); |
| 132 | |
| 133 | // we want check the get the blockhash for the last 5 blocks |
| 134 | const NR_CHECKS: u64 = 5; |
| 135 | let start_block = if deploy_height >= NR_CHECKS { |
| 136 | deploy_height - NR_CHECKS |
| 137 | } else { |
| 138 | 0 |
| 139 | }; |
| 140 | |
| 141 | // check that the blockhash returned by the contract matches the one returned by tendermint |
| 142 | for epoch in start_block..deploy_height { |
| 143 | tracing::info!("Checking blockhashes at epoch: {}", epoch); |
| 144 | |
| 145 | // get the blockhash from the contract, which results in call to get_tipset_cid in fendermint |
| 146 | // |
| 147 | let blockhash: [u8; 32] = contract |
| 148 | .get_blockhash(U256::from(epoch)) |
| 149 | .call() |