diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index c52b01d3476..c4fc51d26a0 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -230,7 +230,6 @@ - [ParachainHeader](#ibc.lightclients.beefy.v1.ParachainHeader) - [PayloadItem](#ibc.lightclients.beefy.v1.PayloadItem) - [SignedCommitment](#ibc.lightclients.beefy.v1.SignedCommitment) - - [TimestampExtrinsic](#ibc.lightclients.beefy.v1.TimestampExtrinsic) - [ibc/lightclients/localhost/v1/localhost.proto](#ibc/lightclients/localhost/v1/localhost.proto) - [ClientState](#ibc.lightclients.localhost.v1.ClientState) @@ -3417,7 +3416,7 @@ data needed to prove parachain header inclusion in mmr. | `parachain_heads_proof` | [bytes](#bytes) | repeated | proofs for our header in the parachain heads root | | `heads_leaf_index` | [uint32](#uint32) | | leaf index for parachain heads proof | | `heads_total_count` | [uint32](#uint32) | | total number of para heads in parachain_heads_root | -| `timestamp` | [TimestampExtrinsic](#ibc.lightclients.beefy.v1.TimestampExtrinsic) | | data needed to provide timestamp for ConsensusState | +| `extrinsic_proof` | [bytes](#bytes) | repeated | trie merkle proof of inclusion in header.extrinsic_root this already encodes the actual extrinsic | @@ -3455,22 +3454,6 @@ signed commitment data - - - -### TimestampExtrinsic -Timestamp extrinsic data - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| `extrinsic_proof` | [bytes](#bytes) | repeated | merkle proof of inclusion in header.extrinsic_root | -| `extrinsic` | [bytes](#bytes) | | actual scale encoded timestamp extrinsic. | - - - - - diff --git a/modules/light-clients/11-beefy/README.md b/modules/light-clients/11-beefy/README.md new file mode 100644 index 00000000000..9052aabd2f8 --- /dev/null +++ b/modules/light-clients/11-beefy/README.md @@ -0,0 +1,45 @@ +# How to run integration tests for 11-Beefy +
+ +### First run the relay chain & parachain nodes: + +
+ +```bash +docker run -ti -p9944:9944 -p9988:9988 -p9998:9998 composablefi/composable-sandbox:latest +``` +
+ +### Then wait until you see this line: +
+ +``` +🚀 POLKADOT LAUNCH COMPLETE 🚀 +``` +
+ +### Now you can run the tests in `./11-beefy/types/update_test.go` +
+ +```bash +go test -test.timeout=0 -run TestCheckHeaderAndUpdateState -v +``` +
+ +### You should start to see these lines: +
+ +```bash +==== connected! ==== +====== subcribed! ====== + + +Initializing client state + + +clientState.LatestBeefyHeight: 169 +clientState.MmrRootHash: 89a2850e8b5e475980ca1ef4c145f4c5624a072d287b85f0430815d5c9b7b387 +====== successfully processed justification! ====== +``` + +### This means the light client is following the relay chain consensus protocol \ No newline at end of file diff --git a/modules/light-clients/11-beefy/spec.md b/modules/light-clients/11-beefy/spec.md index 9ccb94d6835..a4c037edf4d 100644 --- a/modules/light-clients/11-beefy/spec.md +++ b/modules/light-clients/11-beefy/spec.md @@ -1,113 +1,530 @@ -# BEEFY - -Beefy is an extension protocol of Grandpa, which seeks to reduce the size of finality proofs for the sole purpose of bridging the Polkadot/Kusama relay chains and parachains to other blockchains capable of following the BEEFY protocol. - -The BEEFY protocol consists of an extra round of voting on the MMR root hash of all* finalized Grandpa blocks, by same authority set as Grandpa, for the sole purpose of using merkle-mountain range proofs to prove efficiently which blocks have finality. - -BEEFY Leaf data for the MMR is given as: - -```rust - -/// A MMR leaf versioning scheme. -/// -/// Version is a single byte that constist of two components: -/// - `major` - 3 bits -/// - `minor` - 5 bits -/// -/// Any change in encoding that adds new items to the structure is considered non-breaking, hence -/// only requires an update of `minor` version. Any backward incompatible change (i.e. decoding to a -/// previous leaf format fails) should be indicated with `major` version bump. -/// -/// Given that adding new struct elements in SCALE is backward compatible (i.e. old format can be -/// still decoded, the new fields will simply be ignored). We expect the major version to be bumped -/// very rarely (hopefuly never). -#[derive(Debug, Default, PartialEq, Eq, Clone, Encode, Decode)] -pub struct MmrLeafVersion(u8); - -/// A typedef for validator set id. -pub type ValidatorSetId = u64; - -/// Details of the next BEEFY authority set. -#[derive(Debug, Default, PartialEq, Eq, Clone, Encode, Decode, TypeInfo)] -pub struct BeefyNextAuthoritySet { - /// Id of the next set. - /// - /// Id is required to correlate BEEFY signed commitments with the validator set. - /// Light Client can easily verify that the commitment witness it is getting is - /// produced by the latest validator set. - pub id: crate::ValidatorSetId, - /// Number of validators in the set. - /// - /// Some BEEFY Light Clients may use an interactive protocol to verify only subset - /// of signatures. We put set length here, so that these clients can verify the minimal - /// number of required signatures. - pub len: u32, - /// Merkle Root Hash build from BEEFY AuthorityIds. - /// - /// This is used by Light Clients to confirm that the commitments are signed by the correct - /// validator set. Light Clients using interactive protocol, might verify only subset of - /// signatures, hence don't require the full list here (will receive inclusion proofs). - pub root: MerkleRoot, -} - -/// A standard leaf that gets added every block to the MMR constructed by Substrate's `pallet_mmr`. -#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] -pub struct MmrLeaf { - /// Version of the leaf format. - /// - /// Can be used to enable future format migrations and compatibility. - /// See [`MmrLeafVersion`] documentation for details. - pub version: MmrLeafVersion, - /// Current block parent number and hash. - pub parent_number_and_hash: (BlockNumber, Hash), - /// A merkle root of the next BEEFY authority set. - pub beefy_next_authority_set: BeefyNextAuthoritySet, - /// A merkle root of all registered parachain heads. - pub parachain_heads: MerkleRoot, +--- +ics: 11 +title: Beefy Client +stage: draft +category: IBC/TAO +kind: instantiation +implements: 2 +author: Seun Lanlege +created: 2022-03-08 +--- + +## Synopsis + +This specification document describes a client (verification algorithm) for a parachain using Beefy finality gadget + +### Motivation + +Parachains which get their finality from the relay chain (either polkadot/kusama in this case) might like to interface with other replicated state machines or solo machines over IBC. + +### Definitions + +Functions & terms are as defined in [ICS 2](../../core/ics-002-client-semantics). + +`currentTimestamp` is as defined in [ICS 24](../../core/ics-024-host-requirements). + +The Beefy light client uses a custom merkle proof format as described by [paritytech/trie](https://github.com/paritytech/trie) + +`hash` is a generic collision-resistant hash function, and can easily be configured. + +### Desired Properties + +This specification must satisfy the client interface defined in ICS 2. + + +## Technical Specification + + +### Client state + +The Beefy client state tracks the mmr root hash & height of the latest block, current validator set, next validator set, and a possible frozen height. + +```golang +type ClientState struct { + // Latest mmr root hash + MmrRootHash []byte + // block number for the latest mmr_root_hash + LatestBeefyHeight uint32 + // Block height when the client was frozen due to a misbehaviour + FrozenHeight uint64 + // block number that the beefy protocol was activated on the relay chain. + // This shoould be the first block in the merkle-mountain-range tree. + BeefyActivationBlock uint32 + // authorities for the current round + Authority *BeefyAuthoritySet + // authorities for the next round + NextAuthoritySet *BeefyAuthoritySet +} +``` + +### Consensus state + +The Beefy client tracks the timestamp (block time), actual parachain header & commitment root for all Ibc packets committed at this height + +```golang +// ConsensusEngineID is a 4-byte identifier +type ConsensusEngineID [4]byte + +type Consensus struct { + ConsensusEngineID ConsensusEngineID + Bytes []byte +} + +type PreRuntime struct { + ConsensusEngineID ConsensusEngineID + Bytes []byte +} +// DigestItem specifies the item in the logs of a digest +type DigestItem struct { + IsChangesTrieRoot bool // 2 + AsChangesTrieRoot Hash + IsPreRuntime bool // 6 + AsPreRuntime PreRuntime + IsConsensus bool // 4 + AsConsensus Consensus + IsSeal bool // 5 + AsSeal Seal + IsChangesTrieSignal bool // 7 + AsChangesTrieSignal ChangesTrieSignal + IsOther bool // 0 + AsOther []byte +} + +type Digest []DigestItem + +type ParachainHeader struct { + // hash of the parent block + ParentHash [32]byte + // current block number/height + Number uint32 + // merkle root hash of state trie + StateRoot [32]byte + // merkle root hash of all extrisincs in the block + ExtrinsicsRoot [32]byte + // consensus related metadata (aka Consensus Proofs) + Digest Digest +} +// ConsensusState defines the consensus state from Tendermint. +type ConsensusState struct { + // timestamp that corresponds to the block height in which the ConsensusState + // was stored. + Timestamp time.Time + // parachain header + ParachainHeader ParachainHeader +} +``` + +### Headers + +The Beefy client headers include the height, the timestamp, the commitment root, the complete validator set, and the signatures by the validators who committed the block. + +```golang +// Beefy Authority Info +type BeefyAuthoritySet struct { + // Id of the authority set, it should be strictly increasing + Id uint64 + // size of the authority set + Len uint32 + // merkle root of the sorted authority public keys. + AuthorityRoot *[32]byte +} + +// Partial data for MmrLeaf +type BeefyMmrLeafPartial struct { + // leaf version + Version uint8 + // parent block for this leaf + ParentNumber uint32 + // parent hash for this leaf + ParentHash *[32]byte + // next authority set. + BeefyNextAuthoritySet BeefyAuthoritySet +} + + +// data needed to prove parachain header inclusion in mmr. +type ParachainHeader struct { + // scale-encoded parachain header bytes + ParachainHeader []byte + // reconstructed MmrLeaf, see beefy-go spec + MmrLeafPartial *BeefyMmrLeafPartial + // para_id of the header. + ParaId uint32 + // proofs for our header in the parachain heads root + ParachainHeadsProof [][]byte + // leaf index for parachain heads proof + HeadsLeafIndex uint32 + // total number of para heads in parachain_heads_root + HeadsTotalCount uint32 + // trie merkle proof of pallet_timestamp::Call::set() inclusion in header.extrinsic_root + // this already encodes the actual extrinsic + ExtrinsicProof [][]byte +} + +type BeefyMmrLeaf struct { + // leaf version + Version uint8 + // parent block for this leaf + ParentNumber uint32 + // parent hash for this leaf + ParentHash *[32]byte + // beefy next authority set. + BeefyNextAuthoritySet BeefyAuthoritySet + // merkle root hash of parachain heads included in the leaf. + ParachainHeads *[32]byte +} + +// Actual payload items +type PayloadItem struct { + // 2-byte payload id + PayloadId *[2]byte + // arbitrary length payload data., eg mmr_root_hash + PayloadData []byte +} + +// Commitment message signed by beefy validators +type Commitment struct { + // array of payload items signed by Beefy validators + Payload []*PayloadItem + // block number for this commitment + BlockNumer uint32 + // validator set that signed this commitment + ValidatorSetId uint64 +} + +// Signature belonging to a single validator +type CommitmentSignature struct { + // actual signature bytes + Signature [65]byte + // authority leaf index in the merkle tree. + AuthorityIndex uint32 +} + +// signed commitment data +type SignedCommitment struct { + // commitment data being signed + Commitment *Commitment + // gotten from rpc subscription + Signatures []*CommitmentSignature +} + +type MmrUpdateProof struct { + // the new mmr leaf SCALE encoded. + MmrLeaf *BeefyMmrLeaf + // leaf index for the mmr_leaf + MmrLeafIndex uint64 + // proof that this mmr_leaf index is valid. + MmrProof [][]byte + // signed commitment data + SignedCommitment *SignedCommitment + // generated using full authority list from runtime + AuthoritiesProof [][]byte +} + +// Header contains the neccessary data to proove finality about IBC commitments +type Header struct { + // parachain headers needed for proofs and ConsensusState + ParachainHeaders []*ParachainHeader + // mmr proofs for the headers + MmrProofs [][]byte + // size of the mmr for the given proof + MmrSize uint64 + // payload to update the mmr root hash. + MmrUpdateProof MmrUpdateProof +} +``` + +### Client initialisation + +Beefy client initialisation requires a (subjectively chosen) latest beefy height, latest mmr root hash, cureent validator set & the next validator set. + +```golang +func Initialise(MmrRootHash []byte, LatestBeefyHeight uint32,FrozenHeight uint64, BeefyActivationBlock uint32, Authority *BeefyAuthoritySet,NextAuthoritySet *BeefyAuthoritySet) ClientState { + return ClientState { + MmrRootHash: MmrRootHash, + LatestBeefyHeight: LatestBeefyHeight, + FrozenHeight: FrozenHeight, + BeefyActivationBlock: BeefyActivationBlock, + Authority: Authority, + NextAuthoritySet: NextAuthoritySet, + } } ``` +The Beefy client `latestClientHeight` function returns the latest stored height, which is updated every time a new (more recent) header is validated. + +```golang +func (cs *ClientState) latestClientHeight() Height { + return cs.LatestBeefyHeight +} +``` + +### Validity predicate + +Beefy client validity checking happens in two stages, first we check the signatures of the `Commitment`, and use the recovered public keys to reconstruct an authority merkle root, +If this merkle root matches the light client's authority merkle root, we update the `LatestBeefyHeight` and `MmrRootHash` on the client. Optionally rotating our view of the next authority set if the authority set id is higher. + +Next in order to verify if some given parachain headers have been finalized by the Beefy protocol, we attempt to reconstruct each `MmrLeaf` for every parachain header. +This is by reconstructing the `ParachainHeads` field - which contains the merkle root of all parachain headers that have been finalized by the relay chain at this leaf height. +This value, along with the `MmrLeafPartial` will be used to reconstruct the `MmrLeaf`. Then using the [ComposableFi/go-merkle-trees/mmr](https://github.com/composableFi/go-merkle-trees) we can reconstruct the mmr root hash +and compare this with what the light client percieves to the latest root hash. If there's a match, the verified headers are persisted as consensus states to the store. + +```typescript +function checkValidityAndUpdateState( + clientState: ClientState, + revision: uint64, + header: Header +) { + unimplemented() +} +``` + +### Upgrades + +The chain which this light client is tracking can elect to write a special pre-determined key in state to allow the light client to update its client state (e.g. with a new chain ID or revision) in preparation for an upgrade. + +As the client state change will be performed immediately, once the new client state information is written to the predetermined key, the client will no longer be able to follow blocks on the old chain, so it must upgrade promptly. + +```typescript +function upgradeClientState( + clientState: ClientState, + newClientState: ClientState, + height: Height, + proof: CommitmentPrefix) { + // check proof of updated client state in state at predetermined commitment prefix and key + path = applyPrefix(clientState.upgradeCommitmentPrefix, clientState.upgradeKey) + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // verify that the provided consensus state has been stored + assert(root.verifyMembership(path, newClientState, proof)) + // update client state + clientState = newClientState + set("clients/{identifier}", clientState) +} +``` + +### State verification functions + +The Beefy client state verification functions check a Merkle proof against a previously validated commitment root. + +```typescript +function verifyClientConsensusState( + clientState: ClientState, + height: Height, + prefix: CommitmentPrefix, + proof: CommitmentProof, + clientIdentifier: Identifier, + consensusStateHeight: Height, + consensusState: ConsensusState) { + path = applyPrefix(prefix, "clients/{clientIdentifier}/consensusState/{consensusStateHeight}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the provided consensus state has been stored + assert(trie.Get(path) === consensusState) +} + +function verifyConnectionState( + clientState: ClientState, + height: Height, + prefix: CommitmentPrefix, + proof: CommitmentProof, + connectionIdentifier: Identifier, + connectionEnd: ConnectionEnd) { + path = applyPrefix(prefix, "connections/{connectionIdentifier}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the provided connection end has been stored + assert(trie.Get(path) === connectionEnd) +} + +function verifyChannelState( + clientState: ClientState, + height: Height, + prefix: CommitmentPrefix, + proof: CommitmentProof, + portIdentifier: Identifier, + channelIdentifier: Identifier, + channelEnd: ChannelEnd) { + path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the provided channel end has been stored + assert(trie.Get(path) === channelEnd) +} + +function verifyPacketData( + clientState: ClientState, + height: Height, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, + prefix: CommitmentPrefix, + proof: CommitmentProof, + portIdentifier: Identifier, + channelIdentifier: Identifier, + sequence: uint64, + data: bytes) { + path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/packets/{sequence}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the processed time + processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") + // assert that enough time has elapsed + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= processedHeight + delayPeriodBlocks) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the provided commitment has been stored + assert(trie.Get(path) === data) +} + +function verifyPacketAcknowledgement( + clientState: ClientState, + height: Height, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, + prefix: CommitmentPrefix, + proof: CommitmentProof, + portIdentifier: Identifier, + channelIdentifier: Identifier, + sequence: uint64, + acknowledgement: bytes) { + path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/acknowledgements/{sequence}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the processed time + processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") + // assert that enough time has elapsed + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= processedHeight + delayPeriodBlocks) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the provided acknowledgement has been stored + assert(trie.Get(path) === hash(acknowledgement)) +} + +function verifyPacketReceiptAbsence( + clientState: ClientState, + height: Height, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, + prefix: CommitmentPrefix, + proof: CommitmentProof, + portIdentifier: Identifier, + channelIdentifier: Identifier, + sequence: uint64) { + path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/receipts/{sequence}") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the processed time + processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") + // assert that enough time has elapsed + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= processedHeight + delayPeriodBlocks) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that no acknowledgement has been stored + assert(trie.Get(path) === nill) +} + +function verifyNextSequenceRecv( + clientState: ClientState, + height: Height, + delayPeriodTime: uint64, + delayPeriodBlocks: uint64, + prefix: CommitmentPrefix, + proof: CommitmentProof, + portIdentifier: Identifier, + channelIdentifier: Identifier, + nextSequenceRecv: uint64) { + path = applyPrefix(prefix, "ports/{portIdentifier}/channels/{channelIdentifier}/nextSequenceRecv") + // check that the client is at a sufficient height + assert(clientState.latestHeight >= height) + // check that the client is unfrozen or frozen at a higher height + assert(clientState.frozenHeight === null || clientState.frozenHeight > height) + // fetch the processed time + processedTime = get("clients/{identifier}/processedTimes/{height}") + // fetch the processed height + processedHeight = get("clients/{identifier}/processedHeights/{height}") + // assert that enough time has elapsed + assert(currentTimestamp() >= processedTime + delayPeriodTime) + // assert that enough blocks have elapsed + assert(currentHeight() >= processedHeight + delayPeriodBlocks) + // fetch the previously verified commitment root & verify membership + root = get("clients/{identifier}/consensusStates/{height}") + // load proof items into paritytech/trie + trie = trie.NewEmptyTrie().LoadFromProof(proof, root) + // verify that the nextSequenceRecv is as claimed + assert(trie.Get(path) === nextSequenceRecv) +} +``` + +### Properties & Invariants + +Correctness guarantees as provided by the Beefy light client protocol. + +## Backwards Compatibility -In order to follow BEEFY consensus, light clients must be able to reconstruct this MMR leaf in memory and hash it, then using the MMR root hash and merkle mountain range proofs, check for inclusion of this leaf data in the MMR. +Not applicable. +## Forwards Compatibility -# Step 1. Reconstructing `MMRLeaf` +Not applicable. Alterations to the client verification algorithm will require a new client standard. -The relayer that wants to update the state of the light client must provide some additional data to be used to reconstruct the MMRLeaf data for the purpose of hashing and checking for inclusion in the MMR. +## Example Implementation - - `version`, this can be gotten from the runtime - - `parent_number_and_hash`, this can also be gotten from the runtime - - `beefy_next_authority_set` which can be gotten by: - ```rust - // runtime code. - let beefy_next_authority_set = MmrLeaf::beefy_next_authorities() - ``` - - `parachain_heads`, this is where things get a bit tricky. Technically, this is the merkle root hash of a `Vec<(ParaId, HeaderHash)>`. But in order to reconstruct this root hash we'd need - - Our own header hash (This is tricky as well, because we'd like to verify that the messages we're trying to pass across were included in this header, but we'll come back to this.) - - Merkle proof of inclusion of our own header hash in the root_hash of `parachain_heads`. This can be gotten by: +None yet. - ```rust -// runtime code -let para_ids = Paras::parachains(); -let mut para_heads: Vec<(u32, Vec)> = para_ids.iter() - .filter_map(|id| { - Paras::para_head(&id).map(|head| (id.into(), head.0) - }); -para_heads.sort(); -let own_para_head = para_heads.find(|(id, _)| id == OWN_PARA_ID).unwrap(); // unwrap only if we're sure we have a header in thiblock. -let para_heads = para_heads.into_iter().map(|pair| pair.encode()); -let root_hash: H256 = merkle_root(¶_heads); -let proof = merkle_proof(¶_heads, own_para_head); -// such that we should be able to verify -assert!(merkle_verify(root_hash, proof, own_para_head)); +## Other Implementations - ``` -# Step 2. Using MMR to prove inclusion of leaf data in the MMR root hash -// TODO: +None at present. +## History -# Step 3. Verify Signatures of 2/3 + 1 BEEFY authorities. -// TODO: +March 14th, 2022 - Initial version +## Copyright -* Not really all, BEEFY lags behind granpa by a few blocks. \ No newline at end of file +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/modules/light-clients/11-beefy/types/beefy.pb.go b/modules/light-clients/11-beefy/types/beefy.pb.go index fb886cde6bd..4fa8ea3df58 100644 --- a/modules/light-clients/11-beefy/types/beefy.pb.go +++ b/modules/light-clients/11-beefy/types/beefy.pb.go @@ -336,56 +336,6 @@ func (*Misbehaviour) XXX_MessageName() string { return "ibc.lightclients.beefy.v1.Misbehaviour" } -// Timestamp extrinsic data -type TimestampExtrinsic struct { - // merkle proof of inclusion in header.extrinsic_root - ExtrinsicProof [][]byte `protobuf:"bytes,1,rep,name=extrinsic_proof,json=extrinsicProof,proto3" json:"extrinsic_proof,omitempty"` - // actual scale encoded timestamp extrinsic. - Extrinsic []byte `protobuf:"bytes,2,opt,name=extrinsic,proto3" json:"extrinsic,omitempty"` -} - -func (m *TimestampExtrinsic) Reset() { *m = TimestampExtrinsic{} } -func (m *TimestampExtrinsic) String() string { return proto.CompactTextString(m) } -func (*TimestampExtrinsic) ProtoMessage() {} -func (*TimestampExtrinsic) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{8} -} -func (m *TimestampExtrinsic) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TimestampExtrinsic.Unmarshal(m, b) -} -func (m *TimestampExtrinsic) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TimestampExtrinsic.Marshal(b, m, deterministic) -} -func (m *TimestampExtrinsic) XXX_Merge(src proto.Message) { - xxx_messageInfo_TimestampExtrinsic.Merge(m, src) -} -func (m *TimestampExtrinsic) XXX_Size() int { - return xxx_messageInfo_TimestampExtrinsic.Size(m) -} -func (m *TimestampExtrinsic) XXX_DiscardUnknown() { - xxx_messageInfo_TimestampExtrinsic.DiscardUnknown(m) -} - -var xxx_messageInfo_TimestampExtrinsic proto.InternalMessageInfo - -func (m *TimestampExtrinsic) GetExtrinsicProof() [][]byte { - if m != nil { - return m.ExtrinsicProof - } - return nil -} - -func (m *TimestampExtrinsic) GetExtrinsic() []byte { - if m != nil { - return m.Extrinsic - } - return nil -} - -func (*TimestampExtrinsic) XXX_MessageName() string { - return "ibc.lightclients.beefy.v1.TimestampExtrinsic" -} - // Header contains the neccessary data to proove finality about IBC commitments type Header struct { // parachain headers needed for proofs and ConsensusState @@ -402,7 +352,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{9} + return fileDescriptor_43205c4bfbe9a422, []int{8} } func (m *Header) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Header.Unmarshal(m, b) @@ -440,15 +390,16 @@ type ParachainHeader struct { HeadsLeafIndex uint32 `protobuf:"varint,5,opt,name=heads_leaf_index,json=headsLeafIndex,proto3" json:"heads_leaf_index,omitempty"` // total number of para heads in parachain_heads_root HeadsTotalCount uint32 `protobuf:"varint,6,opt,name=heads_total_count,json=headsTotalCount,proto3" json:"heads_total_count,omitempty"` - // data needed to provide timestamp for ConsensusState - Timestamp *TimestampExtrinsic `protobuf:"bytes,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // trie merkle proof of inclusion in header.extrinsic_root + // this already encodes the actual extrinsic + ExtrinsicProof [][]byte `protobuf:"bytes,7,rep,name=extrinsic_proof,json=extrinsicProof,proto3" json:"extrinsic_proof,omitempty"` } func (m *ParachainHeader) Reset() { *m = ParachainHeader{} } func (m *ParachainHeader) String() string { return proto.CompactTextString(m) } func (*ParachainHeader) ProtoMessage() {} func (*ParachainHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{10} + return fileDescriptor_43205c4bfbe9a422, []int{9} } func (m *ParachainHeader) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ParachainHeader.Unmarshal(m, b) @@ -488,7 +439,7 @@ func (m *BeefyMmrLeafPartial) Reset() { *m = BeefyMmrLeafPartial{} } func (m *BeefyMmrLeafPartial) String() string { return proto.CompactTextString(m) } func (*BeefyMmrLeafPartial) ProtoMessage() {} func (*BeefyMmrLeafPartial) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{11} + return fileDescriptor_43205c4bfbe9a422, []int{10} } func (m *BeefyMmrLeafPartial) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeefyMmrLeafPartial.Unmarshal(m, b) @@ -526,7 +477,7 @@ func (m *BeefyAuthoritySet) Reset() { *m = BeefyAuthoritySet{} } func (m *BeefyAuthoritySet) String() string { return proto.CompactTextString(m) } func (*BeefyAuthoritySet) ProtoMessage() {} func (*BeefyAuthoritySet) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{12} + return fileDescriptor_43205c4bfbe9a422, []int{11} } func (m *BeefyAuthoritySet) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeefyAuthoritySet.Unmarshal(m, b) @@ -567,7 +518,7 @@ func (m *BeefyMmrLeaf) Reset() { *m = BeefyMmrLeaf{} } func (m *BeefyMmrLeaf) String() string { return proto.CompactTextString(m) } func (*BeefyMmrLeaf) ProtoMessage() {} func (*BeefyMmrLeaf) Descriptor() ([]byte, []int) { - return fileDescriptor_43205c4bfbe9a422, []int{13} + return fileDescriptor_43205c4bfbe9a422, []int{12} } func (m *BeefyMmrLeaf) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_BeefyMmrLeaf.Unmarshal(m, b) @@ -607,8 +558,6 @@ func init() { golang_proto.RegisterType((*ConsensusState)(nil), "ibc.lightclients.beefy.v1.ConsensusState") proto.RegisterType((*Misbehaviour)(nil), "ibc.lightclients.beefy.v1.Misbehaviour") golang_proto.RegisterType((*Misbehaviour)(nil), "ibc.lightclients.beefy.v1.Misbehaviour") - proto.RegisterType((*TimestampExtrinsic)(nil), "ibc.lightclients.beefy.v1.TimestampExtrinsic") - golang_proto.RegisterType((*TimestampExtrinsic)(nil), "ibc.lightclients.beefy.v1.TimestampExtrinsic") proto.RegisterType((*Header)(nil), "ibc.lightclients.beefy.v1.Header") golang_proto.RegisterType((*Header)(nil), "ibc.lightclients.beefy.v1.Header") proto.RegisterType((*ParachainHeader)(nil), "ibc.lightclients.beefy.v1.ParachainHeader") @@ -629,88 +578,85 @@ func init() { } var fileDescriptor_43205c4bfbe9a422 = []byte{ - // 1313 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x57, 0xcd, 0x6f, 0x1b, 0x45, - 0x14, 0xf7, 0xda, 0x4e, 0x1c, 0x3f, 0x7f, 0xc4, 0x99, 0xb4, 0xe0, 0x96, 0x62, 0xa7, 0x81, 0x52, - 0xb7, 0x25, 0xb6, 0xec, 0x80, 0x84, 0x7a, 0x6a, 0x1d, 0x2a, 0x35, 0x40, 0xa3, 0x6a, 0x53, 0x44, - 0x69, 0x40, 0xd6, 0xd8, 0x3b, 0xb6, 0x47, 0xdd, 0xdd, 0xb1, 0x76, 0xc6, 0x56, 0xd3, 0x3b, 0x12, - 0x07, 0x0e, 0xfd, 0x0f, 0xe8, 0x81, 0x3b, 0x27, 0xee, 0x1c, 0x2b, 0x71, 0xe9, 0x11, 0xf5, 0x10, - 0x50, 0x7c, 0xe3, 0xc8, 0x99, 0x03, 0x9a, 0x8f, 0x5d, 0x6f, 0xdc, 0x60, 0x5a, 0xae, 0xdc, 0x66, - 0xdf, 0xf7, 0xfb, 0xbd, 0x79, 0x6f, 0xde, 0xc2, 0x25, 0xda, 0xed, 0x35, 0x5c, 0x3a, 0x18, 0x8a, - 0x9e, 0x4b, 0x89, 0x2f, 0x78, 0xa3, 0x4b, 0x48, 0xff, 0xb0, 0x31, 0x69, 0xea, 0x43, 0x7d, 0x14, - 0x30, 0xc1, 0xd0, 0x39, 0xda, 0xed, 0xd5, 0xe3, 0x62, 0x75, 0xcd, 0x9d, 0x34, 0xcf, 0x57, 0x06, - 0x8c, 0x0d, 0x5c, 0xd2, 0x50, 0x82, 0xdd, 0x71, 0xbf, 0xe1, 0x8c, 0x03, 0x2c, 0x28, 0xf3, 0xb5, - 0xea, 0xf9, 0xea, 0x3c, 0x5f, 0x50, 0x8f, 0x70, 0x81, 0xbd, 0x91, 0x11, 0x38, 0x33, 0x60, 0x03, - 0xa6, 0x8e, 0x0d, 0x79, 0x32, 0xd4, 0xfc, 0x28, 0x60, 0xac, 0xcf, 0xf5, 0xd7, 0xe6, 0x1f, 0x49, - 0xc8, 0xed, 0x28, 0xcf, 0xfb, 0x02, 0x0b, 0x82, 0x36, 0xa1, 0xe0, 0x79, 0x41, 0x27, 0x60, 0x4c, - 0x74, 0x86, 0x98, 0x0f, 0xcb, 0xd6, 0x86, 0x55, 0xcb, 0xdb, 0x39, 0xcf, 0x0b, 0x6c, 0xc6, 0xc4, - 0x6d, 0xcc, 0x87, 0xa8, 0x0e, 0xeb, 0x2e, 0x16, 0x84, 0x8b, 0x8e, 0x8a, 0xb5, 0x33, 0x24, 0x32, - 0xfe, 0x72, 0x72, 0xc3, 0xaa, 0x15, 0xec, 0x35, 0xcd, 0x6a, 0x4b, 0xce, 0x6d, 0xc5, 0x40, 0xef, - 0x40, 0xa1, 0x1f, 0xb0, 0xc7, 0xc4, 0x0f, 0x25, 0x53, 0x1b, 0x56, 0x2d, 0x6d, 0xe7, 0x35, 0xd1, - 0x08, 0x7d, 0x00, 0x6f, 0x68, 0x6b, 0xb8, 0x27, 0xe8, 0x44, 0xe5, 0xd9, 0xe9, 0xba, 0xac, 0xf7, - 0xb0, 0x9c, 0x56, 0x76, 0xcf, 0x28, 0xee, 0xcd, 0x88, 0xd9, 0x96, 0x3c, 0xf4, 0x09, 0x64, 0xf1, - 0x58, 0x0c, 0x59, 0x40, 0xc5, 0x61, 0x79, 0x69, 0xc3, 0xaa, 0xe5, 0x5a, 0xef, 0xd7, 0xff, 0x11, - 0xd2, 0xba, 0x8a, 0xea, 0x66, 0xa8, 0xb0, 0x4f, 0x84, 0x3d, 0x53, 0x47, 0x0f, 0x00, 0xf9, 0xe4, - 0x91, 0xe8, 0x44, 0x94, 0x0e, 0x27, 0xa2, 0xbc, 0xfc, 0x1f, 0x8c, 0x96, 0xa4, 0x9d, 0x38, 0xe5, - 0x7a, 0xfa, 0xdb, 0xa7, 0xd5, 0xc4, 0x66, 0x17, 0x72, 0x77, 0xf1, 0xa1, 0xcb, 0xb0, 0xb3, 0x2b, - 0x88, 0x87, 0xae, 0x02, 0x8c, 0xf4, 0x67, 0x87, 0x3a, 0x1a, 0xe8, 0x76, 0xee, 0xc5, 0x51, 0x35, - 0x73, 0xd0, 0xfa, 0xba, 0x7b, 0x28, 0x88, 0x9d, 0x35, 0xec, 0x5d, 0x07, 0x5d, 0x84, 0x7c, 0x28, - 0xeb, 0x60, 0x81, 0x15, 0xd8, 0x79, 0x3b, 0x67, 0x68, 0x1f, 0x63, 0x81, 0x8d, 0x8f, 0xef, 0x2d, - 0x80, 0x1d, 0xe6, 0x79, 0x54, 0x78, 0xc4, 0x17, 0xe8, 0x06, 0x64, 0x8c, 0x4c, 0xd9, 0xda, 0x48, - 0xd5, 0x72, 0xad, 0xf7, 0x16, 0x64, 0x12, 0x0b, 0xce, 0x0e, 0xd5, 0x50, 0x15, 0x72, 0xaa, 0x0e, - 0x1d, 0x7f, 0xec, 0x91, 0xc0, 0x54, 0x19, 0x14, 0x69, 0x4f, 0x52, 0x50, 0x0d, 0x4a, 0x13, 0xec, - 0x52, 0x07, 0x0b, 0x16, 0x48, 0xc8, 0x64, 0x32, 0xba, 0xc2, 0xc5, 0x88, 0xbe, 0x4f, 0xc4, 0xae, - 0x13, 0xa1, 0xb0, 0x3e, 0x0b, 0x70, 0x9f, 0x0e, 0x7c, 0x2c, 0xc6, 0x01, 0x41, 0x17, 0x20, 0xcb, - 0xc3, 0x0f, 0x73, 0xeb, 0x66, 0x04, 0x74, 0x19, 0x56, 0x67, 0x75, 0xa1, 0xbe, 0x43, 0x1e, 0x99, - 0x48, 0x8a, 0x11, 0x79, 0x57, 0x52, 0x8d, 0x8f, 0x1f, 0x2d, 0x28, 0x49, 0xd3, 0xc4, 0x89, 0x61, - 0x71, 0x0b, 0xa0, 0x17, 0x7d, 0x29, 0x17, 0xb9, 0xd6, 0xa5, 0x05, 0x70, 0xcc, 0x54, 0xed, 0x98, - 0x22, 0xda, 0x03, 0x88, 0xe2, 0xe2, 0xe5, 0xa4, 0x42, 0xb5, 0xfe, 0x4a, 0x66, 0xa2, 0x64, 0xed, - 0x98, 0x05, 0x13, 0xf1, 0x0f, 0x49, 0x28, 0xde, 0xf1, 0x82, 0xcf, 0x47, 0x0e, 0x16, 0xe4, 0xae, - 0x6c, 0x51, 0xd4, 0x86, 0x15, 0xd9, 0x8b, 0x2e, 0xc1, 0x7d, 0x13, 0xed, 0xe5, 0x7f, 0xbb, 0x86, - 0x77, 0xbc, 0xe0, 0x33, 0x82, 0xfb, 0x76, 0xc6, 0xd3, 0x07, 0xf4, 0x2e, 0x14, 0x43, 0x1b, 0x31, - 0xd8, 0xd2, 0x76, 0xde, 0x08, 0x28, 0xd0, 0xd0, 0x5b, 0x90, 0x95, 0x52, 0x6a, 0x32, 0x94, 0x53, - 0x1b, 0xa9, 0x5a, 0xde, 0x96, 0xae, 0x75, 0x18, 0xf7, 0x61, 0x8d, 0x2b, 0x28, 0x3b, 0x31, 0xf4, - 0xd2, 0x2a, 0x9e, 0x6b, 0x0b, 0xe2, 0x99, 0x87, 0xdf, 0x2e, 0xf1, 0xf9, 0x82, 0x5c, 0x83, 0xb5, - 0xb0, 0x7a, 0x94, 0x70, 0xe3, 0x7e, 0x49, 0xb9, 0x2f, 0xc5, 0x18, 0x2a, 0x0c, 0x03, 0xd3, 0x2f, - 0x16, 0x14, 0x77, 0x98, 0xcf, 0x89, 0xcf, 0xc7, 0x5c, 0x8f, 0xac, 0x36, 0x64, 0xa3, 0xc9, 0x67, - 0x70, 0x3a, 0x5f, 0xd7, 0xb3, 0xb1, 0x1e, 0xce, 0xc6, 0xfa, 0xbd, 0x50, 0xa2, 0xbd, 0xf2, 0xec, - 0xa8, 0x9a, 0x78, 0xf2, 0x5b, 0xd5, 0xb2, 0x67, 0x6a, 0x08, 0x41, 0x5a, 0x8e, 0x3c, 0xd3, 0x56, - 0xea, 0x8c, 0x0e, 0xa0, 0x34, 0xc2, 0x01, 0xee, 0x0d, 0x31, 0x95, 0x93, 0x0b, 0x3b, 0x24, 0x30, - 0x69, 0x5f, 0x5d, 0xd8, 0x43, 0x46, 0xe5, 0xb6, 0xd2, 0x68, 0xa7, 0xa5, 0x3b, 0x7b, 0x75, 0x74, - 0x92, 0x6c, 0xb2, 0x79, 0x6e, 0x41, 0xfe, 0x0e, 0xe5, 0x5d, 0x32, 0xc4, 0x13, 0xca, 0xc6, 0x01, - 0xfa, 0x0a, 0x56, 0xb4, 0xa7, 0x4e, 0x53, 0xc5, 0x92, 0x6b, 0x5d, 0x5c, 0xe0, 0xcb, 0xb8, 0xa8, - 0x1c, 0x1f, 0x55, 0x33, 0xfa, 0xdc, 0xfc, 0xf3, 0xa8, 0xba, 0x7a, 0x88, 0x3d, 0xf7, 0xfa, 0x66, - 0x68, 0x67, 0xd3, 0xce, 0xe8, 0x63, 0x33, 0x66, 0xbd, 0xa5, 0x3a, 0xf4, 0x75, 0xad, 0xb7, 0x5e, - 0xb2, 0xde, 0x8a, 0xac, 0xb7, 0x4c, 0x4a, 0x07, 0x80, 0x22, 0xac, 0x6f, 0x3d, 0x12, 0x01, 0xf5, - 0x39, 0xed, 0xc9, 0xf6, 0x25, 0xe1, 0x87, 0xa9, 0xb3, 0xa5, 0xea, 0x5c, 0x8c, 0xc8, 0xfa, 0xb2, - 0x5d, 0x80, 0x6c, 0x44, 0x31, 0xd5, 0x98, 0x11, 0x36, 0xff, 0xb2, 0x60, 0x59, 0x87, 0x82, 0xbe, - 0x80, 0xb5, 0xf9, 0xea, 0x70, 0x33, 0xe2, 0x5e, 0xa3, 0x3c, 0x76, 0x69, 0xae, 0x30, 0x1c, 0xbd, - 0x0d, 0x10, 0xf5, 0x82, 0x6e, 0xef, 0xbc, 0x9d, 0x0d, 0x9b, 0x81, 0xa3, 0x73, 0xba, 0x29, 0x39, - 0x7d, 0x4c, 0xcc, 0x94, 0x93, 0xbd, 0xb6, 0x4f, 0x1f, 0x13, 0xf4, 0x25, 0x94, 0x24, 0x6b, 0xac, - 0x5a, 0xd8, 0x64, 0xa9, 0x2f, 0xcc, 0x95, 0x05, 0x11, 0x9d, 0x6c, 0x7a, 0x75, 0x5f, 0x2c, 0x5b, - 0x36, 0x6d, 0x8c, 0x6a, 0xb0, 0xfd, 0x2e, 0x05, 0xab, 0x73, 0x09, 0xa0, 0x2b, 0xa7, 0xdc, 0x52, - 0x3d, 0x3d, 0xe7, 0xef, 0x1c, 0xba, 0xaf, 0xe3, 0x53, 0xb3, 0x60, 0x84, 0x03, 0x41, 0xb1, 0x6b, - 0x2e, 0x59, 0xfd, 0x15, 0xe7, 0xca, 0x5d, 0xad, 0xa5, 0xc2, 0x8b, 0x7d, 0xa3, 0x37, 0xe5, 0x2b, - 0x13, 0xe0, 0x70, 0xf2, 0x17, 0xec, 0x65, 0xf9, 0xb9, 0xeb, 0xa0, 0x16, 0x9c, 0x3d, 0x19, 0x1d, - 0x8f, 0x70, 0x91, 0xb8, 0xae, 0x9f, 0x08, 0x51, 0x37, 0xba, 0x7c, 0x4f, 0xb4, 0x64, 0x6c, 0x68, - 0x2d, 0xe9, 0x59, 0xaf, 0xe8, 0xb3, 0xb1, 0x75, 0x15, 0xd6, 0xb4, 0xa4, 0x60, 0x02, 0xbb, 0x9d, - 0x1e, 0x1b, 0xfb, 0xfa, 0xc1, 0x2e, 0xd8, 0xab, 0x8a, 0x71, 0x4f, 0xd2, 0x77, 0x24, 0x19, 0x7d, - 0x1a, 0x9f, 0x12, 0x19, 0x95, 0xf5, 0xd6, 0x82, 0xac, 0x5f, 0xbe, 0xc3, 0xb1, 0x71, 0x61, 0xca, - 0xf1, 0x4d, 0x12, 0xd6, 0x4f, 0x41, 0x07, 0x5d, 0x86, 0xcc, 0x84, 0x04, 0x9c, 0x32, 0x5f, 0x55, - 0xa2, 0xd0, 0x2e, 0xc8, 0x19, 0xf0, 0xe2, 0xa8, 0xba, 0x34, 0xa6, 0xbe, 0xf8, 0xc8, 0x0e, 0xb9, - 0x72, 0x31, 0x1a, 0xe1, 0x80, 0xf8, 0x42, 0xbe, 0xad, 0xdd, 0xe8, 0x71, 0xcd, 0x6b, 0xe2, 0x9e, - 0xa2, 0xa1, 0x2d, 0xc8, 0x19, 0x21, 0xb5, 0x8f, 0xa5, 0xd4, 0x9a, 0x90, 0x7f, 0x71, 0x54, 0x5d, - 0x39, 0xd8, 0x36, 0x7b, 0x02, 0x68, 0x01, 0xb5, 0x9c, 0x3d, 0x84, 0xb2, 0xde, 0xa3, 0x4e, 0xd9, - 0x65, 0xd2, 0xaf, 0xbf, 0xcb, 0x98, 0xf9, 0x75, 0x56, 0x49, 0xec, 0x9d, 0xbe, 0xd6, 0x8c, 0x60, - 0xed, 0x25, 0x3d, 0x54, 0x84, 0xa4, 0x59, 0x6a, 0xd2, 0x76, 0x92, 0x3a, 0xa8, 0x04, 0x29, 0x97, - 0xf8, 0x26, 0x43, 0x79, 0x44, 0xdb, 0x30, 0x7b, 0xbb, 0xd5, 0xc2, 0x79, 0x6a, 0x6e, 0x85, 0x48, - 0x46, 0xee, 0x9f, 0xc6, 0xe3, 0x4f, 0x49, 0xc8, 0xc7, 0x91, 0xff, 0xff, 0x40, 0x8e, 0x3e, 0x84, - 0xd5, 0xb9, 0x8e, 0x52, 0xcd, 0x31, 0x1f, 0x5f, 0xf1, 0x64, 0x67, 0x69, 0xdc, 0xda, 0xfd, 0x67, - 0xc7, 0x95, 0xc4, 0xf3, 0xe3, 0x4a, 0xe2, 0xf7, 0xe3, 0x4a, 0xe2, 0xc9, 0xb4, 0x92, 0x78, 0x3a, - 0xad, 0x24, 0x7e, 0x9e, 0x56, 0xac, 0x67, 0xd3, 0x8a, 0xf5, 0x7c, 0x5a, 0x49, 0xfc, 0x3a, 0xad, - 0x24, 0x1e, 0xdc, 0x18, 0x50, 0x31, 0x1c, 0x77, 0xeb, 0x3d, 0xe6, 0x35, 0x7a, 0x8c, 0x7b, 0x8c, - 0x37, 0x68, 0xb7, 0xb7, 0x35, 0x60, 0x8d, 0xc9, 0x76, 0xc3, 0x63, 0xce, 0xd8, 0x25, 0x5c, 0xff, - 0xda, 0x6c, 0x85, 0xff, 0x36, 0xcd, 0xe6, 0x96, 0xfe, 0xbd, 0x11, 0x87, 0x23, 0xc2, 0xbb, 0xcb, - 0xea, 0xdd, 0xdd, 0xfe, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xb5, 0xb5, 0x7d, 0x2c, 0x05, 0x0d, 0x00, - 0x00, + // 1279 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xf7, 0x3a, 0x4e, 0x9c, 0x3c, 0xff, 0x88, 0x33, 0x69, 0xbf, 0x5f, 0xb7, 0x80, 0x9d, 0x06, + 0x4a, 0xdd, 0x96, 0xd8, 0xb2, 0x03, 0x12, 0xea, 0xa9, 0x75, 0x40, 0x6a, 0x10, 0x8d, 0xaa, 0x49, + 0x11, 0xa5, 0x05, 0x59, 0x63, 0xef, 0xd8, 0x1e, 0x75, 0x77, 0xc7, 0xda, 0x19, 0x5b, 0x4d, 0xef, + 0x48, 0x1c, 0xfb, 0x1f, 0xd0, 0x03, 0x77, 0x4e, 0xdc, 0x39, 0x56, 0xe2, 0xd2, 0x23, 0xea, 0x21, + 0xa0, 0xe4, 0x82, 0x38, 0x72, 0xe6, 0x80, 0xe6, 0xc7, 0xae, 0x37, 0x6e, 0x30, 0x0d, 0x57, 0x6e, + 0xb3, 0xef, 0xe7, 0xe7, 0x7d, 0x66, 0xde, 0x9b, 0x59, 0xb8, 0xcc, 0xba, 0xbd, 0x86, 0xc7, 0x06, + 0x43, 0xd9, 0xf3, 0x18, 0x0d, 0xa4, 0x68, 0x74, 0x29, 0xed, 0x1f, 0x34, 0x26, 0x4d, 0xb3, 0xa8, + 0x8f, 0x42, 0x2e, 0x39, 0xba, 0xc0, 0xba, 0xbd, 0x7a, 0xd2, 0xac, 0x6e, 0xb4, 0x93, 0xe6, 0xc5, + 0xca, 0x80, 0xf3, 0x81, 0x47, 0x1b, 0xda, 0xb0, 0x3b, 0xee, 0x37, 0xdc, 0x71, 0x48, 0x24, 0xe3, + 0x81, 0x71, 0xbd, 0x58, 0x9d, 0xd5, 0x4b, 0xe6, 0x53, 0x21, 0x89, 0x3f, 0xb2, 0x06, 0xe7, 0x06, + 0x7c, 0xc0, 0xf5, 0xb2, 0xa1, 0x56, 0x56, 0x9a, 0x1f, 0x85, 0x9c, 0xf7, 0x85, 0xf9, 0xda, 0xfc, + 0x3d, 0x0d, 0xb9, 0x1d, 0x9d, 0x79, 0x5f, 0x12, 0x49, 0xd1, 0x26, 0x14, 0x7c, 0x3f, 0xec, 0x84, + 0x9c, 0xcb, 0xce, 0x90, 0x88, 0x61, 0xd9, 0xd9, 0x70, 0x6a, 0x79, 0x9c, 0xf3, 0xfd, 0x10, 0x73, + 0x2e, 0x6f, 0x13, 0x31, 0x44, 0x75, 0x58, 0xf7, 0x88, 0xa4, 0x42, 0x76, 0x34, 0xd6, 0xce, 0x90, + 0x2a, 0xfc, 0xe5, 0xf4, 0x86, 0x53, 0x2b, 0xe0, 0x35, 0xa3, 0x6a, 0x2b, 0xcd, 0x6d, 0xad, 0x40, + 0x6f, 0x43, 0xa1, 0x1f, 0xf2, 0x27, 0x34, 0x88, 0x2c, 0x17, 0x36, 0x9c, 0x5a, 0x06, 0xe7, 0x8d, + 0xd0, 0x1a, 0xbd, 0x0f, 0xff, 0x33, 0xd1, 0x48, 0x4f, 0xb2, 0x89, 0xae, 0xb3, 0xd3, 0xf5, 0x78, + 0xef, 0x51, 0x39, 0xa3, 0xe3, 0x9e, 0xd3, 0xda, 0x5b, 0xb1, 0xb2, 0xad, 0x74, 0xe8, 0x13, 0x58, + 0x21, 0x63, 0x39, 0xe4, 0x21, 0x93, 0x07, 0xe5, 0xc5, 0x0d, 0xa7, 0x96, 0x6b, 0xbd, 0x57, 0xff, + 0x5b, 0x4a, 0xeb, 0x1a, 0xd5, 0xad, 0xc8, 0x61, 0x9f, 0x4a, 0x3c, 0x75, 0x47, 0x0f, 0x00, 0x05, + 0xf4, 0xb1, 0xec, 0xc4, 0x92, 0x8e, 0xa0, 0xb2, 0xbc, 0xf4, 0x2f, 0x82, 0x96, 0x54, 0x9c, 0xa4, + 0xe4, 0x46, 0xe6, 0x9b, 0x67, 0xd5, 0xd4, 0x66, 0x17, 0x72, 0x77, 0xc9, 0x81, 0xc7, 0x89, 0xbb, + 0x2b, 0xa9, 0x8f, 0xae, 0x01, 0x8c, 0xcc, 0x67, 0x87, 0xb9, 0x86, 0xe8, 0x76, 0xee, 0xe5, 0x61, + 0x35, 0xfb, 0xb0, 0xf5, 0x55, 0xf7, 0x40, 0x52, 0xbc, 0x62, 0xd5, 0xbb, 0x2e, 0xba, 0x04, 0xf9, + 0xc8, 0xd6, 0x25, 0x92, 0x68, 0xb2, 0xf3, 0x38, 0x67, 0x65, 0x1f, 0x11, 0x49, 0x6c, 0x8e, 0x6f, + 0x1d, 0x80, 0x1d, 0xee, 0xfb, 0x4c, 0xfa, 0x34, 0x90, 0xe8, 0x26, 0x64, 0xad, 0x4d, 0xd9, 0xd9, + 0x58, 0xa8, 0xe5, 0x5a, 0xef, 0xce, 0xa9, 0x24, 0x01, 0x0e, 0x47, 0x6e, 0xa8, 0x0a, 0x39, 0xbd, + 0x0f, 0x9d, 0x60, 0xec, 0xd3, 0xd0, 0xee, 0x32, 0x68, 0xd1, 0x9e, 0x92, 0xa0, 0x1a, 0x94, 0x26, + 0xc4, 0x63, 0x2e, 0x91, 0x3c, 0x54, 0x94, 0xa9, 0x62, 0xcc, 0x0e, 0x17, 0x63, 0xf9, 0x3e, 0x95, + 0xbb, 0x6e, 0xcc, 0xc2, 0xfa, 0x14, 0xe0, 0x3e, 0x1b, 0x04, 0x44, 0x8e, 0x43, 0x8a, 0xde, 0x84, + 0x15, 0x11, 0x7d, 0xd8, 0x53, 0x37, 0x15, 0xa0, 0x2b, 0xb0, 0x3a, 0xdd, 0x17, 0x16, 0xb8, 0xf4, + 0xb1, 0x45, 0x52, 0x8c, 0xc5, 0xbb, 0x4a, 0x6a, 0x73, 0x7c, 0xef, 0x40, 0x49, 0x85, 0xa6, 0x6e, + 0x82, 0x8b, 0x8f, 0x01, 0x7a, 0xf1, 0x97, 0x4e, 0x91, 0x6b, 0x5d, 0x9e, 0x43, 0xc7, 0xd4, 0x15, + 0x27, 0x1c, 0xd1, 0x1e, 0x40, 0x8c, 0x4b, 0x94, 0xd3, 0x9a, 0xd5, 0xfa, 0x6b, 0x85, 0x89, 0x8b, + 0xc5, 0x89, 0x08, 0x16, 0xf1, 0x77, 0x69, 0x28, 0xde, 0xf1, 0xc3, 0xcf, 0x46, 0x2e, 0x91, 0xf4, + 0xae, 0x6a, 0x51, 0xd4, 0x86, 0x65, 0xd5, 0x8b, 0x1e, 0x25, 0x7d, 0x8b, 0xf6, 0xca, 0x3f, 0x1d, + 0xc3, 0x3b, 0x7e, 0xf8, 0x29, 0x25, 0x7d, 0x9c, 0xf5, 0xcd, 0x02, 0xbd, 0x03, 0xc5, 0x28, 0x46, + 0x82, 0xb6, 0x0c, 0xce, 0x5b, 0x03, 0x4d, 0x1a, 0x7a, 0x03, 0x56, 0x94, 0x95, 0x9e, 0x0c, 0xe5, + 0x85, 0x8d, 0x85, 0x5a, 0x1e, 0xab, 0xd4, 0x06, 0xc6, 0x7d, 0x58, 0x13, 0x9a, 0xca, 0x4e, 0x82, + 0xbd, 0x8c, 0xc6, 0x73, 0x7d, 0x0e, 0x9e, 0x59, 0xfa, 0x71, 0x49, 0xcc, 0x6e, 0xc8, 0x75, 0x58, + 0x8b, 0x76, 0x8f, 0x51, 0x61, 0xd3, 0x2f, 0xea, 0xf4, 0xa5, 0x84, 0x42, 0xc3, 0xb0, 0x34, 0xfd, + 0xe4, 0x40, 0x71, 0x87, 0x07, 0x82, 0x06, 0x62, 0x2c, 0xcc, 0xc8, 0x6a, 0xc3, 0x4a, 0x3c, 0xf9, + 0x2c, 0x4f, 0x17, 0xeb, 0x66, 0x36, 0xd6, 0xa3, 0xd9, 0x58, 0xbf, 0x17, 0x59, 0xb4, 0x97, 0x9f, + 0x1f, 0x56, 0x53, 0x4f, 0x7f, 0xa9, 0x3a, 0x78, 0xea, 0x86, 0x10, 0x64, 0xd4, 0xc8, 0xb3, 0x6d, + 0xa5, 0xd7, 0xe8, 0x21, 0x94, 0x46, 0x24, 0x24, 0xbd, 0x21, 0x61, 0x6a, 0x72, 0x11, 0x97, 0x86, + 0xb6, 0xec, 0x6b, 0x73, 0x7b, 0xc8, 0xba, 0xdc, 0xd6, 0x1e, 0xed, 0x8c, 0x4a, 0x87, 0x57, 0x47, + 0x27, 0xc5, 0xb6, 0x9a, 0x17, 0x0e, 0xe4, 0xef, 0x30, 0xd1, 0xa5, 0x43, 0x32, 0x61, 0x7c, 0x1c, + 0xa2, 0x2f, 0x61, 0xd9, 0x64, 0xea, 0x34, 0x35, 0x96, 0x5c, 0xeb, 0xd2, 0x9c, 0x5c, 0x36, 0x45, + 0xe5, 0xe8, 0xb0, 0x9a, 0x35, 0xeb, 0xe6, 0x1f, 0x87, 0xd5, 0xd5, 0x03, 0xe2, 0x7b, 0x37, 0x36, + 0xa3, 0x38, 0x9b, 0x38, 0x6b, 0x96, 0xcd, 0x44, 0xf4, 0x96, 0xee, 0xd0, 0xb3, 0x46, 0x6f, 0xbd, + 0x12, 0xbd, 0x15, 0x47, 0x6f, 0xd9, 0x92, 0xfe, 0x74, 0x60, 0xc9, 0x58, 0xa3, 0xcf, 0x61, 0x6d, + 0x96, 0x40, 0x61, 0xa7, 0xd0, 0x19, 0x18, 0xc4, 0xa5, 0x19, 0xee, 0x04, 0x7a, 0x0b, 0x20, 0x3e, + 0xae, 0xa6, 0x03, 0xf3, 0x78, 0x25, 0x3a, 0xaf, 0x02, 0x5d, 0x30, 0x7d, 0x23, 0xd8, 0x13, 0x6a, + 0x07, 0x91, 0x6a, 0x87, 0x7d, 0xf6, 0x84, 0xa2, 0x2f, 0xa0, 0xa4, 0x54, 0x63, 0xdd, 0x65, 0xf6, + 0xc0, 0x99, 0x3d, 0xbd, 0x3a, 0x07, 0xd1, 0xc9, 0xbe, 0xd4, 0x5b, 0xea, 0x60, 0xd5, 0x57, 0x09, + 0xa9, 0x2d, 0xff, 0xb7, 0x34, 0xac, 0xce, 0x14, 0x80, 0xae, 0x9e, 0x72, 0x90, 0xcc, 0x80, 0x9b, + 0x3d, 0x16, 0xe8, 0xbe, 0xc1, 0xa7, 0xdb, 0x75, 0x44, 0x42, 0xc9, 0x88, 0x67, 0xcf, 0x41, 0xfd, + 0x35, 0x5b, 0xff, 0xae, 0xf1, 0xd2, 0xf0, 0x12, 0xdf, 0xe8, 0xff, 0xea, 0x22, 0x08, 0x49, 0x34, + 0x9c, 0x0b, 0x78, 0x49, 0x7d, 0xee, 0xba, 0xa8, 0x05, 0xe7, 0x4f, 0xa2, 0x13, 0x31, 0x2f, 0x8a, + 0xd7, 0xf5, 0x13, 0x10, 0x4d, 0x2f, 0xaa, 0x91, 0x6f, 0x2c, 0x13, 0x73, 0x65, 0xd1, 0x8c, 0x63, + 0x2d, 0x9f, 0x4e, 0x96, 0x6b, 0xb0, 0x66, 0x2c, 0x25, 0x97, 0xc4, 0xeb, 0xf4, 0xf8, 0x38, 0x30, + 0x77, 0x6a, 0x01, 0xaf, 0x6a, 0xc5, 0x3d, 0x25, 0xdf, 0x51, 0x62, 0x35, 0xe3, 0xe9, 0x63, 0x19, + 0xb2, 0x40, 0xb0, 0x9e, 0xc5, 0x90, 0xd5, 0x18, 0x8a, 0xb1, 0x38, 0x49, 0xf5, 0xd7, 0x69, 0x58, + 0x3f, 0xa5, 0x72, 0x74, 0x05, 0xb2, 0x13, 0x1a, 0x0a, 0xc6, 0x03, 0xcd, 0x72, 0xa1, 0x5d, 0x50, + 0x2d, 0xf8, 0xf2, 0xb0, 0xba, 0x38, 0x66, 0x81, 0xfc, 0x10, 0x47, 0x5a, 0xf5, 0x2e, 0x19, 0x91, + 0x90, 0x06, 0x52, 0x5d, 0x6d, 0xdd, 0xf8, 0x6e, 0xcb, 0x1b, 0xe1, 0x9e, 0x96, 0xa1, 0x2d, 0xc8, + 0x59, 0x23, 0xfd, 0x1c, 0x5a, 0xd0, 0xb7, 0x74, 0xfe, 0xe5, 0x61, 0x75, 0xf9, 0xe1, 0xb6, 0xbd, + 0xa6, 0xc1, 0x18, 0xe8, 0xb7, 0xd1, 0x23, 0x28, 0x9b, 0x67, 0xcc, 0x29, 0x4f, 0x89, 0xcc, 0xd9, + 0x9f, 0x12, 0x76, 0x7c, 0x9c, 0xd7, 0x16, 0x7b, 0xa7, 0xbf, 0x2a, 0x46, 0xb0, 0xf6, 0x8a, 0x1f, + 0x2a, 0x42, 0xda, 0xbe, 0x29, 0x32, 0x38, 0xcd, 0x5c, 0x54, 0x82, 0x05, 0x8f, 0x06, 0xb6, 0x42, + 0xb5, 0x44, 0xdb, 0x30, 0xbd, 0x3a, 0xf5, 0x7b, 0xef, 0xd4, 0xda, 0x0a, 0xb1, 0x8d, 0x7a, 0xfe, + 0xd9, 0x8c, 0x3f, 0xa4, 0x21, 0x9f, 0x64, 0xfe, 0xbf, 0x43, 0x39, 0xfa, 0x00, 0x56, 0x67, 0xba, + 0x45, 0x1f, 0xfc, 0x59, 0x7c, 0xc5, 0x93, 0x5d, 0x63, 0x78, 0x6b, 0xf7, 0x9f, 0x1f, 0x55, 0x52, + 0x2f, 0x8e, 0x2a, 0xa9, 0x5f, 0x8f, 0x2a, 0xa9, 0xa7, 0xc7, 0x95, 0xd4, 0xb3, 0xe3, 0x4a, 0xea, + 0xc7, 0xe3, 0x8a, 0xf3, 0xfc, 0xb8, 0xe2, 0xbc, 0x38, 0xae, 0xa4, 0x7e, 0x3e, 0xae, 0xa4, 0x1e, + 0xdc, 0x1c, 0x30, 0x39, 0x1c, 0x77, 0xeb, 0x3d, 0xee, 0x37, 0x7a, 0x5c, 0xf8, 0x5c, 0x34, 0x58, + 0xb7, 0xb7, 0x35, 0xe0, 0x8d, 0xc9, 0x76, 0xc3, 0xe7, 0xee, 0xd8, 0xa3, 0xc2, 0xfc, 0x59, 0x6c, + 0x45, 0xbf, 0x16, 0xcd, 0xe6, 0x96, 0xf9, 0xbb, 0x90, 0x07, 0x23, 0x2a, 0xba, 0x4b, 0xfa, 0xda, + 0xdb, 0xfe, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x6f, 0x9c, 0xf3, 0x84, 0x0c, 0x00, 0x00, } diff --git a/modules/light-clients/11-beefy/types/header.go b/modules/light-clients/11-beefy/types/header.go index 9b9010f550f..b7581965789 100644 --- a/modules/light-clients/11-beefy/types/header.go +++ b/modules/light-clients/11-beefy/types/header.go @@ -3,14 +3,12 @@ package types import ( "bytes" "encoding/binary" - "fmt" "time" "github.com/ChainSafe/gossamer/lib/trie" "github.com/ComposableFi/go-substrate-rpc-client/v4/scale" - "github.com/ComposableFi/go-substrate-rpc-client/v4/types" - substrateTypes "github.com/ComposableFi/go-substrate-rpc-client/v4/types" - clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" + substrate "github.com/ComposableFi/go-substrate-rpc-client/v4/types" + ics02 "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" "github.com/cosmos/ibc-go/v3/modules/core/exported" ) @@ -20,19 +18,19 @@ const revisionNumber = 0 // DecodeParachainHeader decodes an encoded substrate header to a concrete Header type. It takes encoded bytes // as an argument and returns a concrete substrate Header type. -func DecodeParachainHeader(hb []byte) (substrateTypes.Header, error) { - h := substrateTypes.Header{} - err := types.DecodeFromBytes(hb, &h) +func DecodeParachainHeader(hb []byte) (substrate.Header, error) { + h := substrate.Header{} + err := substrate.DecodeFromBytes(hb, &h) if err != nil { - return substrateTypes.Header{}, err + return substrate.Header{}, err } return h, nil } // DecodeExtrinsicTimestamp decodes a scale encoded timestamp to a time.Time type func DecodeExtrinsicTimestamp(encodedExtrinsic []byte) (time.Time, error) { - var extrinsic substrateTypes.Extrinsic - decodeErr := types.DecodeFromBytes(encodedExtrinsic, &extrinsic) + var extrinsic substrate.Extrinsic + decodeErr := substrate.DecodeFromBytes(encodedExtrinsic, &extrinsic) if decodeErr != nil { return time.Time{}, decodeErr } @@ -58,14 +56,12 @@ func (h Header) ConsensusState() *ConsensusState { log.Fatal(err) } - timestamp, err := DecodeExtrinsicTimestamp(h.ParachainHeaders[0].Timestamp.Extrinsic) if err != nil { log.Fatal(err) } return &ConsensusState{ - Root: rootHash, - Timestamp: timestamp, + Root: rootHash, } } @@ -82,7 +78,7 @@ func (h Header) GetHeight() exported.Height { if err != nil { log.Fatal(err) } - return clienttypes.NewHeight(revisionNumber, uint64(parachainHeader.Number)) + return ics02.NewHeight(revisionNumber, uint64(parachainHeader.Number)) } // ValidateBasic calls the SignedHeader ValidateBasic function and checks @@ -96,25 +92,21 @@ func (h Header) ValidateBasic() error { return err } - _, err = DecodeExtrinsicTimestamp(h.ParachainHeaders[0].Timestamp.Extrinsic) - if err != nil { - return err - } - rootHash := decHeader.ExtrinsicsRoot[:] - extrinsicsProof := header.Timestamp.ExtrinsicProof - extrinsic := header.Timestamp.Extrinsic + extrinsicsProof := header.ExtrinsicProof key := make([]byte, 4) binary.LittleEndian.PutUint32(key, 0) - isVerified, err := trie.VerifyProof(extrinsicsProof, rootHash, []trie.Pair{{Key: key, Value: extrinsic}}) - if err != nil { - return fmt.Errorf("error verifying proof: %v", err.Error()) + trie := trie.NewEmptyTrie() + if err := trie.LoadFromProof(extrinsicsProof, rootHash); err != nil { + return err } - if !isVerified { - return fmt.Errorf("unable to verify extrinsic inclusion") + if ext := trie.Get(key); len(ext) == 0 { + // todo: error } + + // todo: decode extrinsic. } return nil diff --git a/modules/light-clients/11-beefy/types/update.go b/modules/light-clients/11-beefy/types/update.go index ac548082ae6..53079367f54 100644 --- a/modules/light-clients/11-beefy/types/update.go +++ b/modules/light-clients/11-beefy/types/update.go @@ -17,11 +17,6 @@ import ( type Keccak256 struct{} -type ParaIdAndHead struct { - ParaId uint32 - Header []byte -} - func (b Keccak256) Merge(left, right interface{}) interface{} { l := left.([]byte) r := right.([]byte) @@ -77,7 +72,7 @@ func (cs *ClientState) CheckHeaderAndUpdateState( if beefyHeader.MmrUpdateProof != nil { var ( mmrUpdateProof = beefyHeader.MmrUpdateProof - proof = beefyHeader.MmrUpdateProof.AuthoritiesProof + authoritiesProof = beefyHeader.MmrUpdateProof.AuthoritiesProof signedCommitment = beefyHeader.MmrUpdateProof.SignedCommitment ) @@ -137,7 +132,7 @@ func (cs *ClientState) CheckHeaderAndUpdateState( case cs.Authority.Id: // here we construct a merkle proof, and verify that the public keys which produced this signature // are part of the current round. - authoritiesProof := merkle.NewProof(authorityLeaves, proof, cs.Authority.Len, Keccak256{}) + authoritiesProof := merkle.NewProof(authorityLeaves, authoritiesProof, cs.Authority.Len, Keccak256{}) valid, err := authoritiesProof.Verify(cs.Authority.AuthorityRoot[:]) if err != nil || !valid { // todo: error unknown authority set! @@ -146,7 +141,7 @@ func (cs *ClientState) CheckHeaderAndUpdateState( // new authority set has kicked in case cs.NextAuthoritySet.Id: - authoritiesProof := merkle.NewProof(authorityLeaves, proof, cs.NextAuthoritySet.Len, Keccak256{}) + authoritiesProof := merkle.NewProof(authorityLeaves, authoritiesProof, cs.NextAuthoritySet.Len, Keccak256{}) valid, err := authoritiesProof.Verify(cs.NextAuthoritySet.AuthorityRoot[:]) if err != nil || !valid { // todo: error unknown authority set! @@ -198,7 +193,8 @@ func (cs *ClientState) CheckHeaderAndUpdateState( } var mmrLeaves = make([]mmr.Leaf, len(beefyHeader.ParachainHeaders)) - var paraHeads = make([][]byte, len(beefyHeader.ParachainHeaders)) + // for debug purposes + var mmrLeavesRaw = make([]BeefyMmrLeaf, len(beefyHeader.ParachainHeaders)) // verify parachain headers for i := 0; i < len(beefyHeader.ParachainHeaders); i++ { @@ -238,7 +234,8 @@ func (cs *ClientState) CheckHeaderAndUpdateState( }, ParachainHeads: &ParachainHeads, } - paraHeads[i] = ParachainHeadsRoot + // for debug purposes + mmrLeavesRaw[i] = mmrLeaf // the mmr leafs are a scale-encoded mmrLeafBytes, err := Encode(mmrLeaf) diff --git a/modules/light-clients/11-beefy/types/update_test.go b/modules/light-clients/11-beefy/types/update_test.go index bb42f703b4f..7ed4cf5ed0c 100644 --- a/modules/light-clients/11-beefy/types/update_test.go +++ b/modules/light-clients/11-beefy/types/update_test.go @@ -31,7 +31,7 @@ const PARA_ID = 2000 func TestCheckHeaderAndUpdateState(t *testing.T) { - relayApi, err := client.NewSubstrateAPI("ws://127.0.0.1:65353") + relayApi, err := client.NewSubstrateAPI("ws://127.0.0.1:9944") if err != nil { panic(err) } @@ -179,7 +179,7 @@ func TestCheckHeaderAndUpdateState(t *testing.T) { panic(err) } - // double map that holds block numbers, for which our parachain header + // double map that holds block numbers, for which parachain header // was included in the mmr leaf, seeing as our parachain headers might not make it into // every relay chain block. // Map> diff --git a/proto/ibc/lightclients/beefy/v1/beefy.proto b/proto/ibc/lightclients/beefy/v1/beefy.proto index 40c5716e5b1..d6e512ad2fc 100644 --- a/proto/ibc/lightclients/beefy/v1/beefy.proto +++ b/proto/ibc/lightclients/beefy/v1/beefy.proto @@ -130,15 +130,6 @@ message Misbehaviour { Header header_2 = 3 [(gogoproto.customname) = "Header2", (gogoproto.moretags) = "yaml:\"header_2\""]; } -// Timestamp extrinsic data -message TimestampExtrinsic { - // merkle proof of inclusion in header.extrinsic_root - repeated bytes extrinsic_proof = 1; - - // actual scale encoded timestamp extrinsic. - bytes extrinsic = 2; -} - // Header contains the neccessary data to proove finality about IBC commitments message Header { option (gogoproto.goproto_getters) = false; @@ -178,8 +169,9 @@ message ParachainHeader { // total number of para heads in parachain_heads_root uint32 heads_total_count = 6; - // data needed to provide timestamp for ConsensusState - TimestampExtrinsic timestamp = 7; + // trie merkle proof of inclusion in header.extrinsic_root + // this already encodes the actual extrinsic + repeated bytes extrinsic_proof = 7; } // Partial data for MmrLeaf