Skip to content

Commit

Permalink
add some proveBlock logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Keszey Dániel authored and Keszey Dániel committed Jul 4, 2024
1 parent 54461ce commit 6147bfe
Show file tree
Hide file tree
Showing 7 changed files with 356 additions and 269 deletions.
44 changes: 29 additions & 15 deletions packages/protocol/contracts/L1/BasedOperator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract BasedOperator is EssentialContract, TaikoErrors {

/// @dev Struct representing transition to be proven.
struct ProofBatch {
TaikoData.BlockMetadata _block;
TaikoData.BlockMetadata blockMetadata;
TaikoData.Transition transition;
ProofData[] proofs;
address prover;
Expand All @@ -53,14 +53,12 @@ contract BasedOperator is EssentialContract, TaikoErrors {
uint256 public constant MAX_BLOCKS_TO_VERIFY = 5;
uint256 public constant PROVING_WINDOW = 1 hours;

TaikoL1 public taiko; // Might change, so maybe better getting these addreses from addressManager (!)
VerifierRegistry public verifierRegistry; // Same as above
address public treasury; // Same as above

mapping(uint256 => Block) public blocks;

function init(address _addressManager) external initializer {
if(_addressManager == address(0)) {
if (_addressManager == address(0)) {
revert L1_INVALID_ADDRESS();
}
__Essential_init(_addressManager);
Expand Down Expand Up @@ -100,25 +98,30 @@ contract BasedOperator is EssentialContract, TaikoErrors {
ProofBatch memory proofBatch = abi.decode(data, (ProofBatch));

// Check who can prove the block
TaikoData.Block memory taikoBlock = TaikoL1(resolve("taiko", false)).getBlock(proofBatch._block.l2BlockNumber);
TaikoData.Block memory taikoBlock =
TaikoL1(resolve("taiko", false)).getBlock(proofBatch.blockMetadata.l2BlockNumber);
if (block.timestamp < taikoBlock.timestamp + PROVING_WINDOW) {
require(
proofBatch.prover == blocks[proofBatch._block.l2BlockNumber].assignedProver,
proofBatch.prover == blocks[proofBatch.blockMetadata.l2BlockNumber].assignedProver,
"assigned prover not the prover"
);
}

VerifierRegistry verifierRegistry = VerifierRegistry(resolve("verifier_registry", false));
TaikoL1 taiko = TaikoL1(resolve("taiko", false));
// Verify the proofs
uint160 prevVerifier = uint160(0);
for (uint256 i = 0; i < proofBatch.proofs.length; i++) {
IVerifier verifier = proofBatch.proofs[i].verifier;
// Make sure each verifier is unique
require(prevVerifier >= uint160(address(verifier)), "duplicated verifier");
if(prevVerifier >= uint160(address(verifier))) {
revert L1_INVALID_OR_DUPLICATE_VERIFIER();
}
// Make sure it's a valid verifier
require(verifierRegistry.isVerifier(address(verifier)), "invalid verifier");
// Verify the proof
verifier.verifyProof(
proofBatch._block,
proofBatch.blockMetadata,
proofBatch.transition,
proofBatch.prover,
proofBatch.proofs[i].proof
Expand All @@ -133,16 +136,27 @@ contract BasedOperator is EssentialContract, TaikoErrors {
// Only allow an already proven block to be overwritten when the verifiers used are now
// invalid
// Get the currently stored transition
TaikoData.TransitionState memory storedTransition =
taiko.getTransition(proofBatch._block.l2BlockNumber, proofBatch.transition.parentHash);
if (storedTransition.blockHash != proofBatch.transition.blockHash) {
// TODO(Brecht): Check that one of the verifiers is now poissoned
} else {
TaikoData.TransitionState memory storedTransition = taiko.getTransition(
proofBatch.blockMetadata.l2BlockNumber, proofBatch.transition.parentHash
);

console2.log("What is stored:");
console2.logBytes32(storedTransition.blockHash);

console2.log("What we are trying to prove:");
console2.logBytes32(proofBatch.transition.blockHash);

// Brecht: SO we set the blockHash in proposeBlock().
// But we need to prove it too (the same one), so somehow we need to check if this is proven already and IF NOT, then revert with "block already proven", no ? So i set the verifiableAfter in propseBlock to 0, because this is just a "proposed state".
if (storedTransition.isProven == true && storedTransition.blockHash == proofBatch.transition.blockHash) {
revert("block already proven");
}
else {
// TODO(Brecht): Check that one of the verifiers is now poissoned
}

// Prove the block
taiko.proveBlock(proofBatch._block, proofBatch.transition, proofBatch.prover);
taiko.proveBlock(proofBatch.blockMetadata, proofBatch.transition, proofBatch.prover);

// Verify some blocks
_verifyBlocks(MAX_BLOCKS_TO_VERIFY);
Expand All @@ -153,7 +167,7 @@ contract BasedOperator is EssentialContract, TaikoErrors {
}

function _verifyBlocks(uint256 maxBlocksToVerify) internal {
taiko = TaikoL1(resolve("taiko", false));
TaikoL1 taiko = TaikoL1(resolve("taiko", false));
uint256 lastVerifiedBlockIdBefore = taiko.getLastVerifiedBlockId();
// Verify the blocks
taiko.verifyBlocks(maxBlocksToVerify);
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/contracts/L1/TaikoData.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ library TaikoData {
uint64 timestamp;
address prover;
uint64 verifiableAfter;
bool isProven;
}

/// @dev Struct containing data required for verifying a block.
Expand Down
1 change: 1 addition & 0 deletions packages/protocol/contracts/L1/TaikoErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ abstract contract TaikoErrors {
error L1_INVALID_CONFIG();
error L1_INVALID_ETH_DEPOSIT();
error L1_INVALID_L1_STATE_BLOCK();
error L1_INVALID_OR_DUPLICATE_VERIFIER();
error L1_INVALID_PARAM();
error L1_INVALID_PAUSE_STATUS();
error L1_INVALID_PROOF();
Expand Down
6 changes: 5 additions & 1 deletion packages/protocol/deployments/deploy_l1.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"address_manager": "0x5991A2dF15A8F6A256D3Ec51E99254Cd3fb576A9",
"based_operator": "0xa0Cb889707d426A7A386870A03bc70d1b0697598",
"sgx1": "0xD6BbDE9174b1CdAa358d2Cf4D57D1a9F7178FBfF",
"sgx2": "0x15cF58144EF33af1e14b5208015d11F9143E27b9",
"sgx3": "0x212224D2F2d262cd093eE13240ca4873fcCBbA3C",
"taiko": "0x2e234DAe75C793f67A35089C9d99245E1C58470b",
"taiko_token": "0xA4AD4f68d0b91CFD19687c881e50f3A00242828c"
"taiko_token": "0x3D7Ebc40AF7092E3F1C81F2e996cbA5Cae2090d7",
"verifier_registry": "0xA4AD4f68d0b91CFD19687c881e50f3A00242828c"
}
63 changes: 37 additions & 26 deletions packages/protocol/test/L1/TaikoL1.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,49 @@ import "./TaikoL1TestBase.sol";

contract TaikoL1Test is TaikoL1TestBase {
function deployTaikoL1() internal override returns (TaikoL1) {
return TaikoL1(
payable(
deployProxy({ name: "taiko", impl: address(new TaikoL1()), data: "" })
)
);
return
TaikoL1(payable(deployProxy({ name: "taiko", impl: address(new TaikoL1()), data: "" })));
}

function test_L1_proposeBlock() external {

giveEthAndTko(Alice, 100 ether, 100 ether);

TaikoData.BlockMetadata memory meta;

vm.roll(block.number+1);
vm.warp(block.timestamp+12);

console2.log(block.number);
meta.blockHash = randBytes32();
meta.parentMetaHash = GENESIS_BLOCK_HASH;
meta.l1Hash = blockhash(block.number - 1);
meta.difficulty = block.prevrandao;
meta.blobHash = randBytes32();
meta.coinbase = Alice;
meta.l2BlockNumber = 1;
meta.gasLimit = 15_000_000;//L1.getConfig().blockMaxGasLimit;
meta.l1StateBlockNumber = uint32(block.number-1);
meta.timestamp = uint64(block.timestamp - 12); // 1 block behind

meta.txListByteOffset = 0;
meta.txListByteSize = 0;
meta.blobUsed = true;

proposeBlock(Alice, Alice, meta);
vm.roll(block.number + 1);
vm.warp(block.timestamp + 12);

// console2.log(block.number);
// meta.blockHash = randBytes32();
// meta.parentMetaHash = GENESIS_BLOCK_HASH;
// meta.l1Hash = blockhash(block.number - 1);
// meta.difficulty = block.prevrandao;
// meta.blobHash = randBytes32();
// meta.coinbase = Alice;
// meta.l2BlockNumber = 1;
// meta.gasLimit = L1.getConfig().blockMaxGasLimit;
// meta.l1StateBlockNumber = uint32(block.number-1);
// meta.timestamp = uint64(block.timestamp - 12); // 1 block behind

// meta.txListByteOffset = 0;
// meta.txListByteSize = 0;
// meta.blobUsed = true;

for (uint64 blockId = 1; blockId <= 1; blockId++) {
printVariables("before propose");
meta = createBlockMetaData(Alice, blockId, 1, true);
proposeBlock(Alice, Alice, meta);
printVariables("after propose");

BasedOperator.ProofBatch memory blockProofs = createProofs(meta, Alice, true);

proveBlock(Alice, abi.encode(blockProofs));

// bytes32 blockHash = bytes32(1e10 + blockId);
// bytes32 stateRoot = bytes32(1e9 + blockId);

// proveBlock(Alice, meta, parentHash, blockHash, stateRoot, meta.minTier, "");
// parentHash = blockHash;
}
}
}
Loading

0 comments on commit 6147bfe

Please sign in to comment.