From 2b4efe6958c3824e37e739dddece1b291e871000 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Sun, 18 Apr 2021 14:01:25 +0200 Subject: [PATCH 1/8] copy over template and start new ADR --- docs/lazy-adr/adr-004-core-types.md | 72 +++++++++++++++++++++++++++++ docs/lazy-adr/adr-template.md | 72 +++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 docs/lazy-adr/adr-004-core-types.md create mode 100644 docs/lazy-adr/adr-template.md diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md new file mode 100644 index 0000000000..450ae05e09 --- /dev/null +++ b/docs/lazy-adr/adr-004-core-types.md @@ -0,0 +1,72 @@ +# ADR 004: Blockchain Core Data Types + +## Changelog + +- {date}: {changelog} + +## Context + +> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. + +## Alternative Approaches + +> This section contains information around alternative options that are considered before making a decision. It should contain a explanation on why the alternative approach(es) were not chosen. + +## Decision + +> This section records the decision that was made. +> It is best to record as much info as possible from the discussion that happened. This aids in not having to go back to the Pull Request to get the needed information. + +## Detailed Design + +> This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. +> +> Here are some common questions that get answered as part of the detailed design: +> +> - What are the user requirements? +> +> - What systems will be affected? +> +> - What new data structures are needed, what data structures will be changed? +> +> - What new APIs will be needed, what APIs will be changed? +> +> - What are the efficiency considerations (time/space)? +> +> - What are the expected access patterns (load/throughput)? +> +> - Are there any logging, monitoring or observability needs? +> +> - Are there any security considerations? +> +> - Are there any privacy considerations? +> +> - How will the changes be tested? +> +> - If the change is large, how will the changes be broken up for ease of review? +> +> - Will these changes require a breaking (major) release? +> +> - Does this change require coordination with the LazyLedger fork of the SDK or lazyledger-app? + +## Status + +> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. + +{Deprecated|Proposed|Accepted|Declined} + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +### Negative + +### Neutral + +## References + +> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! + +- {reference link} diff --git a/docs/lazy-adr/adr-template.md b/docs/lazy-adr/adr-template.md new file mode 100644 index 0000000000..fc95814282 --- /dev/null +++ b/docs/lazy-adr/adr-template.md @@ -0,0 +1,72 @@ +# ADR {ADR-NUMBER}: {TITLE} + +## Changelog + +- {date}: {changelog} + +## Context + +> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. + +## Alternative Approaches + +> This section contains information around alternative options that are considered before making a decision. It should contain a explanation on why the alternative approach(es) were not chosen. + +## Decision + +> This section records the decision that was made. +> It is best to record as much info as possible from the discussion that happened. This aids in not having to go back to the Pull Request to get the needed information. + +## Detailed Design + +> This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. +> +> Here are some common questions that get answered as part of the detailed design: +> +> - What are the user requirements? +> +> - What systems will be affected? +> +> - What new data structures are needed, what data structures will be changed? +> +> - What new APIs will be needed, what APIs will be changed? +> +> - What are the efficiency considerations (time/space)? +> +> - What are the expected access patterns (load/throughput)? +> +> - Are there any logging, monitoring or observability needs? +> +> - Are there any security considerations? +> +> - Are there any privacy considerations? +> +> - How will the changes be tested? +> +> - If the change is large, how will the changes be broken up for ease of review? +> +> - Will these changes require a breaking (major) release? +> +> - Does this change require coordination with the LazyLedger fork of the SDK or lazyledger-app? + +## Status + +> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. + +{Deprecated|Proposed|Accepted|Declined} + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +### Negative + +### Neutral + +## References + +> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! + +- {reference link} From 2de4aa658037d5cfbbee2cb3a1ccacc3cdc42f71 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 19 Apr 2021 11:54:08 +0200 Subject: [PATCH 2/8] draft ADR with core types --- docs/lazy-adr/adr-004-core-types.md | 104 +++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md index 450ae05e09..d03b71ea9a 100644 --- a/docs/lazy-adr/adr-004-core-types.md +++ b/docs/lazy-adr/adr-004-core-types.md @@ -8,17 +8,113 @@ > This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. +This document describes the core data structures of any Optimint-powered blockchain. + ## Alternative Approaches > This section contains information around alternative options that are considered before making a decision. It should contain a explanation on why the alternative approach(es) were not chosen. ## Decision -> This section records the decision that was made. -> It is best to record as much info as possible from the discussion that happened. This aids in not having to go back to the Pull Request to get the needed information. +We design the core data types as minimalistic as possible, i.e. they only contain the absolute necessary +data for an optimistic rollup to function properly. +If there are any additional fields that conflict with above's claimed minimalism, then they are necessarily inherited +by the ABCI imposed separation between application state machine and consensus/networking (often also referred to as ABCI-server and -client). +Where such tradeoffs are made, we explicitly comment on them. ## Detailed Design +### Transactions + +In Optimint, like in Tendermint, Transactions are just an opaque slice of bytes: + +```go +type Tx []byte +type Txs []Tx +``` + +If necessary `Tx` could be turned into a struct. Currently, there is no need for that though. + +### Block Header + +```go +type Header struct { + // Block and App version + Version Version + // TODO this is redundant; understand if + // anything like the ChainID in the Header is + // required for IBC though. + NamespaceID [8]byte + + Height uint64 + Time uint64 // time in tai64 format + + // prev block info + LastHeaderHash [32]byte + + // hashes of block data + LastCommitHash [32]byte // commit from aggregator(s) from the last block + DataHash [32]byte // Block.Data root aka Transactions + ConsensusHash [32]byte // consensus params for current block + AppHash [32]byte // state after applying txs from the current block + + // root hash of all results from the txs from the previous block + LastResultsHash [32]byte // TODO this is ABCI specific: do we really need it though? + + // TODO: do we need this to be included in the header? + // the address can be derived from the pubkey which can be derived + // from the signature when using secp256k. + ProposerAddress Address // original proposer of the block +} + +// Version captures the consensus rules for processing a block in the blockchain, +// including all blockchain data structures and the rules of the application's +// state transition machine. +// This is equivalent to the tmversion.Consensus type in Tendermint. +type Version struct { + Block uint32 + App uint32 +} +``` + +### Block and Block.Data + +```go +type Block struct { + Header Header + Data Data + LastCommit *Commit +} + +type Data struct { + Txs Txs + IntermediateStateRoots IntermediateStateRoots + Evidence EvidenceData +} +type EvidenceData struct { + Evidence []Evidence +} +``` + +#### Evidence + +`Evidence` represents a go-interface (or oneof in protobuf) of known set of concrete fraud-proofs: +- Same Aggregator signed two different blocks at the same height + - TODO: figure out if this is actually malicious / slashable behaviour - eg. clients could simply accept the last block included in a LL block +- State Transition Fraud Proofs (for previous blocks) +- TODO: that's it, or are the more? + + +### Commit + +```go +type Commit struct { + Height uint64 + HeaderHash [32]byte + Signatures []Signature // most of the time this is a single signature +} +``` + > This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. > > Here are some common questions that get answered as part of the detailed design: @@ -53,7 +149,7 @@ > A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. -{Deprecated|Proposed|Accepted|Declined} +Proposed ## Consequences @@ -70,3 +166,5 @@ > Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! - {reference link} + +TODO link to PR adding go code From 08a4a59ede5cf0856237dce0376e538304069acc Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 19 Apr 2021 11:59:38 +0200 Subject: [PATCH 3/8] consistent indentation --- docs/lazy-adr/adr-004-core-types.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md index d03b71ea9a..35e7992934 100644 --- a/docs/lazy-adr/adr-004-core-types.md +++ b/docs/lazy-adr/adr-004-core-types.md @@ -88,9 +88,10 @@ type Block struct { type Data struct { Txs Txs - IntermediateStateRoots IntermediateStateRoots - Evidence EvidenceData + IntermediateStateRoots IntermediateStateRoots + Evidence EvidenceData } + type EvidenceData struct { Evidence []Evidence } From d0731fc86353528a5822a9bfcf937bbc18919b5a Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 19 Apr 2021 21:18:58 +0200 Subject: [PATCH 4/8] Add ConsensusParams --- docs/lazy-adr/adr-004-core-types.md | 69 ++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md index 35e7992934..274f31f633 100644 --- a/docs/lazy-adr/adr-004-core-types.md +++ b/docs/lazy-adr/adr-004-core-types.md @@ -106,7 +106,7 @@ type EvidenceData struct { - TODO: that's it, or are the more? -### Commit +#### Commit ```go type Commit struct { @@ -116,6 +116,73 @@ type Commit struct { } ``` +#### ConsensusParams + +[ConsensusParams](https://docs.tendermint.com/master/spec/core/state.html#consensusparams) can be updated by the application through ABCI. +This could be seen as a state transition and the ConsensusHash in the header would then require a dedicated state fraud proof. +That said, none of the existing default Cosmos-SDK modules actually make use of this functionality though. +Hence, we can treat the ConsensusParams as constants (for the same app version). +We clearly need to communicate this to optimistic rollup chain developers. +Ideally, we should ensure this programmatically to guarantee that this assumption always holds inside optimint. + +The ConsensusParams have the exact same structure as in Tendermint. For the sake of self-containedness we still list them here: + + +```go +// ConsensusParams contains consensus critical parameters that determine the +// validity of blocks. +type ConsensusParams struct { + Block BlockParams + Evidence EvidenceParams + Validator ValidatorParams + Version VersionParams +} + +// BlockParams contains limits on the block size. +type BlockParams struct { + // Max block size, in bytes. + // Note: must be greater than 0 + MaxBytes int64 + // Max gas per block. + // Note: must be greater or equal to -1 + MaxGas int64 + // Minimum time increment between consecutive blocks (in milliseconds) If the + // block header timestamp is ahead of the system clock, decrease this value. + // + // Not exposed to the application. + TimeIotaMs int64 +} + +// EvidenceParams determine how we handle evidence of malfeasance. +type EvidenceParams struct { + // Max age of evidence, in blocks. + // + // The basic formula for calculating this is: MaxAgeDuration / {average block + // time}. + MaxAgeNumBlocks int64 + // Max age of evidence, in time. + // + // It should correspond with an app's "unbonding period" or other similar + // mechanism for handling [Nothing-At-Stake + // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). + MaxAgeDuration time.Duration + // This sets the maximum size of total evidence in bytes that can be committed in a single block. + // and should fall comfortably under the max block bytes. + // Default is 1048576 or 1MB + MaxBytes int64 +} + +// ValidatorParams restrict the public key types validators can use. +type ValidatorParams struct { + PubKeyTypes []string +} + +// VersionParams contains the ABCI application version. +type VersionParams struct { + AppVersion uint64 +} +``` + > This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. > > Here are some common questions that get answered as part of the detailed design: From 23360645a7087f3c52f8b553ed5a6f87d434754d Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 19 Apr 2021 21:41:56 +0200 Subject: [PATCH 5/8] Start adding core data types as go types as well --- types/block.go | 67 +++++++++++++++++++++++++++++++++++++++++++++++ types/evidence.go | 21 +++++++++++++++ types/tx.go | 5 ++++ 3 files changed, 93 insertions(+) create mode 100644 types/block.go create mode 100644 types/evidence.go create mode 100644 types/tx.go diff --git a/types/block.go b/types/block.go new file mode 100644 index 0000000000..0eaea2ef09 --- /dev/null +++ b/types/block.go @@ -0,0 +1,67 @@ +package types + +type Header struct { + // Block and App version + Version Version + // TODO this is redundant; understand if + // anything like the ChainID in the Header is + // required for IBC though. + NamespaceID [8]byte + + Height uint64 + Time uint64 // time in tai64 format + + // prev block info + LastHeaderHash [32]byte + + // hashes of block data + LastCommitHash [32]byte // commit from aggregator(s) from the last block + DataHash [32]byte // Block.Data root aka Transactions + ConsensusHash [32]byte // consensus params for current block + AppHash [32]byte // state after applying txs from the current block + + // root hash of all results from the txs from the previous block + LastResultsHash [32]byte // TODO this is ABCI specific: do we really need it though? + + // TODO: do we need this to be included in the header? + // the address can be derived from the pubkey which can be derived + // from the signature when using secp256k. + ProposerAddress []byte // original proposer of the block +} + +// Version captures the consensus rules for processing a block in the blockchain, +// including all blockchain data structures and the rules of the application's +// state transition machine. +// This is equivalent to the tmversion.Consensus type in Tendermint. +type Version struct { + Block uint32 + App uint32 +} + +type Block struct { + Header Header + Data Data + LastCommit *Commit +} + +type Data struct { + Txs Txs + IntermediateStateRoots IntermediateStateRoots + Evidence EvidenceData +} + +type EvidenceData struct { + Evidence []Evidence +} + +type Commit struct { + Height uint64 + HeaderHash [32]byte + Signatures []Signature // most of the time this is a single signature +} + +type Signature []byte + +type IntermediateStateRoots struct { + RawRootsList [][]byte +} diff --git a/types/evidence.go b/types/evidence.go new file mode 100644 index 0000000000..a052111972 --- /dev/null +++ b/types/evidence.go @@ -0,0 +1,21 @@ +package types + +import ( + "time" + + // TODO: either copy the vanilla abci types (or the protos) into this repo + // or, import the vanilla tendermint types instead. + abci "github.com/lazyledger/lazyledger-core/abci/types" +) + +// Evidence represents any provable malicious activity by a validator. +// Verification logic for each evidence is part of the evidence module. +type Evidence interface { + ABCI() []abci.Evidence // forms individual evidence to be sent to the application + Bytes() []byte // bytes which comprise the evidence + Hash() []byte // hash of the evidence + Height() int64 // height of the infraction + String() string // string format of the evidence + Time() time.Time // time of the infraction + ValidateBasic() error // basic consistency check +} diff --git a/types/tx.go b/types/tx.go new file mode 100644 index 0000000000..b9a84dff02 --- /dev/null +++ b/types/tx.go @@ -0,0 +1,5 @@ +package types + +type Tx []byte + +type Txs []Tx From ca14ffa1c65f2e299d14f8ff3227e67a4fdfc8f6 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Mon, 19 Apr 2021 21:56:04 +0200 Subject: [PATCH 6/8] Start cleaning up the ADR --- docs/lazy-adr/adr-004-core-types.md | 53 ++++++----------------------- 1 file changed, 11 insertions(+), 42 deletions(-) diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md index 274f31f633..15c9250231 100644 --- a/docs/lazy-adr/adr-004-core-types.md +++ b/docs/lazy-adr/adr-004-core-types.md @@ -12,7 +12,9 @@ This document describes the core data structures of any Optimint-powered blockch ## Alternative Approaches -> This section contains information around alternative options that are considered before making a decision. It should contain a explanation on why the alternative approach(es) were not chosen. +Alternatives for ChainID: + - an integer type like unit64 + - a string that fulfills some basic rules like the ChainID for Cosmos chains ## Decision @@ -41,9 +43,7 @@ If necessary `Tx` could be turned into a struct. Currently, there is no need for type Header struct { // Block and App version Version Version - // TODO this is redundant; understand if - // anything like the ChainID in the Header is - // required for IBC though. + // NamespaceID identifies this chain e.g. when connected to other rollups via IBC. NamespaceID [8]byte Height uint64 @@ -59,11 +59,14 @@ type Header struct { AppHash [32]byte // state after applying txs from the current block // root hash of all results from the txs from the previous block - LastResultsHash [32]byte // TODO this is ABCI specific: do we really need it though? + // This is ABCI specific but smart-contract chains require some way of committing to transaction receipts/results. + LastResultsHash [32]byte - // TODO: do we need this to be included in the header? - // the address can be derived from the pubkey which can be derived + + // Note that the address can be derived from the pubkey which can be derived // from the signature when using secp256k. + // We keep this in case users choose another signature format where the + // pubkey can't be recovered by the signature (e.g. ed25519). ProposerAddress Address // original proposer of the block } @@ -183,40 +186,8 @@ type VersionParams struct { } ``` -> This section does not need to be filled in at the start of the ADR, but must be completed prior to the merging of the implementation. -> -> Here are some common questions that get answered as part of the detailed design: -> -> - What are the user requirements? -> -> - What systems will be affected? -> -> - What new data structures are needed, what data structures will be changed? -> -> - What new APIs will be needed, what APIs will be changed? -> -> - What are the efficiency considerations (time/space)? -> -> - What are the expected access patterns (load/throughput)? -> -> - Are there any logging, monitoring or observability needs? -> -> - Are there any security considerations? -> -> - Are there any privacy considerations? -> -> - How will the changes be tested? -> -> - If the change is large, how will the changes be broken up for ease of review? -> -> - Will these changes require a breaking (major) release? -> -> - Does this change require coordination with the LazyLedger fork of the SDK or lazyledger-app? - ## Status -> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. Once the ADR has been implemented mark the ADR as "implemented". If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. - Proposed ## Consequences @@ -231,8 +202,6 @@ Proposed ## References -> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! +- https://github.com/lazyledger/optimint/pull/41 -- {reference link} -TODO link to PR adding go code From 7525fd6f26000231df31442ab6b1ce1f3d2b20f7 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 20 Apr 2021 09:04:00 +0200 Subject: [PATCH 7/8] update comments in code, too --- types/block.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/types/block.go b/types/block.go index 0eaea2ef09..fcc5a93e71 100644 --- a/types/block.go +++ b/types/block.go @@ -3,9 +3,7 @@ package types type Header struct { // Block and App version Version Version - // TODO this is redundant; understand if - // anything like the ChainID in the Header is - // required for IBC though. + // NamespaceID identifies this chain e.g. when connected to other rollups via IBC. NamespaceID [8]byte Height uint64 @@ -20,12 +18,15 @@ type Header struct { ConsensusHash [32]byte // consensus params for current block AppHash [32]byte // state after applying txs from the current block - // root hash of all results from the txs from the previous block - LastResultsHash [32]byte // TODO this is ABCI specific: do we really need it though? + // Root hash of all results from the txs from the previous block. + // This is ABCI specific but smart-contract chains require some way of committing + // to transaction receipts/results. + LastResultsHash [32]byte - // TODO: do we need this to be included in the header? - // the address can be derived from the pubkey which can be derived + // Note that the address can be derived from the pubkey which can be derived // from the signature when using secp256k. + // We keep this in case users choose another signature format where the + // pubkey can't be recovered by the signature (e.g. ed25519). ProposerAddress []byte // original proposer of the block } From 3213bd3716c43eb814a8fbfae64c5552e3faee24 Mon Sep 17 00:00:00 2001 From: Ismail Khoffi Date: Tue, 20 Apr 2021 09:24:29 +0200 Subject: [PATCH 8/8] Further cleanup ADR and code --- docs/lazy-adr/adr-004-core-types.md | 27 ++++++++++++++++++--------- types/block.go | 2 ++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/lazy-adr/adr-004-core-types.md b/docs/lazy-adr/adr-004-core-types.md index 15c9250231..2c33976fa4 100644 --- a/docs/lazy-adr/adr-004-core-types.md +++ b/docs/lazy-adr/adr-004-core-types.md @@ -2,12 +2,10 @@ ## Changelog -- {date}: {changelog} +- 19-04-2021: Initial Draft ## Context -> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution. - This document describes the core data structures of any Optimint-powered blockchain. ## Alternative Approaches @@ -102,11 +100,13 @@ type EvidenceData struct { #### Evidence -`Evidence` represents a go-interface (or oneof in protobuf) of known set of concrete fraud-proofs: +`Evidence` represents a go-interface (or oneof in protobuf) of known set of concrete fraud-proofs. +The details for this will be defined in a separated adr/PR. + +Here is an incomplete list of potenial evidence types: - Same Aggregator signed two different blocks at the same height - - TODO: figure out if this is actually malicious / slashable behaviour - eg. clients could simply accept the last block included in a LL block + - figure out if this is actually malicious / slashable behaviour - e.g. clients could simply accept the last block included in a LL block - State Transition Fraud Proofs (for previous blocks) -- TODO: that's it, or are the more? #### Commit @@ -188,16 +188,25 @@ type VersionParams struct { ## Status -Proposed +Proposed and partly implemented. -## Consequences +For finishing the implementation these items need to be tackled at least: + +- [ ] methods on core types (e.g. for hashing and basic validation etc) +- [ ] equivalent types for serialization purposes (probably protobuf) +- [ ] conversion from and to protobuf -> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +## Consequences ### Positive +- very close to the original Tendermint types which makes on-boarding devs familiar for the Cosmos-SDK and Tendermint easier + ### Negative +- dependency on abci types for evidence interface (in the current implementation at least) + ### Neutral ## References diff --git a/types/block.go b/types/block.go index fcc5a93e71..8446d744c2 100644 --- a/types/block.go +++ b/types/block.go @@ -4,6 +4,8 @@ type Header struct { // Block and App version Version Version // NamespaceID identifies this chain e.g. when connected to other rollups via IBC. + // TODO(ismail): figure out if we want to use namespace.ID here instead (downside is that it isn't fixed size) + // at least extract the used constants (32, 8) as package variables though. NamespaceID [8]byte Height uint64