Skip to content

Commit a7cfae9

Browse files
committed
Initial works
1 parent ada108f commit a7cfae9

28 files changed

+1639
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# cometbft-analyzer-types
2+
3+
This repository provides type definitions for CometBFT events and core structures used for analytics.

go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module github.com/bft-labs/cometbft-analyzer-types
2+
3+
go 1.24.4
4+
5+
require github.com/cometbft/cometbft/api v1.0.0
6+
7+
require (
8+
github.com/cosmos/gogoproto v1.7.0 // indirect
9+
github.com/golang/protobuf v1.5.4 // indirect
10+
github.com/google/go-cmp v0.6.0 // indirect
11+
google.golang.org/protobuf v1.36.4 // indirect
12+
)

go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
github.com/cometbft/cometbft/api v1.0.0 h1:gGBwvsJi/gnHJEtwYfjPIGs2AKg/Vfa1ZuKCPD1/Ko4=
2+
github.com/cometbft/cometbft/api v1.0.0/go.mod h1:EkQiqVSu/p2ebrZEnB2z6Re7r8XNe//M7ylR0qEwWm0=
3+
github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro=
4+
github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0=
5+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
6+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
7+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
8+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
9+
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
10+
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=

lib/bytes.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package lib
2+
3+
import "encoding/binary"
4+
5+
func Uint64ToBytes(u uint64) []byte {
6+
b := make([]byte, 8)
7+
binary.BigEndian.PutUint64(b, u)
8+
return b
9+
}
10+
11+
func Int64ToBytes(i int64) []byte {
12+
b := make([]byte, 8)
13+
binary.BigEndian.PutUint64(b, uint64(i))
14+
return b
15+
}
16+
17+
func Uint32ToBytes(u uint32) []byte {
18+
b := make([]byte, 4)
19+
binary.BigEndian.PutUint32(b, u)
20+
return b
21+
}
22+
23+
func Int32ToBytes(i int32) []byte {
24+
b := make([]byte, 4)
25+
binary.BigEndian.PutUint32(b, uint32(i))
26+
return b
27+
}

lib/type_conversion.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package lib
2+
3+
import (
4+
"encoding/hex"
5+
"github.com/bft-labs/cometbft-analyzer-types/pkg/core"
6+
cryptov1 "github.com/cometbft/cometbft/api/cometbft/crypto/v1"
7+
v1 "github.com/cometbft/cometbft/api/cometbft/types/v1"
8+
"strings"
9+
)
10+
11+
func CometVoteToVote(vote *v1.Vote) *core.Vote {
12+
if vote == nil {
13+
return nil
14+
}
15+
voteType := vote.GetType().String()
16+
typeStrings := strings.Split(voteType, "_")
17+
endIdx := len(typeStrings) - 1
18+
blockId := vote.GetBlockID()
19+
return &core.Vote{
20+
Type: strings.ToLower(typeStrings[endIdx]),
21+
BlockId: core.BlockID{
22+
Hash: hex.EncodeToString(blockId.Hash),
23+
PartSetHeader: CometPartSetHeaderToPartSetHeader(&blockId.PartSetHeader),
24+
},
25+
Height: uint64(vote.Height),
26+
Round: uint64(vote.Round),
27+
Timestamp: vote.Timestamp,
28+
ValidatorIndex: uint64(vote.ValidatorIndex),
29+
ValidatorAddress: hex.EncodeToString(vote.ValidatorAddress),
30+
Signature: hex.EncodeToString(vote.Signature),
31+
}
32+
}
33+
34+
func StepIntToString(step uint32) string {
35+
switch step {
36+
case 1:
37+
return "newHeight"
38+
case 2:
39+
return "newRound"
40+
case 3:
41+
return "propose"
42+
case 4:
43+
return "prevote"
44+
case 5:
45+
return "prevoteWait"
46+
case 6:
47+
return "precommit"
48+
case 7:
49+
return "precommitWait"
50+
case 8:
51+
return "commit"
52+
default:
53+
return "unknown"
54+
}
55+
}
56+
57+
func CometPartSetHeaderToPartSetHeader(psh *v1.PartSetHeader) core.PartSetHeader {
58+
if psh == nil {
59+
return core.PartSetHeader{}
60+
}
61+
return core.PartSetHeader{
62+
Total: uint64(psh.Total),
63+
Hash: hex.EncodeToString(psh.Hash),
64+
}
65+
}
66+
67+
func CometSignedMsgTypeToString(typ int32) string {
68+
switch typ {
69+
case 1:
70+
return "prevote"
71+
case 2:
72+
return "precommit"
73+
case 32:
74+
return "proposal"
75+
default:
76+
return "unknown"
77+
}
78+
}
79+
80+
func CometBlockIDToBlockID(blockID *v1.BlockID) core.BlockID {
81+
if blockID == nil {
82+
return core.BlockID{}
83+
}
84+
return core.BlockID{
85+
Hash: hex.EncodeToString(blockID.Hash),
86+
PartSetHeader: core.PartSetHeader{
87+
Total: uint64(blockID.PartSetHeader.Total),
88+
Hash: hex.EncodeToString(blockID.PartSetHeader.Hash),
89+
},
90+
}
91+
}
92+
93+
func CometPartToPart(part *v1.Part) core.Part {
94+
if part == nil {
95+
return core.Part{}
96+
}
97+
return core.Part{
98+
Index: part.Index,
99+
Bytes: hex.EncodeToString(part.Bytes),
100+
}
101+
}
102+
103+
func CometProofToProof(proof *cryptov1.Proof) core.Proof {
104+
if proof == nil {
105+
return core.Proof{}
106+
}
107+
108+
return core.Proof{
109+
Total: proof.Total,
110+
Index: proof.Index,
111+
LeafHash: hex.EncodeToString(proof.LeafHash),
112+
Aunts: BytesArrayToHexStringArr(proof.Aunts),
113+
}
114+
}
115+
116+
func BytesArrayToHexStringArr(arr [][]byte) []string {
117+
if arr == nil {
118+
return nil
119+
}
120+
hexStrings := make([]string, len(arr))
121+
for i, b := range arr {
122+
hexStrings[i] = hex.EncodeToString(b)
123+
}
124+
return hexStrings
125+
}

pkg/core/bits.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package core
2+
3+
type BitArray struct {
4+
Bits int64 `bson:"bits" json:"bits"`
5+
Elems []uint64 `bson:"elems" json:"elems"`
6+
}

pkg/core/block.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package core
2+
3+
import (
4+
"encoding/hex"
5+
"fmt"
6+
"time"
7+
)
8+
9+
type Block struct {
10+
Header Header `bson:"header" json:"header"`
11+
Data Data `bson:"data" json:"data"`
12+
Evidence EvidenceData `bson:"evidence" json:"evidence"`
13+
LastCommit *Commit `bson:"lastCommit" json:"lastCommit"`
14+
}
15+
16+
type Header struct {
17+
Version Consensus `bson:"version" json:"version"`
18+
ChainID string `bson:"chainId" json:"chainId"`
19+
Height int64 `bson:"height" json:"height"`
20+
Time time.Time `bson:"time" json:"time"`
21+
LastBlockID BlockID `bson:"lastBlockId" json:"lastBlockId"`
22+
LastCommitHash string `bson:"lastCommitHash" json:"lastCommitHash"`
23+
DataHash string `bson:"dataHash" json:"dataHash"`
24+
ValidatorsHash string `bson:"validatorsHash" json:"validatorsHash"`
25+
NextValidatorsHash string `bson:"nextValidatorsHash" json:"nextValidatorsHash"`
26+
ConsensusHash string `bson:"consensusHash" json:"consensusHash"`
27+
AppHash string `bson:"appHash" json:"appHash"`
28+
LastResultsHash string `bson:"lastResultsHash" json:"lastResultsHash"`
29+
EvidenceHash string `bson:"evidenceHash" json:"evidenceHash"`
30+
ProposerAddress string `bson:"proposerAddress" json:"proposerAddress"`
31+
}
32+
33+
type Consensus struct {
34+
Block uint64 `bson:"block" json:"block"`
35+
App uint64 `bson:"app" json:"app"`
36+
}
37+
38+
type Data struct {
39+
Txs []Tx `bson:"txs" json:"txs"`
40+
}
41+
42+
type Tx []byte
43+
44+
type EvidenceData struct {
45+
Evidence []Evidence `bson:"evidence" json:"evidence"`
46+
}
47+
48+
type Evidence interface{}
49+
50+
type Commit struct {
51+
Height int64 `bson:"height" json:"height"`
52+
Round int32 `bson:"round" json:"round"`
53+
BlockID BlockID `bson:"blockId" json:"blockId"`
54+
Signatures []CommitSig `bson:"signatures" json:"signatures"`
55+
}
56+
57+
type CommitSig struct {
58+
BlockIDFlag BlockIDFlag `bson:"blockIdFlag" json:"blockIdFlag"`
59+
ValidatorAddress string `bson:"validatorAddress" json:"validatorAddress"`
60+
Timestamp time.Time `bson:"timestamp" json:"timestamp"`
61+
Signature string `bson:"signature" json:"signature"`
62+
}
63+
64+
type BlockIDFlag int
65+
66+
const (
67+
BlockIDFlagAbsent BlockIDFlag = 1
68+
BlockIDFlagCommit BlockIDFlag = 2
69+
BlockIDFlagNil BlockIDFlag = 3
70+
)
71+
72+
func NewCommitSigAbsent() CommitSig {
73+
return CommitSig{
74+
BlockIDFlag: BlockIDFlagAbsent,
75+
}
76+
}
77+
78+
func (b *Block) String() string {
79+
if b == nil {
80+
return "nil-Block"
81+
}
82+
return "Block{" +
83+
"\n " + b.Header.String() +
84+
"\n " + b.Data.String() +
85+
"\n " + b.Evidence.String() +
86+
"\n " + b.LastCommit.String() +
87+
"\n}#" + b.Hash()
88+
}
89+
90+
func (h Header) String() string {
91+
return "Header{" +
92+
"\n Version: " + h.Version.String() +
93+
"\n ChainID: " + h.ChainID +
94+
"\n Height: " + fmt.Sprintf("%d", h.Height) +
95+
"\n Time: " + h.Time.Format(time.RFC3339Nano) +
96+
"\n LastBlockID: " + h.LastBlockID.String() +
97+
"\n LastCommit: " + h.LastCommitHash +
98+
"\n Data: " + h.DataHash +
99+
"\n Validators: " + h.ValidatorsHash +
100+
"\n NextValidators: " + h.NextValidatorsHash +
101+
"\n App: " + h.AppHash +
102+
"\n Consensus: " + h.ConsensusHash +
103+
"\n Results: " + h.LastResultsHash +
104+
"\n Evidence: " + h.EvidenceHash +
105+
"\n Proposer: " + h.ProposerAddress +
106+
"\n }#" + h.Hash()
107+
}
108+
109+
func (c Consensus) String() string {
110+
return fmt.Sprintf("{%d %d}", c.Block, c.App)
111+
}
112+
113+
func (d Data) String() string {
114+
result := "Data{"
115+
for _, tx := range d.Txs {
116+
result += fmt.Sprintf("\n %s (%d bytes)", hex.EncodeToString(tx), len(tx))
117+
}
118+
return result + "\n }#" + d.Hash()
119+
}
120+
121+
func (e EvidenceData) String() string {
122+
return "EvidenceData{" +
123+
"\n }#" + e.Hash()
124+
}
125+
126+
func (c *Commit) String() string {
127+
if c == nil {
128+
return "nil-Commit"
129+
}
130+
result := "Commit{" +
131+
fmt.Sprintf("\n Height: %d", c.Height) +
132+
fmt.Sprintf("\n Round: %d", c.Round) +
133+
"\n BlockID: " + c.BlockID.String() +
134+
"\n Signatures:"
135+
for _, sig := range c.Signatures {
136+
result += "\n " + sig.String()
137+
}
138+
return result + "\n }#" + c.Hash()
139+
}
140+
141+
func (cs CommitSig) String() string {
142+
return fmt.Sprintf("CommitSig{%s by %s on %d @ %s}", cs.Signature, cs.ValidatorAddress, cs.BlockIDFlag, cs.Timestamp.Format(time.RFC3339))
143+
}
144+
145+
func (bid BlockID) String() string {
146+
return fmt.Sprintf("%s:%d:%s", bid.Hash, bid.PartSetHeader.Total, bid.PartSetHeader.Hash)
147+
}
148+
149+
func (b *Block) Hash() string {
150+
return ""
151+
}
152+
153+
func (h Header) Hash() string {
154+
return ""
155+
}
156+
157+
func (d Data) Hash() string {
158+
return ""
159+
}
160+
161+
func (e EvidenceData) Hash() string {
162+
return ""
163+
}
164+
165+
func (c *Commit) Hash() string {
166+
return ""
167+
}
168+
169+
func (b *Block) ValidateBasic() error {
170+
return nil
171+
}

pkg/core/block_id.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package core
2+
3+
type BlockID struct {
4+
Hash string `bson:"hash" json:"hash"`
5+
PartSetHeader PartSetHeader `bson:"partSetHeader" json:"partSetHeader"`
6+
}
7+
8+
type PartSetHeader struct {
9+
Total uint64 `bson:"total" json:"total"`
10+
Hash string `bson:"hash" json:"hash"`
11+
}

pkg/core/part.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package core
2+
3+
import (
4+
"crypto/sha256"
5+
"strconv"
6+
)
7+
8+
type Part struct {
9+
Index uint32 `bson:"index" json:"index"`
10+
Bytes string `bson:"bytes" json:"bytes"` // hex encoded bytes of the part
11+
Proof Proof `bson:"proof" json:"proof"`
12+
}
13+
14+
func (p Part) Hash() []byte {
15+
h := sha256.New()
16+
h.Write([]byte(strconv.FormatUint(uint64(p.Index), 10)))
17+
h.Write([]byte(p.Bytes))
18+
h.Write(p.Proof.Hash())
19+
return h.Sum(nil)
20+
}

0 commit comments

Comments
 (0)