diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0bffce707..4e1ab2480 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,7 +45,6 @@ jobs: with: repository: taikoxyz/taiko-mono path: ${{ env.TAIKO_MONO_DIR }} - ref: get_oracle_prover - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 diff --git a/bindings/.githead b/bindings/.githead index ab0dedea9..f4217b3d6 100644 --- a/bindings/.githead +++ b/bindings/.githead @@ -1 +1 @@ -b27d42cc59e26a8ff451692febfc4d1d71da66db +ec477de46f543339e71d4aa8453b62f44c32b32f diff --git a/bindings/gen_taiko_l1.go b/bindings/gen_taiko_l1.go index 631712918..bf55abbfd 100644 --- a/bindings/gen_taiko_l1.go +++ b/bindings/gen_taiko_l1.go @@ -103,7 +103,7 @@ type TaikoDataStateVariables struct { // TaikoL1ClientMetaData contains all meta data concerning the TaikoL1Client contract. var TaikoL1ClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_FORK_CHOICE_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_FORK_CHOICE_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ORACLE_DISABLED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ORACLE_DISABLED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Overflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"depositsRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"cacheTxListInfo\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"treasure\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"parentGasUsed\",\"type\":\"uint32\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositEtherToL2\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getBlock\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"_metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_proposedAt\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockFee\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ringBufferSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txListCacheExpiry\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofCooldownPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"realProofSkipSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositMaxFee\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minEthDepositsPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxEthDepositsPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxEthDepositAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"minEthDepositAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeTarget\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"adjustmentQuotient\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"relaySignalRoot\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getCrossChainBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getCrossChainSignalRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"parentGasUsed\",\"type\":\"uint32\"}],\"name\":\"getForkChoice\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasUsed\",\"type\":\"uint32\"}],\"internalType\":\"structTaikoData.ForkChoice\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOracleProver\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"name\":\"getProofReward\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accBlockFees\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeIssued\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getTaikoTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getVerifierName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_initBlockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_initProofTimeIssued\",\"type\":\"uint64\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"}],\"name\":\"proposeBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"depositsRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"cacheTxListInfo\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"treasure\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"staticRefs\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved71\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved72\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accBlockFees\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeIssued\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved91\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxBlocks\",\"type\":\"uint256\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + ABI: "[{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ALREADY_PROVEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_BLOCK_ID\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"L1_EVIDENCE_MISMATCH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_FORK_CHOICE_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_FORK_CHOICE_NOT_FOUND\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INSUFFICIENT_TOKEN\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_CONFIG\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_ETH_DEPOSIT\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_EVIDENCE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_METADATA\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PARAM\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_INVALID_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_NOT_ORACLE_PROVER\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ORACLE_DISABLED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_ORACLE_DISABLED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_SAME_PROOF\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TOO_MANY_BLOCKS\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_HASH\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_NOT_EXIST\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"L1_TX_LIST_RANGE\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Overflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_DENIED\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RESOLVER_INVALID_ADDR\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"depositsRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"cacheTxListInfo\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"treasure\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"indexed\":false,\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"name\":\"BlockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"parentGasUsed\",\"type\":\"uint32\"}],\"name\":\"BlockProven\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"name\":\"BlockVerified\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"srcHeight\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"}],\"name\":\"CrossChainSynced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"indexed\":false,\"internalType\":\"structTaikoData.EthDeposit\",\"name\":\"deposit\",\"type\":\"tuple\"}],\"name\":\"EthDeposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addressManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositEtherToL2\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"depositTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getBlock\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"_metaHash\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"_proposer\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"_proposedAt\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockFee\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxNumProposedBlocks\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ringBufferSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxVerificationsPerTx\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"blockMaxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxTransactionsPerBlock\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxBytesPerTxList\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minTxGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"txListCacheExpiry\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"proofCooldownPeriod\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"realProofSkipSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"ethDepositMaxFee\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"minEthDepositsPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"maxEthDepositsPerBlock\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxEthDepositAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"minEthDepositAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeTarget\",\"type\":\"uint64\"},{\"internalType\":\"uint8\",\"name\":\"adjustmentQuotient\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"relaySignalRoot\",\"type\":\"bool\"}],\"internalType\":\"structTaikoData.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getCrossChainBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"}],\"name\":\"getCrossChainSignalRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"parentGasUsed\",\"type\":\"uint32\"}],\"name\":\"getForkChoice\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"key\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"signalRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"prover\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"gasUsed\",\"type\":\"uint32\"}],\"internalType\":\"structTaikoData.ForkChoice\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"provenAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proposedAt\",\"type\":\"uint64\"}],\"name\":\"getProofReward\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStateVariables\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accBlockFees\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeIssued\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numEthDeposits\",\"type\":\"uint64\"}],\"internalType\":\"structTaikoData.StateVariables\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getTaikoTokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"id\",\"type\":\"uint16\"}],\"name\":\"getVerifierName\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_addressManager\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_genesisBlockHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"_initBlockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"_initProofTimeIssued\",\"type\":\"uint64\"}],\"name\":\"init\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"txList\",\"type\":\"bytes\"}],\"name\":\"proposeBlock\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"id\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"timestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"l1Height\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"l1Hash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"mixHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"depositsRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"txListHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint24\",\"name\":\"txListByteStart\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"txListByteEnd\",\"type\":\"uint24\"},{\"internalType\":\"uint32\",\"name\":\"gasLimit\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"},{\"internalType\":\"uint8\",\"name\":\"cacheTxListInfo\",\"type\":\"uint8\"},{\"internalType\":\"address\",\"name\":\"treasure\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"internalType\":\"structTaikoData.EthDeposit[]\",\"name\":\"depositsProcessed\",\"type\":\"tuple[]\"}],\"internalType\":\"structTaikoData.BlockMetadata\",\"name\":\"meta\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"input\",\"type\":\"bytes\"}],\"name\":\"proveBlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"name\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"allowZeroAddress\",\"type\":\"bool\"}],\"name\":\"resolve\",\"outputs\":[{\"internalType\":\"addresspayable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"state\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"staticRefs\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"genesisHeight\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"genesisTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved71\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved72\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accProposedAt\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"accBlockFees\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"numBlocks\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"nextEthDepositToProcess\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockFee\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"proofTimeIssued\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBlockId\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"__reserved91\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxBlocks\",\"type\":\"uint256\"}],\"name\":\"verifyBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawTaikoToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", } // TaikoL1ClientABI is the input ABI used to generate the binding from. @@ -488,37 +488,6 @@ func (_TaikoL1Client *TaikoL1ClientCallerSession) GetForkChoice(blockId *big.Int return _TaikoL1Client.Contract.GetForkChoice(&_TaikoL1Client.CallOpts, blockId, parentHash, parentGasUsed) } -// GetOracleProver is a free data retrieval call binding the contract method 0x6287f325. -// -// Solidity: function getOracleProver() view returns(address) -func (_TaikoL1Client *TaikoL1ClientCaller) GetOracleProver(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _TaikoL1Client.contract.Call(opts, &out, "getOracleProver") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -// GetOracleProver is a free data retrieval call binding the contract method 0x6287f325. -// -// Solidity: function getOracleProver() view returns(address) -func (_TaikoL1Client *TaikoL1ClientSession) GetOracleProver() (common.Address, error) { - return _TaikoL1Client.Contract.GetOracleProver(&_TaikoL1Client.CallOpts) -} - -// GetOracleProver is a free data retrieval call binding the contract method 0x6287f325. -// -// Solidity: function getOracleProver() view returns(address) -func (_TaikoL1Client *TaikoL1ClientCallerSession) GetOracleProver() (common.Address, error) { - return _TaikoL1Client.Contract.GetOracleProver(&_TaikoL1Client.CallOpts) -} - // GetProofReward is a free data retrieval call binding the contract method 0x4ee56f9e. // // Solidity: function getProofReward(uint64 provenAt, uint64 proposedAt) view returns(uint64) diff --git a/cmd/flags/prover.go b/cmd/flags/prover.go index d7cb94c83..3ead325d3 100644 --- a/cmd/flags/prover.go +++ b/cmd/flags/prover.go @@ -57,7 +57,11 @@ var ( Name: "oracleProver", Usage: "Set whether prover should use oracle prover or not", Category: proverCategory, - Value: false, + } + OracleProverPrivateKey = &cli.BoolFlag{ + Name: "oracleProverPrivateKey", + Usage: "Private key of oracle prover", + Category: proverCategory, } Graffiti = &cli.StringFlag{ Name: "graffiti", @@ -80,5 +84,6 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{ Dummy, RandomDummyProofDelay, OracleProver, + OracleProverPrivateKey, Graffiti, }) diff --git a/metrics/metrics.go b/metrics/metrics.go index 12a85bbdd..df838ff5f 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -40,6 +40,7 @@ var ( ProverSentValidProofCounter = metrics.NewRegisteredCounter("prover/proof/valid/sent", nil) ProverSentInvalidProofCounter = metrics.NewRegisteredCounter("prover/proof/invalid/sent", nil) ProverReceivedProposedBlockGauge = metrics.NewRegisteredGauge("prover/proposed/received", nil) + ProverReceivedProvenBlockGauge = metrics.NewRegisteredGauge("prover/proven/received", nil) ) // Serve starts the metrics server on the given address, will be closed when the given diff --git a/prover/config.go b/prover/config.go index 62b3884b6..5bd34e857 100644 --- a/prover/config.go +++ b/prover/config.go @@ -28,6 +28,7 @@ type Config struct { MaxConcurrentProvingJobs uint Dummy bool OracleProver bool + OracleProverPrivateKey *ecdsa.PrivateKey Graffiti string RandomDummyProofDelayLowerBound *time.Duration RandomDummyProofDelayUpperBound *time.Duration @@ -42,6 +43,20 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { return nil, fmt.Errorf("invalid L1 prover private key: %w", err) } + var oracleProverPrivKey *ecdsa.PrivateKey + if c.IsSet(flags.OracleProver.Name) { + if !c.IsSet(flags.OracleProverPrivateKey.Name) { + return nil, fmt.Errorf("oracleProver flag set without oracleProverPrivateKey set") + } + + oracleProverPrivKeyStr := c.String(flags.OracleProverPrivateKey.Name) + + oracleProverPrivKey, err = crypto.ToECDSA(common.Hex2Bytes(oracleProverPrivKeyStr)) + if err != nil { + return nil, fmt.Errorf("invalid oracle private key: %w", err) + } + } + var ( randomDummyProofDelayLowerBound *time.Duration randomDummyProofDelayUpperBound *time.Duration @@ -90,6 +105,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) { MaxConcurrentProvingJobs: c.Uint(flags.MaxConcurrentProvingJobs.Name), Dummy: c.Bool(flags.Dummy.Name), OracleProver: c.Bool(flags.OracleProver.Name), + OracleProverPrivateKey: oracleProverPrivKey, Graffiti: c.String(flags.Graffiti.Name), RandomDummyProofDelayLowerBound: randomDummyProofDelayLowerBound, RandomDummyProofDelayUpperBound: randomDummyProofDelayUpperBound, diff --git a/prover/config_test.go b/prover/config_test.go index a57d7db92..b0eb34271 100644 --- a/prover/config_test.go +++ b/prover/config_test.go @@ -30,6 +30,7 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() { &cli.BoolFlag{Name: flags.Dummy.Name}, &cli.StringFlag{Name: flags.RandomDummyProofDelay.Name}, &cli.BoolFlag{Name: flags.OracleProver.Name}, + &cli.StringFlag{Name: flags.OracleProverPrivateKey.Name}, &cli.StringFlag{Name: flags.Graffiti.Name}, } app.Action = func(ctx *cli.Context) error { @@ -49,6 +50,10 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() { s.Equal(time.Hour, *c.RandomDummyProofDelayUpperBound) s.True(c.Dummy) s.True(c.OracleProver) + s.Equal( + crypto.PubkeyToAddress(s.p.cfg.OracleProverPrivateKey.PublicKey), + crypto.PubkeyToAddress(c.OracleProverPrivateKey.PublicKey), + ) s.Equal("", c.Graffiti) s.Nil(new(Prover).InitFromCli(context.Background(), ctx)) @@ -67,6 +72,52 @@ func (s *ProverTestSuite) TestNewConfigFromCliContext() { "-" + flags.Dummy.Name, "-" + flags.RandomDummyProofDelay.Name, "30m-1h", "-" + flags.OracleProver.Name, + "-" + flags.OracleProverPrivateKey.Name, os.Getenv("L1_PROVER_PRIVATE_KEY"), "-" + flags.Graffiti.Name, "", })) } + +func (s *ProverTestSuite) TestNewConfigFromCliContext_OracleProverError() { + l1WsEndpoint := os.Getenv("L1_NODE_WS_ENDPOINT") + l1HttpEndpoint := os.Getenv("L1_NODE_HTTP_ENDPOINT") + l2WsEndpoint := os.Getenv("L2_EXECUTION_ENGINE_WS_ENDPOINT") + l2HttpEndpoint := os.Getenv("L2_EXECUTION_ENGINE_HTTP_ENDPOINT") + taikoL1 := os.Getenv("TAIKO_L1_ADDRESS") + taikoL2 := os.Getenv("TAIKO_L2_ADDRESS") + + app := cli.NewApp() + app.Flags = []cli.Flag{ + &cli.StringFlag{Name: flags.L1WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L1HTTPEndpoint.Name}, + &cli.StringFlag{Name: flags.L2WSEndpoint.Name}, + &cli.StringFlag{Name: flags.L2HTTPEndpoint.Name}, + &cli.StringFlag{Name: flags.TaikoL1Address.Name}, + &cli.StringFlag{Name: flags.TaikoL2Address.Name}, + &cli.StringFlag{Name: flags.L1ProverPrivKey.Name}, + &cli.BoolFlag{Name: flags.Dummy.Name}, + &cli.StringFlag{Name: flags.RandomDummyProofDelay.Name}, + &cli.BoolFlag{Name: flags.OracleProver.Name}, + &cli.StringFlag{Name: flags.OracleProverPrivateKey.Name}, + &cli.StringFlag{Name: flags.Graffiti.Name}, + } + app.Action = func(ctx *cli.Context) error { + _, err := NewConfigFromCliContext(ctx) + s.NotNil(err) + return err + } + + s.ErrorContains(app.Run([]string{ + "TestNewConfigFromCliContext", + "-" + flags.L1WSEndpoint.Name, l1WsEndpoint, + "-" + flags.L1HTTPEndpoint.Name, l1HttpEndpoint, + "-" + flags.L2WSEndpoint.Name, l2WsEndpoint, + "-" + flags.L2HTTPEndpoint.Name, l2HttpEndpoint, + "-" + flags.TaikoL1Address.Name, taikoL1, + "-" + flags.TaikoL2Address.Name, taikoL2, + "-" + flags.L1ProverPrivKey.Name, os.Getenv("L1_PROVER_PRIVATE_KEY"), + "-" + flags.Dummy.Name, + "-" + flags.RandomDummyProofDelay.Name, "30m-1h", + "-" + flags.OracleProver.Name, + "-" + flags.Graffiti.Name, "", + }), "oracleProver flag set without oracleProverPrivateKey set") +} diff --git a/prover/proof_producer/dummy_producer.go b/prover/proof_producer/dummy_producer.go index 2a25d768f..c601d8a2a 100644 --- a/prover/proof_producer/dummy_producer.go +++ b/prover/proof_producer/dummy_producer.go @@ -61,3 +61,8 @@ func (d *DummyProofProducer) proofDelay() time.Duration { return delay } + +// Cancel cancels an existing proof generation. +func (d *DummyProofProducer) Cancel(ctx context.Context, blockID *big.Int) error { + return nil +} diff --git a/prover/proof_producer/oracle_proof_producer.go b/prover/proof_producer/oracle_proof_producer.go index 7a542f44f..6a6550a0e 100644 --- a/prover/proof_producer/oracle_proof_producer.go +++ b/prover/proof_producer/oracle_proof_producer.go @@ -3,6 +3,7 @@ package producer import ( "context" "crypto/ecdsa" + "errors" "fmt" "math/big" "time" @@ -17,6 +18,10 @@ import ( anchorTxValidator "github.com/taikoxyz/taiko-client/prover/anchor_tx_validator" ) +var ( + errProtocolAddressMismatch = errors.New("oracle prover private key does not match protocol setting") +) + // OracleProducer is responsible for generating a fake "zkproof" consisting // of a signature of the evidence. type OracleProducer struct { @@ -32,7 +37,13 @@ func NewOracleProducer( proverPrivKey *ecdsa.PrivateKey, taikoL2Address common.Address, proofTimeTarget time.Duration, + protocolOracleProverAddress common.Address, ) (*OracleProducer, error) { + proverAddress := crypto.PubkeyToAddress(proverPrivKey.PublicKey) + if proverAddress != protocolOracleProverAddress { + return nil, errProtocolAddressMismatch + } + anchorValidator, err := anchorTxValidator.New(taikoL2Address, rpc.L2ChainID, rpc) if err != nil { return nil, err @@ -138,3 +149,9 @@ func hashAndSignForOracleProof( return sig, v, nil } + +// Cancel cancels an existing proof generation. +// Since Oracle proofs are not "real" proofs, there is nothing to cancel. +func (d *OracleProducer) Cancel(ctx context.Context, blockID *big.Int) error { + return nil +} diff --git a/prover/proof_producer/proof_producer.go b/prover/proof_producer/proof_producer.go index 3fd07e3ba..e7faa78a9 100644 --- a/prover/proof_producer/proof_producer.go +++ b/prover/proof_producer/proof_producer.go @@ -42,6 +42,7 @@ type ProofProducer interface { header *types.Header, resultCh chan *ProofWithHeader, ) error + Cancel(ctx context.Context, blockID *big.Int) error } func DegreeToCircuitsIdx(degree uint64) (uint16, error) { diff --git a/prover/proof_producer/zkevm_cmd_producer.go b/prover/proof_producer/zkevm_cmd_producer.go index d2f7e708b..596135304 100644 --- a/prover/proof_producer/zkevm_cmd_producer.go +++ b/prover/proof_producer/zkevm_cmd_producer.go @@ -154,3 +154,11 @@ func (d *ZkevmCmdProducer) outputToCalldata(output *ProverCmdOutput) []byte { return calldata[:bufLen] } + +// Cancel cancels an existing proof generation. +// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof +// with the current zkevm software. +func (d *ZkevmCmdProducer) Cancel(ctx context.Context, blockID *big.Int) error { + log.Info("Cancel proof generation for block ", "blockId", blockID) + return nil +} diff --git a/prover/proof_producer/zkevm_rpcd_producer.go b/prover/proof_producer/zkevm_rpcd_producer.go index 70880bb77..f0916b1a9 100644 --- a/prover/proof_producer/zkevm_rpcd_producer.go +++ b/prover/proof_producer/zkevm_rpcd_producer.go @@ -210,3 +210,11 @@ func (d *ZkevmRpcdProducer) requestProof(opts *ProofRequestOptions) (*RpcdOutput return output.Result, nil } + +// Cancel cancels an existing proof generation. +// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof +// with the current zkevm software. +func (d *ZkevmRpcdProducer) Cancel(ctx context.Context, blockID *big.Int) error { + log.Info("Cancel proof generation for block ", "blockId", blockID) + return nil +} diff --git a/prover/proof_submitter/interface.go b/prover/proof_submitter/interface.go index ec3f84d50..84973585f 100644 --- a/prover/proof_submitter/interface.go +++ b/prover/proof_submitter/interface.go @@ -2,6 +2,7 @@ package submitter import ( "context" + "math/big" "github.com/taikoxyz/taiko-client/bindings" proofProducer "github.com/taikoxyz/taiko-client/prover/proof_producer" @@ -10,4 +11,5 @@ import ( type ProofSubmitter interface { RequestProof(ctx context.Context, event *bindings.TaikoL1ClientBlockProposed) error SubmitProof(ctx context.Context, proofWithHeader *proofProducer.ProofWithHeader) error + CancelProof(ctx context.Context, blockID *big.Int) error } diff --git a/prover/proof_submitter/valid_proof_submitter.go b/prover/proof_submitter/valid_proof_submitter.go index ccdb15844..3c567b7e5 100644 --- a/prover/proof_submitter/valid_proof_submitter.go +++ b/prover/proof_submitter/valid_proof_submitter.go @@ -5,6 +5,7 @@ import ( "crypto/ecdsa" "errors" "fmt" + "math/big" "sync" "github.com/ethereum/go-ethereum/common" @@ -231,3 +232,10 @@ func (s *ValidProofSubmitter) SubmitProof( return nil } + +// CancelProof cancels an existing proof generation. +// Right now, it is just a stub that does nothing, because it is not possible to cnacel the proof +// with the current zkevm software. +func (s *ValidProofSubmitter) CancelProof(ctx context.Context, blockID *big.Int) error { + return s.proofProducer.Cancel(ctx, blockID) +} diff --git a/prover/proof_submitter/valid_proof_submitter_test.go b/prover/proof_submitter/valid_proof_submitter_test.go index c910cb163..2396abf1c 100644 --- a/prover/proof_submitter/valid_proof_submitter_test.go +++ b/prover/proof_submitter/valid_proof_submitter_test.go @@ -116,6 +116,20 @@ func (s *ProofSubmitterTestSuite) TestValidSubmitProofs() { } } +func (s *ProofSubmitterTestSuite) TestValidProofSubmitterRequestProofCancelled() { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + time.AfterFunc(2*time.Second, func() { + cancel() + }) + }() + + s.ErrorContains( + s.validProofSubmitter.RequestProof( + ctx, &bindings.TaikoL1ClientBlockProposed{Id: common.Big256}), "context canceled", + ) +} + func TestProofSubmitterTestSuite(t *testing.T) { suite.Run(t, new(ProofSubmitterTestSuite)) } diff --git a/prover/prover.go b/prover/prover.go index 51649ef7d..32bacd3ef 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -24,11 +24,14 @@ import ( "github.com/urfave/cli/v2" ) +type cancelFunc func() + // Prover keep trying to prove new proposed blocks valid/invalid. type Prover struct { // Configurations - cfg *Config - proverAddress common.Address + cfg *Config + proverAddress common.Address + oracleProverAddress common.Address // Clients rpc *rpc.Client @@ -48,6 +51,8 @@ type Prover struct { // Subscriptions blockProposedCh chan *bindings.TaikoL1ClientBlockProposed blockProposedSub event.Subscription + blockProvenCh chan *bindings.TaikoL1ClientBlockProven + blockProvenSub event.Subscription blockVerifiedCh chan *bindings.TaikoL1ClientBlockVerified blockVerifiedSub event.Subscription proveNotify chan struct{} @@ -61,6 +66,9 @@ type Prover struct { submitProofConcurrencyGuard chan struct{} submitProofTxMutex *sync.Mutex + currentBlocksBeingProven map[uint64]cancelFunc + currentBlocksBeingProvenMutex *sync.Mutex + ctx context.Context wg sync.WaitGroup } @@ -79,6 +87,8 @@ func (p *Prover) InitFromCli(ctx context.Context, c *cli.Context) error { func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.cfg = cfg p.ctx = ctx + p.currentBlocksBeingProven = make(map[uint64]cancelFunc) + p.currentBlocksBeingProvenMutex = &sync.Mutex{} // Clients if p.rpc, err = rpc.NewClient(p.ctx, &rpc.ClientConfig{ @@ -112,6 +122,7 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { chBufferSize := p.protocolConfigs.MaxNumProposedBlocks.Uint64() p.blockProposedCh = make(chan *bindings.TaikoL1ClientBlockProposed, chBufferSize) p.blockVerifiedCh = make(chan *bindings.TaikoL1ClientBlockVerified, chBufferSize) + p.blockProvenCh = make(chan *bindings.TaikoL1ClientBlockProven, chBufferSize) p.proveValidProofCh = make(chan *proofProducer.ProofWithHeader, chBufferSize) p.proveInvalidProofCh = make(chan *proofProducer.ProofWithHeader, chBufferSize) p.proveNotify = make(chan struct{}, 1) @@ -123,14 +134,25 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { p.proposeConcurrencyGuard = make(chan struct{}, cfg.MaxConcurrentProvingJobs) p.submitProofConcurrencyGuard = make(chan struct{}, cfg.MaxConcurrentProvingJobs) + oracleName := [32]byte{} + copy(oracleName[:], "oracle_prover") + + oracleProverAddress, err := p.rpc.TaikoL1.Resolve(nil, p.rpc.L1ChainID, oracleName, true) + if err != nil { + return err + } + + p.oracleProverAddress = oracleProverAddress + var producer proofProducer.ProofProducer if cfg.OracleProver { if producer, err = proofProducer.NewOracleProducer( p.rpc, - p.cfg.L1ProverPrivKey, + p.cfg.OracleProverPrivateKey, p.cfg.TaikoL2Address, time.Duration(p.protocolConfigs.ProofTimeTarget)*time.Second, + oracleProverAddress, ); err != nil { return err } @@ -219,6 +241,10 @@ func (p *Prover) eventLoop() { if err := p.onBlockVerified(p.ctx, e); err != nil { log.Error("Handle BlockVerified event error", "error", err) } + case e := <-p.blockProvenCh: + if err := p.onBlockProven(p.ctx, e); err != nil { + log.Error("Handle BlockProven event error", "error", err) + } case <-forceProvingTicker.C: reqProving() } @@ -287,6 +313,16 @@ func (p *Prover) onBlockProposed( return nil } + ctx, cancelCtx := context.WithCancel(ctx) + p.currentBlocksBeingProvenMutex.Lock() + p.currentBlocksBeingProven[event.Id.Uint64()] = cancelFunc(func() { + defer cancelCtx() + if err := p.validProofSubmitter.CancelProof(ctx, event.Id); err != nil { + log.Error("error cancelling proof", "error", err, "blockID", event.Id) + } + }) + p.currentBlocksBeingProvenMutex.Unlock() + return p.validProofSubmitter.RequestProof(ctx, event) } @@ -297,6 +333,9 @@ func (p *Prover) onBlockProposed( go func() { if err := handleBlockProposedEvent(); err != nil { + p.currentBlocksBeingProvenMutex.Lock() + delete(p.currentBlocksBeingProven, event.Id.Uint64()) + p.currentBlocksBeingProvenMutex.Unlock() log.Error("Handle new BlockProposed event error", "error", err) } }() @@ -308,7 +347,12 @@ func (p *Prover) onBlockProposed( func (p *Prover) submitProofOp(ctx context.Context, proofWithHeader *proofProducer.ProofWithHeader, isValidProof bool) { p.submitProofConcurrencyGuard <- struct{}{} go func() { - defer func() { <-p.submitProofConcurrencyGuard }() + defer func() { + <-p.submitProofConcurrencyGuard + p.currentBlocksBeingProvenMutex.Lock() + delete(p.currentBlocksBeingProven, proofWithHeader.Meta.Id) + p.currentBlocksBeingProvenMutex.Unlock() + }() if err := p.validProofSubmitter.SubmitProof(p.ctx, proofWithHeader); err != nil { log.Error("Submit proof error", "isValidProof", isValidProof, "error", err) @@ -316,8 +360,8 @@ func (p *Prover) submitProofOp(ctx context.Context, proofWithHeader *proofProduc }() } -// onBlockVerified update the latestVerified block in current state. -// TODO: cancel the corresponding block's proof generation, if requested before. +// onBlockVerified update the latestVerified block in current state, and cancels +// the block being proven if it's verified. func (p *Prover) onBlockVerified(ctx context.Context, event *bindings.TaikoL1ClientBlockVerified) error { metrics.ProverLatestVerifiedIDGauge.Update(event.Id.Int64()) p.latestVerifiedL1Height = event.Raw.BlockNumber @@ -328,6 +372,27 @@ func (p *Prover) onBlockVerified(ctx context.Context, event *bindings.TaikoL1Cli } log.Info("New verified valid block", "blockID", event.Id, "hash", common.BytesToHash(event.BlockHash[:])) + + // cancel any proofs being generated for this block + p.cancelProof(ctx, event.Id.Uint64()) + + return nil +} + +// onBlockProven cancels proof generation if the proof is being generated by this prover, +// and the proof is not the oracle proof address. +func (p *Prover) onBlockProven(ctx context.Context, event *bindings.TaikoL1ClientBlockProven) error { + metrics.ProverReceivedProvenBlockGauge.Update(event.Id.Int64()) + // if oracle prover, dont cancel proof. + if event.Prover == p.oracleProverAddress { + return nil + } + + // cancel any proofs being generated for this block + if err := p.cancelProofIfValid(ctx, event.Id.Uint64(), uint64(event.ParentGasUsed), event.ParentHash); err != nil { + return err + } + return nil } @@ -430,6 +495,7 @@ func (p *Prover) NeedNewProof(id *big.Int) (bool, error) { func (p *Prover) initSubscription() { p.blockProposedSub = rpc.SubscribeBlockProposed(p.rpc.TaikoL1, p.blockProposedCh) p.blockVerifiedSub = rpc.SubscribeBlockVerified(p.rpc.TaikoL1, p.blockVerifiedCh) + p.blockProvenSub = rpc.SubscribeBlockProven(p.rpc.TaikoL1, p.blockProvenCh) } // closeSubscription closes all subscriptions. @@ -437,3 +503,35 @@ func (p *Prover) closeSubscription() { p.blockVerifiedSub.Unsubscribe() p.blockProposedSub.Unsubscribe() } + +// cancelProofIfValid cancels proof only if the parentGasUsed and parentHash in the proof match what +// is expected +func (p *Prover) cancelProofIfValid( + ctx context.Context, + blockID uint64, + parentGasUsed uint64, + parentHash common.Hash, +) error { + parent, err := p.rpc.L2ParentByBlockId(ctx, new(big.Int).SetUint64(blockID)) + if err != nil { + return err + } + + if parent.GasUsed == parentGasUsed && parent.Hash() == parentHash { + p.cancelProof(ctx, blockID) + } + + return nil +} + +// cancelProof cancels local proof generation +func (p *Prover) cancelProof(ctx context.Context, blockID uint64) { + p.currentBlocksBeingProvenMutex.Lock() + defer p.currentBlocksBeingProvenMutex.Unlock() + + if cancel, ok := p.currentBlocksBeingProven[blockID]; ok { + cancel() + delete(p.currentBlocksBeingProven, blockID) + log.Info("Cancelled proof for ", "blockID", blockID) + } +} diff --git a/prover/prover_test.go b/prover/prover_test.go index 18328d105..d4f03ae1e 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -43,6 +43,7 @@ func (s *ProverTestSuite) SetupTest() { TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1_ADDRESS")), TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")), L1ProverPrivKey: l1ProverPrivKey, + OracleProverPrivateKey: l1ProverPrivKey, Dummy: true, MaxConcurrentProvingJobs: 1, }))) @@ -91,6 +92,10 @@ func (s *ProverTestSuite) TestName() { func (s *ProverTestSuite) TestOnBlockProposed() { s.p.cfg.OracleProver = true + // Init prover + l1ProverPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROVER_PRIVATE_KEY"))) + s.Nil(err) + s.p.cfg.OracleProverPrivateKey = l1ProverPrivKey // Valid block e := testutils.ProposeAndInsertValidBlock(&s.ClientTestSuite, s.proposer, s.d.ChainSyncer().CalldataSyncer()) s.Nil(s.p.onBlockProposed(context.Background(), e, func() {}))