diff --git a/.husky/pre-commit b/.husky/pre-commit index abd02de196c..c271f69e200 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -pnpm --filter "@taiko/proto" lint-staged +pnpm --filter "@taiko/protocol" lint-staged diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 2305a40abc1..04d59815355 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -284,6 +284,10 @@ contract TaikoL1 is EssentialContract, IHeaderSync, TaikoEvents { return state.forkChoices[id][parentHash].provers; } + function getUncleProofDelay(uint256 blockId) public view returns (uint64) { + return LibUtils.getUncleProofDelay(state, getConfig(), blockId); + } + function getConfig() public pure virtual returns (TaikoData.Config memory) { return LibSharedConfig.getConfig(); } diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index b0afe88b99b..dc384a256c3 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -300,7 +300,7 @@ library LibProving { require( block.timestamp < - LibUtils.uncleProofDeadline({ + LibUtils.getUncleProofDeadline({ state: state, config: config, fc: fc, diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index 84adbc26a63..d581a943596 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -143,20 +143,28 @@ library LibUtils { return (feeBase * gamma) / 1024; } - // Returns a deterministic deadline for uncle proof submission. - function uncleProofDeadline( + function getUncleProofDelay( TaikoData.State storage state, TaikoData.Config memory config, - TaikoData.ForkChoice storage fc, uint256 blockId ) internal view returns (uint64) { if (blockId <= 2 * config.maxNumBlocks) { - return fc.provenAt + config.initialUncleDelay; + return config.initialUncleDelay; } else { - return fc.provenAt + state.avgProofTime; + return state.avgProofTime; } } + // Returns a deterministic deadline for uncle proof submission. + function getUncleProofDeadline( + TaikoData.State storage state, + TaikoData.Config memory config, + TaikoData.ForkChoice storage fc, + uint256 blockId + ) internal view returns (uint64) { + return fc.provenAt + getUncleProofDelay(state, config, blockId); + } + function hashMetadata( TaikoData.BlockMetadata memory meta ) internal pure returns (bytes32) { diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index 406cdf4c029..d44fb4de870 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -238,7 +238,7 @@ library LibVerifying { return fc.blockHash != 0 && block.timestamp > - LibUtils.uncleProofDeadline({ + LibUtils.getUncleProofDeadline({ state: state, config: config, fc: fc, diff --git a/packages/protocol/tasks/deploy_L1.ts b/packages/protocol/tasks/deploy_L1.ts index 3a4aab593ef..ecca9458826 100644 --- a/packages/protocol/tasks/deploy_L1.ts +++ b/packages/protocol/tasks/deploy_L1.ts @@ -85,7 +85,10 @@ export async function deployContracts(hre: any) { const ProofVerifier = await utils.deployContract(hre, "ProofVerifier"); await utils.waitTx( hre, - await AddressManager.setAddress(`${chainId}.proof_verifier`, ProofVerifier.address) + await AddressManager.setAddress( + `${chainId}.proof_verifier`, + ProofVerifier.address + ) ); await utils.waitTx( diff --git a/packages/protocol/test/L1/TaikoL1.test.ts b/packages/protocol/test/L1/TaikoL1.test.ts index 402f9d91f73..2f5b032c21f 100644 --- a/packages/protocol/test/L1/TaikoL1.test.ts +++ b/packages/protocol/test/L1/TaikoL1.test.ts @@ -29,7 +29,7 @@ describe("TaikoL1", function () { await ethers.getContractFactory("LibProving", { libraries: { LibReceiptDecoder: libReceiptDecoder.address, - LibTxDecoder: libTxDecoder.address + LibTxDecoder: libTxDecoder.address, }, }) ).deploy(); @@ -41,16 +41,13 @@ describe("TaikoL1", function () { genesisHash = randomBytes32(); const feeBase = BigNumber.from(10).pow(18); taikoL1 = await ( - await ethers.getContractFactory( - "TestTaikoL1", - { - libraries: { - LibVerifying: libVerifying.address, - LibProposing: libProposing.address, - LibProving: libProving.address, - }, - } - ) + await ethers.getContractFactory("TestTaikoL1", { + libraries: { + LibVerifying: libVerifying.address, + LibProposing: libProposing.address, + LibProving: libProving.address, + }, + }) ).deploy(); await taikoL1.init(addressManager.address, genesisHash, feeBase); }); @@ -85,6 +82,26 @@ describe("TaikoL1", function () { expect(provers).to.be.empty; }); }); + + describe("getDelayForBlockId()", async function () { + it("should return initial uncle delay for block id <= 2 * K_MAX_NUM_BLOCKS", async function () { + const constants = await taikoL1.getConfig(); + const maxNumBlocks = constants[1]; + const delay = await taikoL1.getUncleProofDelay(maxNumBlocks.mul(2)); + const initialUncleDelay = 60; + expect(delay).to.be.eq(initialUncleDelay); + }); + + it("should return avg proof time for block id > 2 * K_MAX_NUM_BLOCKS", async function () { + const constants = await taikoL1.getConfig(); + const maxNumBlocks = constants[1]; + const delay = await taikoL1.getUncleProofDelay( + maxNumBlocks.mul(2).add(1) + ); + const avgProofTime = 0; // no proofs have been generated + expect(delay).to.be.eq(avgProofTime); + }); + }); }); function randomBytes32() { diff --git a/packages/website/docs/smart-contracts/L1/ProofVerifier.md b/packages/website/docs/smart-contracts/L1/ProofVerifier.md new file mode 100644 index 00000000000..b66a43a5ec3 --- /dev/null +++ b/packages/website/docs/smart-contracts/L1/ProofVerifier.md @@ -0,0 +1,27 @@ +## IProofVerifier + +### verifyZKP + +```solidity +function verifyZKP(bytes verificationKey, bytes zkproof, bytes32 blockHash, address prover, bytes32 txListHash) external pure returns (bool verified) +``` + +### verifyMKP + +```solidity +function verifyMKP(bytes key, bytes value, bytes proof, bytes32 root) external pure returns (bool verified) +``` + +## ProofVerifier + +### verifyZKP + +```solidity +function verifyZKP(bytes verificationKey, bytes zkproof, bytes32 blockHash, address prover, bytes32 txListHash) external pure returns (bool) +``` + +### verifyMKP + +```solidity +function verifyMKP(bytes key, bytes value, bytes proof, bytes32 root) external pure returns (bool) +``` diff --git a/packages/website/docs/smart-contracts/L1/TaikoData.md b/packages/website/docs/smart-contracts/L1/TaikoData.md new file mode 100644 index 00000000000..2e9969f0f4d --- /dev/null +++ b/packages/website/docs/smart-contracts/L1/TaikoData.md @@ -0,0 +1,98 @@ +## TaikoData + +### Config + +```solidity +struct Config { + uint256 chainId; + uint256 maxNumBlocks; + uint256 blockHashHistory; + uint256 zkProofsPerBlock; + uint256 maxVerificationsPerTx; + uint256 commitConfirmations; + uint256 maxProofsPerForkChoice; + uint256 blockMaxGasLimit; + uint256 maxTransactionsPerBlock; + uint256 maxBytesPerTxList; + uint256 minTxGasLimit; + uint256 anchorTxGasLimit; + uint256 feePremiumLamda; + uint256 rewardBurnBips; + uint256 proposerDepositPctg; + uint256 feeBaseMAF; + uint256 blockTimeMAF; + uint256 proofTimeMAF; + uint64 rewardMultiplierPctg; + uint64 feeGracePeriodPctg; + uint64 feeMaxPeriodPctg; + uint64 blockTimeCap; + uint64 proofTimeCap; + uint64 boostrapDiscountHalvingPeriod; + uint64 initialUncleDelay; + bool enableTokenomics; +} +``` + +### BlockMetadata + +```solidity +struct BlockMetadata { + uint256 id; + uint256 l1Height; + bytes32 l1Hash; + address beneficiary; + bytes32 txListHash; + bytes32 mixHash; + bytes extraData; + uint64 gasLimit; + uint64 timestamp; + uint64 commitHeight; + uint64 commitSlot; +} +``` + +### ProposedBlock + +```solidity +struct ProposedBlock { + bytes32 metaHash; + uint256 deposit; + address proposer; + uint64 proposedAt; +} +``` + +### ForkChoice + +```solidity +struct ForkChoice { + bytes32 blockHash; + uint64 provenAt; + address[] provers; +} +``` + +### State + +```solidity +struct State { + mapping(uint256 => bytes32) l2Hashes; + mapping(uint256 => struct TaikoData.ProposedBlock) proposedBlocks; + mapping(uint256 => mapping(bytes32 => struct TaikoData.ForkChoice)) forkChoices; + mapping(address => mapping(uint256 => bytes32)) commits; + uint64 genesisHeight; + uint64 genesisTimestamp; + uint64 __reservedA1; + uint64 statusBits; + uint256 feeBase; + uint64 nextBlockId; + uint64 lastProposedAt; + uint64 avgBlockTime; + uint64 __avgGasLimit; + uint64 latestVerifiedHeight; + uint64 latestVerifiedId; + uint64 avgProofTime; + uint64 __reservedC1; + uint256[42] __gap; +} +``` diff --git a/packages/website/docs/smart-contracts/L1/TaikoEvents.md b/packages/website/docs/smart-contracts/L1/TaikoEvents.md new file mode 100644 index 00000000000..aa541532715 --- /dev/null +++ b/packages/website/docs/smart-contracts/L1/TaikoEvents.md @@ -0,0 +1,31 @@ +## TaikoEvents + +### BlockVerified + +```solidity +event BlockVerified(uint256 id, bytes32 blockHash) +``` + +### BlockCommitted + +```solidity +event BlockCommitted(uint64 commitSlot, uint64 commitHeight, bytes32 commitHash) +``` + +### BlockProposed + +```solidity +event BlockProposed(uint256 id, struct TaikoData.BlockMetadata meta) +``` + +### BlockProven + +```solidity +event BlockProven(uint256 id, bytes32 parentHash, bytes32 blockHash, uint64 timestamp, uint64 provenAt, address prover) +``` + +### Halted + +```solidity +event Halted(bool halted) +``` diff --git a/packages/website/docs/smart-contracts/L1/TaikoL1.md b/packages/website/docs/smart-contracts/L1/TaikoL1.md index 3a52bde5cf9..ab79ee24db2 100644 --- a/packages/website/docs/smart-contracts/L1/TaikoL1.md +++ b/packages/website/docs/smart-contracts/L1/TaikoL1.md @@ -6,16 +6,10 @@ struct TaikoData.State state ``` -### tentative - -```solidity -struct TaikoData.TentativeState tentative -``` - ### init ```solidity -function init(address _addressManager, bytes32 _genesisBlockHash) external +function init(address _addressManager, bytes32 _genesisBlockHash, uint256 _feeBase) external ``` ### commitBlock @@ -95,51 +89,6 @@ Verify up to N blocks. | --------- | ------- | ------------------------------- | | maxBlocks | uint256 | Max number of blocks to verify. | -### enableWhitelisting - -```solidity -function enableWhitelisting(bool whitelistProposers, bool whitelistProvers) public -``` - -Enable or disable proposer and prover whitelisting - -#### Parameters - -| Name | Type | Description | -| ------------------ | ---- | ------------------------------------- | -| whitelistProposers | bool | True to enable proposer whitelisting. | -| whitelistProvers | bool | True to enable prover whitelisting. | - -### whitelistProposer - -```solidity -function whitelistProposer(address proposer, bool whitelisted) public -``` - -Add or remove a proposer from the whitelist. - -#### Parameters - -| Name | Type | Description | -| ----------- | ------- | ------------------------------------ | -| proposer | address | The proposer to be added or removed. | -| whitelisted | bool | True to add; remove otherwise. | - -### whitelistProver - -```solidity -function whitelistProver(address prover, bool whitelisted) public -``` - -Add or remove a prover from the whitelist. - -#### Parameters - -| Name | Type | Description | -| ----------- | ------- | ---------------------------------- | -| prover | address | The prover to be added or removed. | -| whitelisted | bool | True to add; remove otherwise. | - ### halt ```solidity @@ -154,46 +103,18 @@ Halt or resume the chain. | ------ | ---- | ------------------------------ | | toHalt | bool | True to halt, false to resume. | -### isProposerWhitelisted +### getBlockFee ```solidity -function isProposerWhitelisted(address proposer) public view returns (bool) +function getBlockFee() public view returns (uint256) ``` -Check whether a proposer is whitelisted. - -#### Parameters - -| Name | Type | Description | -| -------- | ------- | ------------- | -| proposer | address | The proposer. | - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | ----------------------------------------------------- | -| [0] | bool | True if the proposer is whitelisted, false otherwise. | - -### isProverWhitelisted +### getProofReward ```solidity -function isProverWhitelisted(address prover) public view returns (bool) +function getProofReward(uint64 provenAt, uint64 proposedAt) public view returns (uint256 reward) ``` -Check whether a prover is whitelisted. - -#### Parameters - -| Name | Type | Description | -| ------ | ------- | ----------- | -| prover | address | The prover. | - -#### Return Values - -| Name | Type | Description | -| ---- | ---- | --------------------------------------------------- | -| [0] | bool | True if the prover is whitelisted, false otherwise. | - ### isHalted ```solidity @@ -223,7 +144,7 @@ function getProposedBlock(uint256 id) public view returns (struct TaikoData.Prop ### getSyncedHeader ```solidity -function getSyncedHeader(uint256 number) public view returns (bytes32) +function getSyncedHeader(uint256 number) public view returns (bytes32 header) ``` ### getLatestSyncedHeader @@ -235,7 +156,7 @@ function getLatestSyncedHeader() public view returns (bytes32) ### getStateVariables ```solidity -function getStateVariables() public view returns (uint64, uint64, uint64, uint64) +function getStateVariables() public view returns (uint64, uint64, uint64, uint256, uint64, uint64, uint64, uint64, uint64, uint64) ``` ### signWithGoldenTouch @@ -250,8 +171,14 @@ function signWithGoldenTouch(bytes32 hash, uint8 k) public view returns (uint8 v function getBlockProvers(uint256 id, bytes32 parentHash) public view returns (address[]) ``` -### getConstants +### getUncleProofDelay + +```solidity +function getUncleProofDelay(uint256 blockId) public view returns (uint64) +``` + +### getConfig ```solidity -function getConstants() public pure returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256) +function getConfig() public pure virtual returns (struct TaikoData.Config) ``` diff --git a/packages/website/docs/smart-contracts/L2/TaikoL2.md b/packages/website/docs/smart-contracts/L2/TaikoL2.md index a25186c80ba..40aabafe805 100644 --- a/packages/website/docs/smart-contracts/L2/TaikoL2.md +++ b/packages/website/docs/smart-contracts/L2/TaikoL2.md @@ -60,6 +60,12 @@ Invalidate a L2 block by verifying its txList is not intrinsically valid. | hint | enum LibInvalidTxList.Reason | A hint for this method to invalidate the txList. | | txIdx | uint256 | If the hint is for a specific transaction in txList, txIdx specifies which transaction to check. | +### getConfig + +```solidity +function getConfig() public view virtual returns (struct TaikoData.Config config) +``` + ### getSyncedHeader ```solidity @@ -77,9 +83,3 @@ function getLatestSyncedHeader() public view returns (bytes32) ```solidity function getBlockHash(uint256 number) public view returns (bytes32) ``` - -### getConstants - -```solidity -function getConstants() public pure returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256) -```