-
Notifications
You must be signed in to change notification settings - Fork 3
chore: Use stored block data instead #90
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
package common | ||
|
||
import ( | ||
"errors" | ||
"time" | ||
|
||
cmbytes "github.com/cometbft/cometbft/libs/bytes" | ||
cmversion "github.com/cometbft/cometbft/proto/tendermint/version" | ||
cmttypes "github.com/cometbft/cometbft/types" | ||
|
||
rlktypes "github.com/rollkit/rollkit/types" | ||
) | ||
|
||
// ToABCIHeader converts Rollkit header to Header format defined in ABCI. | ||
// Caller should fill all the fields that are not available in Rollkit header (like ChainID). | ||
func ToABCIHeader(header *rlktypes.Header) (cmttypes.Header, error) { | ||
return cmttypes.Header{ | ||
Version: cmversion.Consensus{ | ||
Block: header.Version.Block, | ||
App: header.Version.App, | ||
}, | ||
Height: int64(header.Height()), //nolint:gosec | ||
Time: header.Time(), | ||
LastBlockID: cmttypes.BlockID{ | ||
Hash: cmbytes.HexBytes(header.LastHeaderHash[:]), | ||
PartSetHeader: cmttypes.PartSetHeader{ | ||
Total: 0, | ||
Hash: nil, | ||
}, | ||
}, | ||
LastCommitHash: cmbytes.HexBytes(header.LastCommitHash), | ||
DataHash: cmbytes.HexBytes(header.DataHash), | ||
ConsensusHash: cmbytes.HexBytes(header.ConsensusHash), | ||
AppHash: cmbytes.HexBytes(header.AppHash), | ||
LastResultsHash: cmbytes.HexBytes(header.LastResultsHash), | ||
EvidenceHash: new(cmttypes.EvidenceData).Hash(), | ||
ProposerAddress: header.ProposerAddress, | ||
ChainID: header.ChainID(), | ||
ValidatorsHash: cmbytes.HexBytes(header.ValidatorHash), | ||
NextValidatorsHash: cmbytes.HexBytes(header.ValidatorHash), | ||
}, nil | ||
} | ||
|
||
// ToABCIBlock converts Rolkit block into block format defined by ABCI. | ||
// Returned block should pass `ValidateBasic`. | ||
func ToABCIBlock(header *rlktypes.SignedHeader, data *rlktypes.Data) (*cmttypes.Block, error) { | ||
abciHeader, err := ToABCIHeader(&header.Header) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// we have one validator | ||
if len(header.ProposerAddress) == 0 { | ||
return nil, errors.New("proposer address is not set") | ||
} | ||
|
||
abciCommit := ToABCICommit(header.Height(), header.Hash(), header.ProposerAddress, header.Time(), header.Signature) | ||
|
||
// This assumes that we have only one signature | ||
if len(abciCommit.Signatures) == 1 { | ||
abciCommit.Signatures[0].ValidatorAddress = header.ProposerAddress | ||
} | ||
Comment on lines
+59
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainHardcoded assumption about signature count. The code assumes there will only be one signature, which is currently correct but may not remain true if requirements change. Consider making this more robust by iterating through signatures or documenting this assumption clearly. 🏁 Script executed: #!/bin/bash
# Check if there are any Rollkit files that handle multiple signatures
rg -A 2 -B 2 "[]signature" --type go -g "*.go" Length of output: 122 🏁 Script executed: #!/bin/bash
# Search for all occurrences of the Signatures field across Go files
rg -n "Signatures" -g "*.go" Length of output: 518 Avoid hardcoding single‐signature assumption The code currently assumes there will only ever be one signature in
Rather than special-casing a single signature, consider uniformly handling all signatures. For example, replace the one-off check/assignment with: - if len(abciCommit.Signatures) == 1 {
- abciCommit.Signatures[0].ValidatorAddress = header.ProposerAddress
- }
+ for i := range abciCommit.Signatures {
+ abciCommit.Signatures[i].ValidatorAddress = header.ProposerAddress
+ } And update the static slice constructions to collect or initialize all signatures dynamically. If single-signature is an explicit protocol limitation, add a clear comment/TODO in one shared helper to document this behavior. |
||
abciBlock := cmttypes.Block{ | ||
Header: abciHeader, | ||
Evidence: cmttypes.EvidenceData{ | ||
Evidence: nil, | ||
}, | ||
LastCommit: abciCommit, | ||
} | ||
abciBlock.Txs = make([]cmttypes.Tx, len(data.Txs)) | ||
for i := range data.Txs { | ||
abciBlock.Txs[i] = cmttypes.Tx(data.Txs[i]) | ||
} | ||
abciBlock.DataHash = cmbytes.HexBytes(header.DataHash) | ||
|
||
return &abciBlock, nil | ||
} | ||
|
||
// ToABCIBlockMeta converts Rollkit block into BlockMeta format defined by ABCI | ||
func ToABCIBlockMeta(header *rlktypes.SignedHeader, data *rlktypes.Data) (*cmttypes.BlockMeta, error) { | ||
cmblock, err := ToABCIBlock(header, data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
blockID := cmttypes.BlockID{Hash: cmblock.Hash()} | ||
|
||
return &cmttypes.BlockMeta{ | ||
BlockID: blockID, | ||
BlockSize: cmblock.Size(), | ||
Header: cmblock.Header, | ||
NumTxs: len(cmblock.Txs), | ||
}, nil | ||
} | ||
|
||
// ToABCICommit returns a commit format defined by ABCI. | ||
// Other fields (especially ValidatorAddress and Timestamp of Signature) have to be filled by caller. | ||
func ToABCICommit(height uint64, hash rlktypes.Hash, val cmttypes.Address, time time.Time, signature rlktypes.Signature) *cmttypes.Commit { | ||
return &cmttypes.Commit{ | ||
Height: int64(height), //nolint:gosec | ||
Round: 0, | ||
BlockID: cmttypes.BlockID{ | ||
Hash: cmbytes.HexBytes(hash), | ||
PartSetHeader: cmttypes.PartSetHeader{}, | ||
}, | ||
Signatures: []cmttypes.CommitSig{{ | ||
BlockIDFlag: cmttypes.BlockIDFlagCommit, | ||
Signature: signature, | ||
ValidatorAddress: val, | ||
Timestamp: time, | ||
}}, | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider organizing imports into standard groups with blank lines between them:
This pattern improves readability and follows Go conventions. For example:
Spotted by Diamond (based on custom rules)
Is this helpful? React 👍 or 👎 to let us know.