From 261103e2637c452cf4acd64e0d53a1cac0a2adf7 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Wed, 14 Feb 2024 10:02:44 +0800 Subject: [PATCH] improve --- .../contracts/L1/libs/LibVerifying.sol | 3 +- packages/protocol/contracts/L2/TaikoL2.sol | 3 +- .../protocol/contracts/signal/LibSignals.sol | 21 ++++++++++++ .../contracts/signal/SignalService.sol | 32 +++++++++++++------ .../protocol/docs/how_taiko_proves_blocks.md | 16 +++++----- .../protocol/test/signal/SignalService.t.sol | 15 +++++---- 6 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 packages/protocol/contracts/signal/LibSignals.sol diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 49d14497ff0..9b05a4f2ae3 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -18,6 +18,7 @@ import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; import "../../libs/LibMath.sol"; import "../../signal/ISignalService.sol"; +import "../../signal/LibSignals.sol"; import "../tiers/ITierProvider.sol"; import "../TaikoData.sol"; import "./LibUtils.sol"; @@ -248,7 +249,7 @@ library LibVerifying { // is sent as a signal and verifiable with merkle proofs, all other blocks' // stateRoot are not. ISignalService(resolver.resolve("signal_service", false)).relayChainData( - config.chainId, "state_root", stateRoot + config.chainId, LibSignals.STATE_ROOT, stateRoot ); emit CrossChainSynced( diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index 9ae3727f91e..a26d44deb9f 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -19,6 +19,7 @@ import "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; import "../common/ICrossChainSync.sol"; import "../signal/ISignalService.sol"; +import "../signal/LibSignals.sol"; import "../libs/LibAddress.sol"; import "../libs/LibMath.sol"; import "./Lib1559Math.sol"; @@ -144,7 +145,7 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync { // Store the L1's state root as a signal to the local signal service to // allow for multi-hop bridging. ISignalService(resolve("signal_service", false)).relayChainData( - ownerChainId, "state_root", l1StateRoot + ownerChainId, LibSignals.STATE_ROOT, l1StateRoot ); emit CrossChainSynced(l1Height, l1BlockHash, l1StateRoot); diff --git a/packages/protocol/contracts/signal/LibSignals.sol b/packages/protocol/contracts/signal/LibSignals.sol new file mode 100644 index 00000000000..5cf4ca69045 --- /dev/null +++ b/packages/protocol/contracts/signal/LibSignals.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +// _____ _ _ _ _ +// |_ _|_ _(_) |_____ | | __ _| |__ ___ +// | |/ _` | | / / _ \ | |__/ _` | '_ (_-< +// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ +// +// Email: security@taiko.xyz +// Website: https://taiko.xyz +// GitHub: https://github.com/taikoxyz +// Discord: https://discord.gg/taikoxyz +// Twitter: https://twitter.com/taikoxyz +// Blog: https://mirror.xyz/labs.taiko.eth +// Youtube: https://www.youtube.com/@taikoxyz + +pragma solidity 0.8.24; + +/// @title LibSignals +library LibSignals { + bytes32 public constant STATE_ROOT = keccak256("STATE_ROOT"); + bytes32 public constant SIGNAL_ROOT = keccak256("SIGNAL_ROOT"); +} diff --git a/packages/protocol/contracts/signal/SignalService.sol b/packages/protocol/contracts/signal/SignalService.sol index 83da3605018..98db5636a64 100644 --- a/packages/protocol/contracts/signal/SignalService.sol +++ b/packages/protocol/contracts/signal/SignalService.sol @@ -21,6 +21,7 @@ import "../libs/LibTrieProof.sol"; import "../thirdparty/optimism/trie/SecureMerkleTrie.sol"; import "../thirdparty/optimism/rlp/RLPReader.sol"; import "./ISignalService.sol"; +import "./LibSignals.sol"; /// @title SignalService /// @dev Labeled in AddressResolver as "signal_service" @@ -34,9 +35,6 @@ contract SignalService is EssentialContract, ISignalService { bytes[] storageProof; } - bytes32 private constant _STATE_ROOT = bytes32("state_root"); - bytes32 private constant _SIGNAL_ROOT = bytes32("signal_root"); - uint256[50] private __gap; event SnippetRelayed( @@ -115,13 +113,9 @@ contract SignalService is EssentialContract, ISignalService { bool isFullProof = hop.accountProof.length > 0; - if (hop.cacheChainData) { - if (isLastHop) _relayChainData(_chainId, _SIGNAL_ROOT, signalRoot); - else if (isFullProof) _relayChainData(_chainId, _STATE_ROOT, hop.rootHash); - else _relayChainData(_chainId, _SIGNAL_ROOT, hop.rootHash); - } + _cacheChainData(hop, _chainId, signalRoot, isFullProof, isLastHop); - bytes32 kind = isFullProof ? _STATE_ROOT : _SIGNAL_ROOT; + bytes32 kind = isFullProof ? LibSignals.STATE_ROOT : LibSignals.SIGNAL_ROOT; _signal = signalForChainData(_chainId, kind, hop.rootHash); _chainId = hop.chainId; _app = _signalService; @@ -218,4 +212,24 @@ contract SignalService is EssentialContract, ISignalService { function _authorizePause(address) internal pure override { revert SS_UNSUPPORTED(); } + + function _cacheChainData( + HopProof memory hop, + uint64 chainId, + bytes32 signalRoot, + bool isFullProof, + bool isLastHop + ) + private + { + if (hop.cacheChainData) { + if (isLastHop) { + _relayChainData(chainId, LibSignals.SIGNAL_ROOT, signalRoot); + } else if (isFullProof) { + _relayChainData(chainId, LibSignals.STATE_ROOT, hop.rootHash); + } else { + _relayChainData(chainId, LibSignals.SIGNAL_ROOT, hop.rootHash); + } + } + } } diff --git a/packages/protocol/docs/how_taiko_proves_blocks.md b/packages/protocol/docs/how_taiko_proves_blocks.md index f6f72877bc5..2976244d6a9 100644 --- a/packages/protocol/docs/how_taiko_proves_blocks.md +++ b/packages/protocol/docs/how_taiko_proves_blocks.md @@ -232,16 +232,16 @@ s_gas_excess -.-> dot2 ---|calcBasefee| v_block_basefee; m_processed_deposits -.->|keccak| dot4; -b_signal_root --- a_l1_signal_root; +bSIGNAL_ROOT --- a_l1SIGNAL_ROOT; h_gas_used --- e_gas_used; BlockMetadata -.-> dot4((" ")) --- |keccak| e_meta_hash -.-> dot3((" ")) -.->|keccak| zk_instance; -e_parent_hash & e_block_hash & e_signal_root & e_graffiti & e_prover & e_parent_gas_used & e_gas_used -.-> dot3; +e_parent_hash & e_block_hash & eSIGNAL_ROOT & e_graffiti & e_prover & e_parent_gas_used & e_gas_used -.-> dot3; b_l1_signal_service_addr -.-> dot3; b_l2_signal_service_addr -.-> dot3; b_l1_taiko_addr -.-> dot3; -e_signal_root --- s_signal_root +eSIGNAL_ROOT --- sSIGNAL_ROOT e_parent_gas_used --- a_parent_gas_used h_gas_limit ---|>=| h_gas_used @@ -280,7 +280,7 @@ h_mix_hash(mixHash) h_proposer(proposer) h_parent_hash(parentHash) h_ommers_hash("ommersHash = keccak([])") -h_state_root(stateRoot) +hSTATE_ROOT(stateRoot) h_transactions_root(transactionsRoot) h_receipts_root(receiptsRoot) h_logs_bloom("logsBloom = []") @@ -312,7 +312,7 @@ subgraph Anchor [Anchor Tx] a_l1_height(l1Height) a_l1_hash(l1Hash) a_parent_gas_used(parentGasUsed) -a_l1_signal_root(l1SignalRoot) +a_l1SIGNAL_ROOT(l1SignalRoot) end Anchor:::group @@ -321,7 +321,7 @@ subgraph L1Storage[L1 Storage] b_l1_taiko_addr[/taikoL1Address/] b_l1_signal_service_addr[/L1 signalServiceAddress/] b_l2_signal_service_addr[/L2 signalServiceAddress/] -b_signal_root[/stateRoot/] +bSIGNAL_ROOT[/stateRoot/] end L1Storage:::group @@ -331,7 +331,7 @@ subgraph L2Storage[L2 Storage] s_public_input_hash[/publicInputHash/] s_parent_timestamp[/parentTimestamp/] s_gas_excess[/gasExcess/] -s_signal_root[/stateRoot/] +sSIGNAL_ROOT[/stateRoot/] end L2Storage:::group @@ -340,7 +340,7 @@ subgraph BlockEvidence e_meta_hash(metaHash) e_parent_hash(parentHash):::transition e_block_hash(blockHash) -e_signal_root(stateRoot) +eSIGNAL_ROOT(stateRoot) e_graffiti(graffiti) e_prover(prover) e_parent_gas_used(parentGasUsed):::transition diff --git a/packages/protocol/test/signal/SignalService.t.sol b/packages/protocol/test/signal/SignalService.t.sol index 01b2148d111..151728f3cc1 100644 --- a/packages/protocol/test/signal/SignalService.t.sol +++ b/packages/protocol/test/signal/SignalService.t.sol @@ -254,7 +254,7 @@ contract TestSignalService is TaikoTest { }); } - function test_SignalService_proveSignalReceived_one_hop_cache_signal_root() public { + function test_SignalService_proveSignalReceived_one_hop_cacheSIGNAL_ROOT() public { uint64 srcChainId = uint64(block.chainid + 1); vm.prank(Alice); @@ -280,7 +280,7 @@ contract TestSignalService is TaikoTest { // relay the signal root vm.prank(taiko); - signalService.relayChainData(srcChainId, "signal_root", proofs[0].rootHash); + signalService.relayChainData(srcChainId, LibSignals.SIGNAL_ROOT, proofs[0].rootHash); signalService.proveSignalReceived({ chainId: srcChainId, app: randAddress(), @@ -289,7 +289,7 @@ contract TestSignalService is TaikoTest { }); } - function test_SignalService_proveSignalReceived_one_hop_state_root() public { + function test_SignalService_proveSignalReceived_one_hopSTATE_ROOT() public { uint64 srcChainId = uint64(block.chainid + 1); vm.prank(Alice); @@ -315,7 +315,7 @@ contract TestSignalService is TaikoTest { // relay the state root vm.prank(taiko); - signalService.relayChainData(srcChainId, "state_root", proofs[0].rootHash); + signalService.relayChainData(srcChainId, LibSignals.STATE_ROOT, proofs[0].rootHash); // Should not revert signalService.proveSignalReceived({ @@ -325,8 +325,9 @@ contract TestSignalService is TaikoTest { proof: abi.encode(proofs) }); - bytes32 signal = - signalService.signalForChainData(srcChainId, "signal_root", bytes32(uint256(789))); + bytes32 signal = signalService.signalForChainData( + srcChainId, LibSignals.SIGNAL_ROOT, bytes32(uint256(789)) + ); assertEq(signalService.isSignalSent(address(signalService), signal), false); // enable cache @@ -393,7 +394,7 @@ contract TestSignalService is TaikoTest { }); vm.prank(taiko); - signalService.relayChainData(proofs[1].chainId, "state_root", proofs[2].rootHash); + signalService.relayChainData(proofs[1].chainId, LibSignals.STATE_ROOT, proofs[2].rootHash); signalService.proveSignalReceived({ chainId: srcChainId,