-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(protocol): extract two anchor-related functions (#13199)
- Loading branch information
Showing
48 changed files
with
236 additions
and
241 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ import {EssentialContract} from "../common/EssentialContract.sol"; | |
import {LibZKP} from "../libs/LibZKP.sol"; | ||
import {LibMerkleTrie} from "../thirdparty/LibMerkleTrie.sol"; | ||
|
||
/// @author dantaik <[email protected]> | ||
interface IProofVerifier { | ||
function verifyZKP( | ||
string memory verifierId, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ | |
|
||
pragma solidity ^0.8.18; | ||
|
||
/// @author david <[email protected]> | ||
abstract contract TaikoCustomErrors { | ||
// The following custom errors must match the definitions in other V1 libraries. | ||
error L1_0_FEE_BASE(); | ||
|
@@ -21,6 +20,7 @@ abstract contract TaikoCustomErrors { | |
error L1_ANCHOR_RECEIPT_TOPICS(); | ||
error L1_ANCHOR_SIG_R(); | ||
error L1_ANCHOR_SIG_S(); | ||
error L1_ANCHOR_TX_PROOF(); | ||
error L1_ANCHOR_TYPE(); | ||
error L1_BLOCK_NUMBER(); | ||
error L1_CANNOT_BE_FIRST_PROVER(); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ | |
|
||
pragma solidity ^0.8.18; | ||
|
||
/// @author dantaik <[email protected]> | ||
library TaikoData { | ||
struct Config { | ||
uint256 chainId; | ||
|
@@ -41,7 +40,7 @@ library TaikoData { | |
uint64 proverRewardRandomizedPercentage; | ||
bool enableTokenomics; | ||
bool enablePublicInputsCheck; | ||
bool enableProofValidation; | ||
bool enableAnchorValidation; | ||
bool enableOracleProver; | ||
} | ||
|
||
|
@@ -80,7 +79,9 @@ library TaikoData { | |
// only the latest one if verified in a batch | ||
mapping(uint256 blockId => bytes32 blockHash) l2Hashes; | ||
mapping(uint256 blockId => ProposedBlock proposedBlock) proposedBlocks; | ||
// solhint-disable-next-line max-line-length | ||
mapping(uint256 blockId => mapping(bytes32 parentHash => ForkChoice forkChoice)) forkChoices; | ||
// solhint-disable-next-line max-line-length | ||
mapping(address proposerAddress => mapping(uint256 commitSlot => bytes32 commitHash)) commits; | ||
// Never or rarely changed | ||
uint64 genesisHeight; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,6 @@ pragma solidity ^0.8.18; | |
|
||
import {TaikoData} from "./TaikoData.sol"; | ||
|
||
/// @author david <[email protected]> | ||
abstract contract TaikoEvents { | ||
// The following events must match the definitions in other V1 libraries. | ||
event BlockVerified(uint256 indexed id, bytes32 blockHash); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,9 +19,6 @@ import {LibUtils} from "./libs/LibUtils.sol"; | |
import {LibVerifying} from "./libs/LibVerifying.sol"; | ||
import {AddressResolver} from "../common/AddressResolver.sol"; | ||
|
||
/** | ||
* @author dantaik <[email protected]> | ||
*/ | ||
contract TaikoL1 is | ||
EssentialContract, | ||
IHeaderSync, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,6 @@ import { | |
IERC20Upgradeable | ||
} from "../thirdparty/ERC20Upgradeable.sol"; | ||
|
||
/// @author dantaik <[email protected]> | ||
/// @dev This is Taiko's governance and fee token. | ||
contract TkoToken is EssentialContract, ERC20Upgradeable, IMintableERC20 { | ||
using LibMath for uint256; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ import {LibUtils} from "./LibUtils.sol"; | |
import {TaikoData} from "../TaikoData.sol"; | ||
import {AddressResolver} from "../../common/AddressResolver.sol"; | ||
|
||
/// @author dantaik <[email protected]> | ||
library LibProposing { | ||
using LibTxDecoder for bytes; | ||
using SafeCastUpgradeable for uint256; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,8 +18,6 @@ import {LibRLPWriter} from "../../thirdparty/LibRLPWriter.sol"; | |
import {LibUtils} from "./LibUtils.sol"; | ||
import {TaikoData} from "../../L1/TaikoData.sol"; | ||
|
||
/// @author dantaik <[email protected]> | ||
/// @author david <[email protected]> | ||
library LibProving { | ||
using LibBlockHeader for BlockHeader; | ||
using LibUtils for TaikoData.BlockMetadata; | ||
|
@@ -74,6 +72,7 @@ library LibProving { | |
error L1_ANCHOR_RECEIPT_ADDR(); | ||
error L1_ANCHOR_RECEIPT_TOPICS(); | ||
error L1_ANCHOR_RECEIPT_DATA(); | ||
error L1_ANCHOR_TX_PROOF(); | ||
error L1_HALTED(); | ||
|
||
function proveBlock( | ||
|
@@ -89,9 +88,6 @@ library LibProving { | |
if (inputs.length != 3) revert L1_INPUT_SIZE(); | ||
Evidence memory evidence = abi.decode(inputs[0], (Evidence)); | ||
|
||
bytes calldata anchorTx = inputs[1]; | ||
bytes calldata anchorReceipt = inputs[2]; | ||
|
||
// Check evidence | ||
if (evidence.meta.id != blockId) revert L1_ID(); | ||
|
||
|
@@ -106,59 +102,15 @@ library LibProving { | |
resolver.resolve("proof_verifier", false) | ||
); | ||
|
||
if (config.enableProofValidation) { | ||
// Check anchor tx is valid | ||
LibTxDecoder.Tx memory _tx = LibTxDecoder.decodeTx( | ||
config.chainId, | ||
anchorTx | ||
); | ||
if (_tx.txType != 0) revert L1_ANCHOR_TYPE(); | ||
if ( | ||
_tx.destination != | ||
resolver.resolve(config.chainId, "taiko", false) | ||
) revert L1_ANCHOR_DEST(); | ||
if (_tx.gasLimit != config.anchorTxGasLimit) | ||
revert L1_ANCHOR_GAS_LIMIT(); | ||
|
||
// Check anchor tx's signature is valid and deterministic | ||
_validateAnchorTxSignature(config.chainId, _tx); | ||
|
||
// Check anchor tx's calldata is valid | ||
if ( | ||
!LibBytesUtils.equal( | ||
_tx.data, | ||
bytes.concat( | ||
ANCHOR_TX_SELECTOR, | ||
bytes32(evidence.meta.l1Height), | ||
evidence.meta.l1Hash | ||
) | ||
) | ||
) revert L1_ANCHOR_CALLDATA(); | ||
|
||
// Check anchor tx is the 1st tx in the block | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: anchorTx, | ||
proof: evidence.proofs[zkProofsPerBlock], | ||
root: evidence.header.transactionsRoot | ||
}) | ||
) revert L1_ZKP(); | ||
|
||
// Check anchor tx does not throw | ||
|
||
LibReceiptDecoder.Receipt memory receipt = LibReceiptDecoder | ||
.decodeReceipt(anchorReceipt); | ||
|
||
if (receipt.status != 1) revert L1_ANCHOR_RECEIPT_STATUS(); | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: anchorReceipt, | ||
proof: evidence.proofs[zkProofsPerBlock + 1], | ||
root: evidence.header.receiptsRoot | ||
}) | ||
) revert L1_ANCHOR_RECEIPT_PROOF(); | ||
if (config.enableAnchorValidation) { | ||
_proveAnchorForValidBlock({ | ||
config: config, | ||
resolver: resolver, | ||
proofVerifier: proofVerifier, | ||
evidence: evidence, | ||
anchorTx: inputs[1], | ||
anchorReceipt: inputs[2] | ||
}); | ||
} | ||
|
||
// ZK-prove block and mark block proven to be valid. | ||
|
@@ -189,7 +141,6 @@ library LibProving { | |
inputs[1], | ||
(TaikoData.BlockMetadata) | ||
); | ||
bytes calldata invalidateBlockReceipt = inputs[2]; | ||
|
||
// Check evidence | ||
if (evidence.meta.id != blockId) revert L1_ID(); | ||
|
@@ -200,37 +151,15 @@ library LibProving { | |
resolver.resolve("proof_verifier", false) | ||
); | ||
|
||
// Check the event is the first one in the throw-away block | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: invalidateBlockReceipt, | ||
proof: evidence.proofs[config.zkProofsPerBlock], | ||
root: evidence.header.receiptsRoot | ||
}) | ||
) revert L1_ANCHOR_RECEIPT_PROOF(); | ||
|
||
// Check the 1st receipt is for an InvalidateBlock tx with | ||
// a BlockInvalidated event | ||
LibReceiptDecoder.Receipt memory receipt = LibReceiptDecoder | ||
.decodeReceipt(invalidateBlockReceipt); | ||
if (receipt.status != 1) revert L1_ANCHOR_RECEIPT_STATUS(); | ||
|
||
if (receipt.logs.length != 1) revert L1_ANCHOR_RECEIPT_LOGS(); | ||
|
||
{ | ||
LibReceiptDecoder.Log memory log = receipt.logs[0]; | ||
if ( | ||
log.contractAddress != | ||
resolver.resolve(config.chainId, "taiko", false) | ||
) revert L1_ANCHOR_RECEIPT_ADDR(); | ||
|
||
if (log.data.length != 0) revert L1_ANCHOR_RECEIPT_DATA(); | ||
if ( | ||
log.topics.length != 2 || | ||
log.topics[0] != INVALIDATE_BLOCK_LOG_TOPIC || | ||
log.topics[1] != target.txListHash | ||
) revert L1_ANCHOR_RECEIPT_TOPICS(); | ||
if (config.enableAnchorValidation) { | ||
_proveAnchorForInvalidBlock({ | ||
config: config, | ||
resolver: resolver, | ||
target: target, | ||
proofVerifier: proofVerifier, | ||
evidence: evidence, | ||
invalidateBlockReceipt: inputs[2] | ||
}); | ||
} | ||
|
||
// ZK-prove block and mark block proven as invalid. | ||
|
@@ -393,6 +322,97 @@ library LibProving { | |
}); | ||
} | ||
|
||
function _proveAnchorForValidBlock( | ||
TaikoData.Config memory config, | ||
AddressResolver resolver, | ||
IProofVerifier proofVerifier, | ||
Evidence memory evidence, | ||
bytes calldata anchorTx, | ||
bytes calldata anchorReceipt | ||
) private view { | ||
// Check anchor tx is valid | ||
LibTxDecoder.Tx memory _tx = LibTxDecoder.decodeTx( | ||
config.chainId, | ||
anchorTx | ||
); | ||
if (_tx.txType != 0) revert L1_ANCHOR_TYPE(); | ||
if (_tx.destination != resolver.resolve(config.chainId, "taiko", false)) | ||
revert L1_ANCHOR_DEST(); | ||
if (_tx.gasLimit != config.anchorTxGasLimit) | ||
revert L1_ANCHOR_GAS_LIMIT(); | ||
// Check anchor tx's signature is valid and deterministic | ||
_validateAnchorTxSignature(config.chainId, _tx); | ||
// Check anchor tx's calldata is valid | ||
if ( | ||
!LibBytesUtils.equal( | ||
_tx.data, | ||
bytes.concat( | ||
ANCHOR_TX_SELECTOR, | ||
bytes32(evidence.meta.l1Height), | ||
evidence.meta.l1Hash | ||
) | ||
) | ||
) revert L1_ANCHOR_CALLDATA(); | ||
// Check anchor tx is the 1st tx in the block | ||
|
||
uint256 zkProofsPerBlock = config.zkProofsPerBlock; | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: anchorTx, | ||
proof: evidence.proofs[zkProofsPerBlock], | ||
root: evidence.header.transactionsRoot | ||
}) | ||
) revert L1_ANCHOR_TX_PROOF(); | ||
// Check anchor tx does not throw | ||
LibReceiptDecoder.Receipt memory receipt = LibReceiptDecoder | ||
.decodeReceipt(anchorReceipt); | ||
if (receipt.status != 1) revert L1_ANCHOR_RECEIPT_STATUS(); | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: anchorReceipt, | ||
proof: evidence.proofs[zkProofsPerBlock + 1], | ||
root: evidence.header.receiptsRoot | ||
}) | ||
) revert L1_ANCHOR_RECEIPT_PROOF(); | ||
} | ||
|
||
function _proveAnchorForInvalidBlock( | ||
TaikoData.Config memory config, | ||
AddressResolver resolver, | ||
TaikoData.BlockMetadata memory target, | ||
IProofVerifier proofVerifier, | ||
Evidence memory evidence, | ||
bytes calldata invalidateBlockReceipt | ||
) private view { | ||
if ( | ||
!proofVerifier.verifyMKP({ | ||
key: LibRLPWriter.writeUint(0), | ||
value: invalidateBlockReceipt, | ||
proof: evidence.proofs[config.zkProofsPerBlock], | ||
root: evidence.header.receiptsRoot | ||
}) | ||
) revert L1_ANCHOR_RECEIPT_PROOF(); | ||
// Check the 1st receipt is for an InvalidateBlock tx with | ||
// a BlockInvalidated event | ||
LibReceiptDecoder.Receipt memory receipt = LibReceiptDecoder | ||
.decodeReceipt(invalidateBlockReceipt); | ||
if (receipt.status != 1) revert L1_ANCHOR_RECEIPT_STATUS(); | ||
if (receipt.logs.length != 1) revert L1_ANCHOR_RECEIPT_LOGS(); | ||
LibReceiptDecoder.Log memory log = receipt.logs[0]; | ||
if ( | ||
log.contractAddress != | ||
resolver.resolve(config.chainId, "taiko", false) | ||
) revert L1_ANCHOR_RECEIPT_ADDR(); | ||
if (log.data.length != 0) revert L1_ANCHOR_RECEIPT_DATA(); | ||
if ( | ||
log.topics.length != 2 || | ||
log.topics[0] != INVALIDATE_BLOCK_LOG_TOPIC || | ||
log.topics[1] != target.txListHash | ||
) revert L1_ANCHOR_RECEIPT_TOPICS(); | ||
} | ||
|
||
function _validateAnchorTxSignature( | ||
uint256 chainId, | ||
LibTxDecoder.Tx memory _tx | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,6 @@ import { | |
import {LibMath} from "../../libs/LibMath.sol"; | ||
import {TaikoData} from "../TaikoData.sol"; | ||
|
||
/// @author dantaik <[email protected]> | ||
library LibUtils { | ||
using LibMath for uint256; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ import {TaikoData} from "../../L1/TaikoData.sol"; | |
|
||
/** | ||
* LibVerifying. | ||
* @author dantaik <[email protected]> | ||
*/ | ||
library LibVerifying { | ||
using SafeCastUpgradeable for uint256; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,9 +19,6 @@ import {LibSharedConfig} from "../libs/LibSharedConfig.sol"; | |
import {LibTxDecoder} from "../libs/LibTxDecoder.sol"; | ||
import {TaikoData} from "../L1/TaikoData.sol"; | ||
|
||
/** | ||
* @author dantaik <[email protected]> | ||
*/ | ||
contract TaikoL2 is AddressResolver, ReentrancyGuard, IHeaderSync { | ||
using LibTxDecoder for bytes; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,6 @@ import {LibBridgeStatus} from "./libs/LibBridgeStatus.sol"; | |
* Bridge contract which is deployed on both L1 and L2. Mostly a thin wrapper | ||
* which calls the library implementations. See _IBridge_ for more details. | ||
* @dev The code hash for the same address on L1 and L2 may be different. | ||
* @author dantaik <[email protected]> | ||
*/ | ||
contract Bridge is EssentialContract, IBridge { | ||
using LibBridgeData for Message; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,9 +17,6 @@ import { | |
import {EssentialContract} from "../common/EssentialContract.sol"; | ||
import {ERC20Upgradeable} from "../thirdparty/ERC20Upgradeable.sol"; | ||
|
||
/** | ||
* @author dantaik <[email protected]> | ||
*/ | ||
contract BridgedERC20 is | ||
EssentialContract, | ||
IERC20Upgradeable, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,7 +22,6 @@ import {LibAddress} from "../libs/LibAddress.sol"; | |
* - Is initialized with 2^128 Ether. | ||
* - Allows the contract owner to authorize addresses. | ||
* - Allows authorized addresses to send/release Ether. | ||
* @author dantaik <[email protected]> | ||
*/ | ||
contract EtherVault is EssentialContract { | ||
using LibAddress for address; | ||
|
Oops, something went wrong.