Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(protocol)!: improve signal service and remove ICrossChainSync #15859

Merged
merged 58 commits into from
Feb 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
aaf90c1
remove ICrossChainSync
dantaik Feb 15, 2024
d7cb588
fmt
dantaik Feb 15, 2024
6594284
fix
dantaik Feb 15, 2024
c083948
Update SignalService.sol
dantaik Feb 15, 2024
e9064a1
Merge branch 'slight_change' into option-2-remove-snippets
dantaik Feb 15, 2024
a215734
fix
dantaik Feb 15, 2024
233ae2e
refactor
dantaik Feb 15, 2024
bd0ba3d
more
dantaik Feb 15, 2024
e2c640e
Update SignalService.sol
dantaik Feb 15, 2024
48f2e8e
Update SignalService.sol
dantaik Feb 15, 2024
51b52bc
Update SignalService.t.sol
dantaik Feb 15, 2024
811b148
carry and hash in the block number with chain data
dantaik Feb 15, 2024
6a30a49
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 15, 2024
be4c244
Update LibVerifying.sol
dantaik Feb 15, 2024
d8c4639
Update TaikoL2.sol
dantaik Feb 15, 2024
bf8aa95
Merge branch 'main' into add_block_id
dantaik Feb 15, 2024
def6038
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 15, 2024
f905786
Update TaikoL2.sol
dantaik Feb 15, 2024
6086fd9
more
dantaik Feb 15, 2024
7245486
Update TaikoL2.ts
dantaik Feb 15, 2024
5ff9fdc
rename
dantaik Feb 15, 2024
5368a6f
Merge branch 'main' into add_block_id
dantaik Feb 15, 2024
74087c8
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 15, 2024
26431cc
Merge branch 'main' into add_block_id
dionysuzx Feb 16, 2024
485c695
fix tests
dantaik Feb 16, 2024
7310653
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 16, 2024
0d32de1
chore(protocol): store signal value instead of `1` in signal service …
dantaik Feb 16, 2024
168db94
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 16, 2024
a214c85
more
dantaik Feb 16, 2024
e387162
more
dantaik Feb 16, 2024
2feee88
more
dantaik Feb 16, 2024
e8b5906
more
dantaik Feb 16, 2024
50f53d6
more
dantaik Feb 16, 2024
aabae4b
rename
dantaik Feb 16, 2024
ccb2d3d
fix
dantaik Feb 16, 2024
9765a37
Update SignalService.t.sol
dantaik Feb 16, 2024
072645e
Update SignalService.sol
dantaik Feb 16, 2024
26f12a0
Update ISignalService.sol
dantaik Feb 16, 2024
6f35469
Merge branch 'main' into add_block_id
dantaik Feb 16, 2024
754d634
Merge branch 'add_block_id' into option-2-remove-snippets
dantaik Feb 16, 2024
fbc1e4d
Merge branch 'main' into remove_cross_chain_snippet
dantaik Feb 16, 2024
e170476
rename
dantaik Feb 16, 2024
ef0dc91
Merge branch 'remove_cross_chain_snippet' of https://github.com/taiko…
dantaik Feb 16, 2024
33d5c48
slight improve
dantaik Feb 16, 2024
7cfefb0
Update SignalService.sol
dantaik Feb 16, 2024
d206ccf
rename a method
dantaik Feb 16, 2024
0f239dd
rename
dantaik Feb 16, 2024
31beda9
Update SignalService.sol
dantaik Feb 16, 2024
fd7f446
Update ISignalService.sol
dantaik Feb 16, 2024
274c9e4
Update packages/protocol/contracts/L1/TaikoData.sol
dantaik Feb 16, 2024
9ec21b8
minor change
dantaik Feb 16, 2024
06f75af
rename
dantaik Feb 16, 2024
f080679
refactor
dantaik Feb 16, 2024
f6e4ec9
fmt
dantaik Feb 16, 2024
b386a3f
Merge branch 'main' into remove_cross_chain_snippet
dantaik Feb 16, 2024
99be03f
Merge branch 'main' into remove_cross_chain_snippet
dantaik Feb 16, 2024
6e3da09
Merge branch 'main' into remove_cross_chain_snippet
dantaik Feb 17, 2024
64fb08c
Merge branch 'remove_cross_chain_snippet' of https://github.com/taiko…
dantaik Feb 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ library TaikoData {
uint256 ethDepositGas;
// The maximum fee allowed for an ETH deposit.
uint256 ethDepositMaxFee;
// The max number of L2 blocks that can stay unsynced on L1 (a value of zero disables
// syncing)
uint8 blockSyncThreshold;
}

/// @dev Struct representing prover assignment
Expand Down
25 changes: 3 additions & 22 deletions packages/protocol/contracts/L1/TaikoL1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,7 @@ import "./TaikoEvents.sol";
/// layers"). The contract also handles the deposit and withdrawal of Taiko
/// tokens and Ether.
/// This contract doesn't hold any Ether. Ether deposited to L2 are held by the Bridge contract.
contract TaikoL1 is
EssentialContract,
ITaikoL1,
ICrossChainSync,
ITierProvider,
TaikoEvents,
TaikoErrors
{
contract TaikoL1 is EssentialContract, ITaikoL1, ITierProvider, TaikoEvents, TaikoErrors {
TaikoData.State public state;
uint256[100] private __gap;

Expand Down Expand Up @@ -168,19 +161,6 @@ contract TaikoL1 is
return LibUtils.getTransition(state, getConfig(), blockId, parentHash);
}

/// @inheritdoc ICrossChainSync
/// @notice Important: as this contract doesn't send each block's state root as a signal when
/// the block is verified, bridging developers should subscribe to CrossChainSynced events
/// to ensure all synced state roots are verifiable using merkle proofs.
function getSyncedSnippet(uint64 blockId)
public
view
override
returns (ICrossChainSync.Snippet memory)
{
return LibUtils.getSyncedSnippet(state, getConfig(), AddressResolver(this), blockId);
}

/// @notice Gets the state variables of the TaikoL1 contract.
function getStateVariables()
public
Expand Down Expand Up @@ -247,7 +227,8 @@ contract TaikoL1 is
ethDepositMinAmount: 1 ether,
ethDepositMaxAmount: 10_000 ether,
ethDepositGas: 21_000,
ethDepositMaxFee: 1 ether / 10
ethDepositMaxFee: 1 ether / 10,
blockSyncThreshold: 16
dantaik marked this conversation as resolved.
Show resolved Hide resolved
});
}

Expand Down
35 changes: 0 additions & 35 deletions packages/protocol/contracts/L1/libs/LibUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
pragma solidity 0.8.24;

import "../../common/AddressResolver.sol";
import "../../common/ICrossChainSync.sol";
import "../../signal/ISignalService.sol";
import "../../signal/LibSignals.sol";
import "../TaikoData.sol";
Expand Down Expand Up @@ -57,40 +56,6 @@ library LibUtils {
ts = state.transitions[slot][tid];
}

function getSyncedSnippet(
TaikoData.State storage state,
TaikoData.Config memory config,
AddressResolver resolver,
uint64 blockId
)
external
view
returns (ICrossChainSync.Snippet memory)
{
uint64 _blockId = blockId == 0 ? state.slotB.lastVerifiedBlockId : blockId;
uint64 slot = _blockId % config.blockRingBufferSize;

TaikoData.Block storage blk = state.blocks[slot];

if (blk.blockId != _blockId) revert L1_BLOCK_MISMATCH();
if (blk.verifiedTransitionId == 0) revert L1_TRANSITION_NOT_FOUND();

TaikoData.TransitionState storage ts = state.transitions[slot][blk.verifiedTransitionId];

// bool relayed = ISignalService(resolver.resolve("signal_service",
// false)).isChainDataRelayed(
// config.chainId, LibSignals.STATE_ROOT, ts.stateRoot
// );
// if (!relayed) revert L1_CHAIN_DATA_NOT_RELAYED();

return ICrossChainSync.Snippet({
syncedInBlock: blk.proposedIn,
blockId: blockId,
blockHash: ts.blockHash,
stateRoot: ts.stateRoot
});
}

/// @dev Retrieves a block based on its ID.
function getBlock(
TaikoData.State storage state,
Expand Down
40 changes: 23 additions & 17 deletions packages/protocol/contracts/L1/libs/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ library LibVerifying {
uint8 contestations
);

event CrossChainSynced(
uint64 indexed syncedInBlock, uint64 indexed blockId, bytes32 blockHash, bytes32 stateRoot
);

// Warning: Any errors defined here must also be defined in TaikoErrors.sol.
error L1_BLOCK_MISMATCH();
error L1_INVALID_CONFIG();
Expand Down Expand Up @@ -242,20 +238,30 @@ library LibVerifying {
// Update protocol level state variables
state.slotB.lastVerifiedBlockId = lastVerifiedBlockId;

// Store the L2's state root as a signal to the local signal
// service to allow for multi-hop bridging.
//
// This also means if we verified more than one block, only the last one's stateRoot
// 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, LibSignals.STATE_ROOT, stateRoot
);

emit CrossChainSynced(
uint64(block.number), lastVerifiedBlockId, blockHash, stateRoot
);
// sync chain data
_syncChainData(config, resolver, lastVerifiedBlockId, stateRoot);
}
}
}

function _syncChainData(
TaikoData.Config memory config,
AddressResolver resolver,
uint64 lastVerifiedBlockId,
bytes32 stateRoot
)
private
{
ISignalService signalService = ISignalService(resolver.resolve("signal_service", false));

(uint64 lastSyncedBlock,) = signalService.getSyncedChainData(
config.chainId, LibSignals.STATE_ROOT, 0 /* latest block Id*/
);

if (lastVerifiedBlockId > lastSyncedBlock + config.blockSyncThreshold) {
signalService.syncChainData(
config.chainId, LibSignals.STATE_ROOT, lastVerifiedBlockId, stateRoot
);
}
}
}
74 changes: 28 additions & 46 deletions packages/protocol/contracts/L2/TaikoL2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ pragma solidity 0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/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 "../signal/ISignalService.sol";
import "../signal/LibSignals.sol";
import "./Lib1559Math.sol";
import "./CrossChainOwned.sol";

Expand All @@ -31,7 +30,7 @@ import "./CrossChainOwned.sol";
/// It is used to anchor the latest L1 block details to L2 for cross-layer
/// communication, manage EIP-1559 parameters for gas pricing, and store
/// verified L1 block information.
contract TaikoL2 is CrossChainOwned, ICrossChainSync {
contract TaikoL2 is CrossChainOwned {
using LibAddress for address;
using LibMath for uint256;
using SafeERC20 for IERC20;
Expand All @@ -43,18 +42,18 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {

// Golden touch address
address public constant GOLDEN_TOUCH_ADDRESS = 0x0000777735367b36bC9B61C50022d9D0700dB4Ec;
uint8 public constant BLOCK_SYNC_THRESHOLD = 5;
dantaik marked this conversation as resolved.
Show resolved Hide resolved
dantaik marked this conversation as resolved.
Show resolved Hide resolved

// Mapping from L2 block numbers to their block hashes.
// All L2 block hashes will be saved in this mapping.
mapping(uint256 blockId => bytes32 blockHash) public l2Hashes;
mapping(uint256 l1height => ICrossChainSync.Snippet) public snippets;

// A hash to check the integrity of public inputs.
bytes32 public publicInputHash; // slot 3
uint64 public gasExcess; // slot 4
uint64 public latestSyncedL1Height;
bytes32 public publicInputHash; // slot 2
uint64 public gasExcess; // slot 3
uint64 public lastSyncedBlock;

uint256[146] private __gap;
uint256[147] private __gap;

event Anchored(bytes32 parentHash, uint64 gasExcess);

Expand Down Expand Up @@ -102,19 +101,19 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
/// @param l1BlockHash The latest L1 block hash when this block was
/// proposed.
/// @param l1StateRoot The latest L1 block's state root.
/// @param l1Height The latest L1 block height when this block was proposed.
/// @param l1BlockId The latest L1 block height when this block was proposed.
/// @param parentGasUsed The gas used in the parent block.
function anchor(
bytes32 l1BlockHash,
bytes32 l1StateRoot,
uint64 l1Height,
uint64 l1BlockId,
uint32 parentGasUsed
)
external
nonReentrant
{
if (
l1BlockHash == 0 || l1StateRoot == 0 || l1Height == 0
l1BlockHash == 0 || l1StateRoot == 0 || l1BlockId == 0
dantaik marked this conversation as resolved.
Show resolved Hide resolved
|| (block.number != 1 && parentGasUsed == 0)
) {
revert L2_INVALID_PARAM();
Expand All @@ -137,29 +136,23 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {

// Verify the base fee per gas is correct
uint256 basefee;
(basefee, gasExcess) = _calc1559BaseFee(config, l1Height, parentGasUsed);
(basefee, gasExcess) = _calc1559BaseFee(config, l1BlockId, parentGasUsed);
if (!skipFeeCheck() && block.basefee != basefee) {
revert L2_BASEFEE_MISMATCH();
}

// 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, LibSignals.STATE_ROOT, l1StateRoot
);

emit CrossChainSynced(uint64(block.number), l1Height, l1BlockHash, l1StateRoot);

if (l1BlockId > lastSyncedBlock + BLOCK_SYNC_THRESHOLD) {
// 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)).syncChainData(
ownerChainId, LibSignals.STATE_ROOT, l1BlockId, l1StateRoot
);
lastSyncedBlock = l1BlockId;
}
// Update state variables
l2Hashes[parentId] = blockhash(parentId);
snippets[l1Height] = ICrossChainSync.Snippet({
syncedInBlock: uint64(block.number),
blockId: l1Height,
blockHash: l1BlockHash,
stateRoot: l1StateRoot
});
publicInputHash = publicInputHashNew;
latestSyncedL1Height = l1Height;

emit Anchored(blockhash(parentId), gasExcess);
}

Expand All @@ -181,31 +174,20 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
}
}

/// @inheritdoc ICrossChainSync
function getSyncedSnippet(uint64 blockId)
public
view
override
returns (ICrossChainSync.Snippet memory)
{
uint256 id = blockId == 0 ? latestSyncedL1Height : blockId;
return snippets[id];
}

/// @notice Gets the basefee and gas excess using EIP-1559 configuration for
/// the given parameters.
/// @param l1Height The synced L1 height in the next Taiko block
/// @param l1BlockId The synced L1 height in the next Taiko block
/// @param parentGasUsed Gas used in the parent block.
/// @return basefee The calculated EIP-1559 base fee per gas.
function getBasefee(
uint64 l1Height,
uint64 l1BlockId,
uint32 parentGasUsed
)
public
view
returns (uint256 basefee)
{
(basefee,) = _calc1559BaseFee(getConfig(), l1Height, parentGasUsed);
(basefee,) = _calc1559BaseFee(getConfig(), l1BlockId, parentGasUsed);
dantaik marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Retrieves the block hash for the given L2 block number.
Expand Down Expand Up @@ -265,7 +247,7 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {

function _calc1559BaseFee(
Config memory config,
uint64 l1Height,
uint64 l1BlockId,
uint32 parentGasUsed
)
private
Expand All @@ -281,13 +263,13 @@ contract TaikoL2 is CrossChainOwned, ICrossChainSync {
// Calculate how much more gas to issue to offset gas excess.
// after each L1 block time, config.gasTarget more gas is issued,
// the gas excess will be reduced accordingly.
// Note that when latestSyncedL1Height is zero, we skip this step
// Note that when lastSyncedBlock is zero, we skip this step
// because that means this is the first time calculating the basefee
// and the difference between the L1 height would be extremely big,
// reverting the initial gas excess value back to 0.
uint256 numL1Blocks;
if (latestSyncedL1Height > 0 && l1Height > latestSyncedL1Height) {
numL1Blocks = l1Height - latestSyncedL1Height;
if (lastSyncedBlock > 0 && l1BlockId > lastSyncedBlock) {
numL1Blocks = l1BlockId - lastSyncedBlock;
}

if (numL1Blocks > 0) {
Expand Down
46 changes: 0 additions & 46 deletions packages/protocol/contracts/common/ICrossChainSync.sol

This file was deleted.

Loading
Loading