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

Add deadline and rename to Verifier #4

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {StateProofVerifier as Verifier} from "../libs/StateProofVerifier.sol";

interface IBlockHashOracle {
function get_block_hash(uint256 _number) external view returns (bytes32);
function get_state_root(uint256 _number) external view returns (bytes32);
}

interface IRelayer {
Expand All @@ -17,13 +18,13 @@ interface IRelayer {
function relay(uint256 agent, Message[] calldata messages) external;
}

/// @title Message Digest Prover
/// @title Message Digest Verifier
/// @author Curve Finance
contract MessageDigestProver {
contract MessageDigestVerifier {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;

address constant BROADCASTER = 0x5786696bB5bE7fCDb9997E7f89355d9e97FF8d89;
address constant BROADCASTER = 0x7BA33456EC00812C6B6BB6C1C3dfF579c34CC2cc;
bytes32 constant BROADCASTER_HASH =
keccak256(abi.encodePacked(BROADCASTER));

Expand All @@ -34,31 +35,24 @@ contract MessageDigestProver {
address public immutable BLOCK_HASH_ORACLE;
address public immutable RELAYER;

uint256 public nonce;
mapping (uint256 => uint256) public nonce;

constructor(address _block_hash_oracle, address _relayer) {
BLOCK_HASH_ORACLE = _block_hash_oracle;
RELAYER = _relayer;
}

/// Prove a message digest and optionally execute.
/// Verify a message digest and optionally execute.
/// @param _agent The agent which produced the execution digest. (1 = OWNERSHIP, 2 = PARAMETER, 4 = EMERGENCY)
/// @param _messages The sequence of messages to execute.
/// @param _block_header_rlp The block header of any block in which the gauge has its type set.
/// @param _proof_rlp The state proof of the gauge types.
function prove(
function verifyMessagesByBlockHash(
uint256 _agent,
IRelayer.Message[] memory _messages,
bytes memory _block_header_rlp,
bytes memory _proof_rlp
) external {
require(
_agent == OWNERSHIP_AGENT ||
_agent == PARAMETER_AGENT ||
_agent == EMERGENCY_AGENT
);
require(_messages.length != 0);

Verifier.BlockHeader memory block_header = Verifier.parseBlockHeader(
_block_header_rlp
);
Expand All @@ -70,18 +64,52 @@ contract MessageDigestProver {
)
); // dev: blockhash mismatch

_verifyMessages(_agent, _messages, block_header.stateRootHash, _proof_rlp);
}

/// Verify a message digest and optionally execute.
/// @param _agent The agent which produced the execution digest. (1 = OWNERSHIP, 2 = PARAMETER, 4 = EMERGENCY)
/// @param _messages The sequence of messages to execute.
/// @param _block_number Number of the block to use state root hash.
/// @param _proof_rlp The state proof of the gauge types.
function verifyMessagesByStateRoot(
uint256 _agent,
IRelayer.Message[] memory _messages,
uint256 _block_number,
bytes memory _proof_rlp
) external {
bytes32 state_root = IBlockHashOracle(BLOCK_HASH_ORACLE).get_state_root(_block_number);

_verifyMessages(_agent, _messages, state_root, _proof_rlp);
}

function _verifyMessages(
uint256 _agent,
IRelayer.Message[] memory _messages,
bytes32 _state_root,
bytes memory _proof_rlp
) internal {
require(
_agent == OWNERSHIP_AGENT ||
_agent == PARAMETER_AGENT ||
_agent == EMERGENCY_AGENT
);
require(_messages.length != 0);

// convert _proof_rlp into a list of `RLPItem`s
RLPReader.RLPItem[] memory proofs = _proof_rlp.toRlpItem().toList();
require(proofs.length == 2); // dev: invalid number of proofs
require(proofs.length == 3); // dev: invalid number of proofs

// 0th proof is the account proof for the Broadcaster contract
Verifier.Account memory account = Verifier.extractAccountFromProof(
BROADCASTER_HASH, // position of the account is the hash of its address
block_header.stateRootHash,
_state_root,
proofs[0].toList()
);
require(account.exists); // dev: Broadcaster account does not exist

uint256 cur_nonce = nonce[_agent];

Verifier.SlotValue memory slot = Verifier.extractSlotValueFromProof(
keccak256(
abi.encode(
Expand All @@ -93,7 +121,7 @@ contract MessageDigestProver {
block.chainid
)
),
nonce++
cur_nonce
)
)
)
Expand All @@ -105,6 +133,29 @@ contract MessageDigestProver {
require(slot.exists && slot.value != 0);
require(keccak256(abi.encode(_messages)) == bytes32(slot.value));

IRelayer(RELAYER).relay(_agent, _messages);
uint256 deadline = Verifier.extractSlotValueFromProof(
keccak256(
abi.encode(
keccak256( // self.deadline[_agent][_chain_id][_nonce]
abi.encode(
keccak256( // self.deadline[_agent][_chain_id]
abi.encode(
keccak256(abi.encode(9, _agent)), // self.deadline[_agent]
block.chainid
)
),
cur_nonce
)
)
)
),
account.storageRoot,
proofs[2].toList()
).value;

++nonce[_agent];
if (block.timestamp <= deadline) {
IRelayer(RELAYER).relay(_agent, _messages);
}
}
}
4 changes: 2 additions & 2 deletions scripts/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
CRVUSDLayerZeroBridge,
CRVUSDLayerZeroBridgeETH,
MinterProxy,
MessageDigestProver,
MessageDigestVerifier,
XYZRelayer,
Agent,
history,
Expand Down Expand Up @@ -43,7 +43,7 @@ def main(gauge_type, lz_endpoint, lz_chain_id):
relayer = XYZRelayer.deploy(
agent_blueprint, deployer.get_deployment_address(deployer.nonce + 1), {"from": deployer}
)
MessageDigestProver.deploy(
MessageDigestVerifier.deploy(
deployer.get_deployment_address(deployer.nonce + 1), relayer, {"from": deployer}, publish_source=False
)

Expand Down