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 missing fields in events #4

Merged
merged 3 commits into from
Aug 22, 2023
Merged
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
5 changes: 3 additions & 2 deletions forge/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl From<ConsensusMessage> for BeefyConsensusProof {
BeefyConsensusProof {
relay: message.mmr.into(),
parachain: ParachainProof {
parachains: message
parachain: message
.parachain
.parachains
.into_iter()
Expand All @@ -21,7 +21,8 @@ impl From<ConsensusMessage> for BeefyConsensusProof {
id: parachain.para_id.into(),
header: parachain.header.into(),
})
.collect(),
.collect::<Vec<_>>()[0]
.clone(),
proof: message
.parachain
.proof
Expand Down
54 changes: 49 additions & 5 deletions src/EvmHost.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ abstract contract EvmHost is IIsmpHost, Context {
// (stateMachineId => (blockHeight => timestamp))
mapping(uint256 => mapping(uint256 => uint256)) private _stateCommitmentsUpdateTime;

uint256 private _latestStateMachineHeight;

// Parameters for the host
HostParams private _hostParams;

Expand All @@ -68,15 +70,31 @@ abstract contract EvmHost is IIsmpHost, Context {
uint256 indexed nonce,
uint256 timeoutTimestamp,
bytes data,
// response
uint256 gaslimit,
bytes response
);

event PostRequestEvent(
bytes source, bytes dest, bytes from, bytes to, uint256 indexed nonce, uint256 timeoutTimestamp, bytes data
bytes source,
bytes dest,
bytes from,
bytes to,
uint256 indexed nonce,
uint256 timeoutTimestamp,
bytes data,
uint256 gaslimit
);

event GetRequestEvent(bytes source, bytes dest, bytes from, uint256 indexed nonce, uint256 timeoutTimestamp);
event GetRequestEvent(
bytes source,
bytes dest,
bytes from,
bytes[] keys,
uint256 indexed nonce,
uint256 height,
uint256 timeoutTimestamp,
uint256 gaslimit
);

modifier onlyAdmin() {
require(_msgSender() == _hostParams.admin, "EvmHost: Only admin");
Expand Down Expand Up @@ -200,6 +218,13 @@ abstract contract EvmHost is IIsmpHost, Context {
return _hostParams.challengePeriod;
}

/**
* @return the latest state machine height
*/
function latestStateMachineHeight() external returns (uint256) {
return _latestStateMachineHeight;
}

/**
* @dev Updates bridge params
* @param params new bridge params
Expand Down Expand Up @@ -228,6 +253,14 @@ abstract contract EvmHost is IIsmpHost, Context {
_hostParams.lastUpdated = time;
}

/**
* @dev Store the latest state machine height
* @param height State Machine Latest Height
*/
function storeLatestStateMachineHeight(uint256 height) external onlyHandler {
_latestStateMachineHeight = height;
}

/**
* @dev Store the commitment at `state height`
*/
Expand Down Expand Up @@ -354,7 +387,8 @@ abstract contract EvmHost is IIsmpHost, Context {
abi.encodePacked(_request.to),
_request.nonce,
_request.timeoutTimestamp,
_request.body
_request.body,
_request.gaslimit
);
}

Expand All @@ -379,7 +413,16 @@ abstract contract EvmHost is IIsmpHost, Context {
bytes32 commitment = Message.hash(_request);
_requestCommitments[commitment] = true;

emit GetRequestEvent(_request.source, _request.dest, _request.from, _request.nonce, _request.timeoutTimestamp);
emit GetRequestEvent(
_request.source,
_request.dest,
_request.from,
_request.keys,
_request.nonce,
request.height,
_request.timeoutTimestamp,
request.gaslimit
);
}

/**
Expand All @@ -401,6 +444,7 @@ abstract contract EvmHost is IIsmpHost, Context {
response.request.nonce,
response.request.timeoutTimestamp,
response.request.body,
response.request.gaslimit,
response.response
);
}
Expand Down
13 changes: 9 additions & 4 deletions src/HandlerV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ contract HandlerV1 is IHandler, Context {
bytes private constant REQUEST_COMMITMENT_STORAGE_PREFIX =
hex"103895530afb23bb607661426d55eb8b0484aecefe882c3ce64e6f82507f715a";

event StateMachineUpdated(uint256 stateMachineId, uint256 height);

/**
* @dev Handle incoming consensus messages
* @param host - Ismp host
Expand All @@ -38,18 +40,21 @@ contract HandlerV1 is IHandler, Context {
"IHandler: still in challenge period"
);

(bytes memory verifiedState, IntermediateState[] memory intermediates) =
(bytes memory verifiedState, IntermediateState memory intermediate) =
IConsensusClient(host.consensusClient()).verifyConsensus(host.consensusState(), proof);
host.storeConsensusState(verifiedState);
host.storeConsensusUpdateTime(host.timestamp());

uint256 commitmentsLen = intermediates.length;
for (uint256 i = 0; i < commitmentsLen; i++) {
IntermediateState memory intermediate = intermediates[i];
if (intermediate.height > host.latestStateMachineHeight()) {
StateMachineHeight memory stateMachineHeight =
StateMachineHeight({stateMachineId: intermediate.stateMachineId, height: intermediate.height});
host.storeStateMachineCommitment(stateMachineHeight, intermediate.commitment);
host.storeStateMachineCommitmentUpdateTime(stateMachineHeight, host.timestamp());
host.storeLatestStateMachineHeight(stateMachineHeight.height);
emit StateMachineUpdated({
stateMachineId: stateMachineHeight.stateMachineId,
height: stateMachineHeight.height
});
}
}

Expand Down
83 changes: 44 additions & 39 deletions src/beefy/BeefyV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct Parachain {
}

struct ParachainProof {
Parachain[] parachains;
Parachain parachain;
Node[][] proof;
}

Expand All @@ -114,32 +114,38 @@ contract BeefyV1 is IConsensusClient {
/// ConsensusID for aura
bytes4 public constant AURA_CONSENSUS_ID = bytes4("aura");

uint256 private _paraId;

constructor(uint256 paraId) {
_paraId = paraId;
}

function verifyConsensus(bytes memory encodedState, bytes memory encodedProof)
external
returns (bytes memory, IntermediateState[] memory)
returns (bytes memory, IntermediateState memory)
{
BeefyConsensusState memory consensusState = abi.decode(encodedState, (BeefyConsensusState));
(RelayChainProof memory relay, ParachainProof memory parachain) =
abi.decode(encodedProof, (RelayChainProof, ParachainProof));

(BeefyConsensusState memory newState, IntermediateState[] memory intermediates) =
(BeefyConsensusState memory newState, IntermediateState memory intermediate) =
this.verifyConsensus(consensusState, BeefyConsensusProof(relay, parachain));

return (abi.encode(newState), intermediates);
return (abi.encode(newState), intermediate);
}

/// Verify the consensus proof and return the new trusted consensus state and any intermediate states finalized
/// by this consensus proof.
function verifyConsensus(BeefyConsensusState memory trustedState, BeefyConsensusProof memory proof)
external
pure
returns (BeefyConsensusState memory, IntermediateState[] memory)
view
returns (BeefyConsensusState memory, IntermediateState memory)
{
// verify mmr root proofs
(BeefyConsensusState memory state, bytes32 headsRoot) = verifyMmrUpdateProof(trustedState, proof.relay);

// verify intermediate state commitment proofs
IntermediateState[] memory intermediate = verifyParachainHeaderProof(headsRoot, proof.parachain);
IntermediateState memory intermediate = verifyParachainHeaderProof(headsRoot, proof.parachain);

return (state, intermediate);
}
Expand Down Expand Up @@ -247,45 +253,44 @@ contract BeefyV1 is IConsensusClient {
/// Verifies that some parachain header has been finalized, given the current trusted consensus state.
function verifyParachainHeaderProof(bytes32 headsRoot, ParachainProof memory proof)
private
pure
returns (IntermediateState[] memory)
view
returns (IntermediateState memory)
{
uint256 headerLen = proof.parachains.length;
IntermediateState[] memory intermediates = new IntermediateState[](headerLen);
Node[] memory leaves = new Node[](headerLen);

for (uint256 i = 0; i < headerLen; i++) {
Parachain memory para = proof.parachains[i];
Header memory header = Codec.DecodeHeader(para.header);
require(header.number != 0, "Genesis block should not be included");
// extract verified metadata from header
bytes32 commitment;
uint256 timestamp;
for (uint256 j = 0; j < header.digests.length; j++) {
if (header.digests[j].isConsensus && header.digests[j].consensus.consensusId == ISMP_CONSENSUS_ID) {
commitment = Bytes.toBytes32(header.digests[j].consensus.data);
}

if (header.digests[j].isPreRuntime && header.digests[j].preruntime.consensusId == AURA_CONSENSUS_ID) {
uint256 slot = ScaleCodec.decodeUint256(header.digests[j].preruntime.data);
timestamp = slot * SLOT_DURATION;
}
}
// require(commitment != bytes32(0), "Request commitment not found!");
require(timestamp != 0, "Request commitment not found!");
Node[] memory leaves = new Node[](1);
Parachain memory para = proof.parachain;
if (para.id != _paraId) {
revert("Unknown paraId");
}

leaves[i] = Node(
para.index,
keccak256(bytes.concat(ScaleCodec.encode32(uint32(para.id)), ScaleCodec.encodeBytes(para.header)))
);
Header memory header = Codec.DecodeHeader(para.header);
require(header.number != 0, "Genesis block should not be included");
// extract verified metadata from header
bytes32 commitment;
uint256 timestamp;
for (uint256 j = 0; j < header.digests.length; j++) {
if (header.digests[j].isConsensus && header.digests[j].consensus.consensusId == ISMP_CONSENSUS_ID) {
commitment = Bytes.toBytes32(header.digests[j].consensus.data);
}

intermediates[i] =
IntermediateState(para.id, header.number, StateCommitment(timestamp, commitment, header.stateRoot));
if (header.digests[j].isPreRuntime && header.digests[j].preruntime.consensusId == AURA_CONSENSUS_ID) {
uint256 slot = ScaleCodec.decodeUint256(header.digests[j].preruntime.data);
timestamp = slot * SLOT_DURATION;
}
}
// require(commitment != bytes32(0), "Request commitment not found!");
require(timestamp != 0, "Request commitment not found!");

leaves[0] = Node(
para.index,
keccak256(bytes.concat(ScaleCodec.encode32(uint32(para.id)), ScaleCodec.encodeBytes(para.header)))
);

IntermediateState memory intermediate =
IntermediateState(para.id, header.number, StateCommitment(timestamp, commitment, header.stateRoot));

require(MerkleMultiProof.VerifyProofSorted(headsRoot, proof.proof, leaves), "Invalid parachains heads proof");

return intermediates;
return intermediate;
}

/// Calculates the mmr leaf index for a block whose parent number is given.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IConsensusClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ interface IConsensusClient {
/// by this consensus proof.
function verifyConsensus(bytes memory trustedState, bytes memory proof)
external
returns (bytes memory, IntermediateState[] memory);
returns (bytes memory, IntermediateState memory);
}
11 changes: 11 additions & 0 deletions src/interfaces/IIsmpHost.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ interface IIsmpHost is IIsmpDispatcher {
*/
function consensusUpdateTime() external returns (uint256);

/**
* @return the latest state machine height
*/
function latestStateMachineHeight() external returns (uint256);

/**
* @return the state of the consensus client
*/
Expand Down Expand Up @@ -114,6 +119,12 @@ interface IIsmpHost is IIsmpDispatcher {
*/
function storeConsensusUpdateTime(uint256 timestamp) external;

/**
* @dev Store the latest state machine height
* @param height State Machine Height
*/
function storeLatestStateMachineHeight(uint256 height) external;

/**
* @dev Store the commitment at `state height`
* @param height state machine height
Expand Down
4 changes: 2 additions & 2 deletions test/Beefy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ contract BeefyConsensusClientTest is Test {
BeefyV1 internal beefy;

function setUp() public virtual {
beefy = new BeefyV1();
beefy = new BeefyV1(2000);
}

function VerifyV1(bytes memory trustedConsensusState, bytes memory proof)
public
returns (bytes memory, IntermediateState[] memory)
returns (bytes memory, IntermediateState memory)
{
return beefy.verifyConsensus(trustedConsensusState, proof);
}
Expand Down
6 changes: 2 additions & 4 deletions test/TestConsensusClient.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import "../src/interfaces/IConsensusClient.sol";
contract TestConsensusClient is IConsensusClient {
function verifyConsensus(bytes memory consensusState, bytes memory proof)
external
returns (bytes memory, IntermediateState[] memory)
returns (bytes memory, IntermediateState memory)
{
IntermediateState memory intermediate = abi.decode(proof, (IntermediateState));
IntermediateState[] memory intermediates = new IntermediateState[](1);
intermediates[0] = intermediate;

return (consensusState, intermediates);
return (consensusState, intermediate);
}
}
Loading