Skip to content

Commit

Permalink
privval,config,cometbft: stop using cometbft/libs that are becoming i…
Browse files Browse the repository at this point in the history
…nternal (#621)

* privval: update for internalizing comet imports

use kwil HexBytes

* config,comet: more removal of comet libs

* deps: gogoproto is now indirect
  • Loading branch information
jchappelow authored Apr 5, 2024
1 parent bd7d19b commit bae8cfb
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 116 deletions.
5 changes: 4 additions & 1 deletion cmd/kwild/config/folders.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ package config
// configurable.
const (
ABCIDirName = "abci" // cometBFT node's root folder
ABCIInfoSubDirName = "info" // e.g. abci/info for kv state data
ReceivedSnapsDirName = "rcvdSnaps"
SigningDirName = "signing"

// ABCIInfoSubDirName is deprecated, only used to migrate old kv state
// (meta) data into the main DB's kwild_chain schema (internal/abci/meta).
ABCIInfoSubDirName = "info" // e.g. abci/info for kv state data

ConfigFileName = "config.toml"
PrivateKeyFileName = "private_key"

Expand Down
17 changes: 17 additions & 0 deletions core/types/hex.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"strings"
)

// HexBytes is used to decode hexadecimal text into a byte slice.
Expand Down Expand Up @@ -38,3 +39,19 @@ func (hb HexBytes) MarshalJSON() ([]byte, error) {

var _ json.Marshaler = HexBytes{}
var _ json.Unmarshaler = (*HexBytes)(nil)

var _ fmt.Formatter = HexBytes{}

// Format writes either address of 0th element in a slice in base 16 notation,
// with leading 0x (%p), or casts HexBytes to bytes and writes as hexadecimal
// string to s.
func (hb HexBytes) Format(s fmt.State, verb rune) {
switch verb {
case 'p':
s.Write([]byte(fmt.Sprintf("%p", hb)))
case 'X':
s.Write([]byte(strings.ToUpper(hb.String())))
default:
s.Write([]byte(hb.String()))
}
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ replace (
require (
dario.cat/mergo v1.0.0
github.com/alexliesenfeld/health v0.6.0
github.com/cometbft/cometbft v0.38.5
github.com/cosmos/gogoproto v1.4.11
github.com/cometbft/cometbft v0.38.6
github.com/dgraph-io/badger/v3 v3.2103.5
github.com/ethereum/go-ethereum v1.13.8
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.5
Expand Down Expand Up @@ -55,6 +54,7 @@ require (
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/containerd/continuity v0.4.1 // indirect
github.com/cosmos/gogoproto v1.4.11 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect
github.com/cstockton/go-conv v1.0.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeS
github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU=
github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg=
github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk=
github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw=
github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo=
github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
Expand Down
2 changes: 1 addition & 1 deletion internal/abci/cometbft/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func (n *CometBftNode) Stop() error {
return n.Node.Stop()
}

// IsCatchup returns true if the node is operating in ccatchup / blocksync
// IsCatchup returns true if the node is operating in catchup / blocksync
// mode. If the node is caught up with the network, it returns false.
func (n *CometBftNode) IsCatchup() bool {
return n.Node.ConsensusReactor().WaitSync()
Expand Down
103 changes: 48 additions & 55 deletions internal/abci/cometbft/privval/privvalidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,28 @@ import (
"fmt"
"time"

cometEd25519 "github.com/cometbft/cometbft/crypto/ed25519"
cmtbytes "github.com/cometbft/cometbft/libs/bytes"
"github.com/cometbft/cometbft/libs/protoio"
tendermintTypes "github.com/cometbft/cometbft/proto/tendermint/types"
cmttime "github.com/cometbft/cometbft/types/time"
"github.com/cosmos/gogoproto/proto"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/protoadapt"

abciTypes "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/crypto"
cometEd25519 "github.com/cometbft/cometbft/crypto/ed25519"
tendermintTypes "github.com/cometbft/cometbft/proto/tendermint/types" // will be api/cometbft/types/v1 in the api(/v1) module
"github.com/cometbft/cometbft/types"

coreTypes "github.com/kwilteam/kwil-db/core/types"
)

// NewValidatorSigner returns a new ValidatorSigner
// it takes in an ed25519 key, and a keyvalue store
// the key values store should NOT be atomically committed with other KV
// stores. Instead, it should simply fsync after every write/commit
// NewValidatorSigner returns a new ValidatorSigner from an ed25519 key and a
// keyvalue store. The key values stored should NOT be atomically committed with
// other KV stores. Instead, it should simply fsync after every write/commit
func NewValidatorSigner(privKey cometEd25519.PrivKey, storer AtomicReadWriter) (*ValidatorSigner, error) {
if len(privKey.Bytes()) != cometEd25519.PrivateKeySize {
return nil, fmt.Errorf("invalid private key size. received: %d, expected: %d",
len(privKey.Bytes()), cometEd25519.PrivateKeySize)
}

lss := &LastSignState{
storer: storer,
}
err := lss.loadLatest()
lss, err := newLastSignState(storer)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -113,7 +110,11 @@ func (v *ValidatorSigner) SignProposal(chainID string, proposal *tendermintTypes
// SignVote signs a vote message
// It is part of the cometTypes.PrivValidator interface
func (v *ValidatorSigner) SignVote(chainID string, vote *tendermintTypes.Vote) error {
height, round, step := vote.Height, vote.Round, VoteToStep(vote)
step, err := voteToStep(vote)
if err != nil {
return err
}
height, round := vote.Height, vote.Round

sameHRS, err := v.lastSignedState.checkHRS(height, round, step)
if err != nil {
Expand All @@ -138,11 +139,10 @@ func (v *ValidatorSigner) SignVote(chainID string, vote *tendermintTypes.Vote) e
return errors.New("unexpected vote extension - extensions are only allowed in non-nil precommits")
}

// We might crash before writing to the wal,
// causing us to try to re-sign for the same HRS.
// If signbytes are the same, use the last signature.
// If they only differ by timestamp, use last timestamp and signature
// Otherwise, return error
// We might crash before writing to the wal, causing us to try to re-sign
// for the same HRS. If signbytes are the same, use the last signature. If
// they only differ by timestamp, use last timestamp and signature.
// Otherwise, return error.
if sameHRS {
if bytes.Equal(signBytes, v.lastSignedState.SignBytes) {
vote.Signature = v.lastSignedState.Signature
Expand Down Expand Up @@ -212,7 +212,7 @@ type LastSignState struct {
Signature []byte `json:"signature"`

// SignBytes is the bytes that were signed by the validator
SignBytes cmtbytes.HexBytes `json:"sign_bytes"`
SignBytes coreTypes.HexBytes `json:"sign_bytes"`

// storer is the store that this lastSignState is persisted to
storer AtomicReadWriter
Expand All @@ -228,29 +228,22 @@ func (l *LastSignState) store() error {
return l.storer.Write(bts)
}

// loadLatest loads the latest lastSignState from the given KV store
// if none exists, it sets all fields to zero values
func (l *LastSignState) loadLatest() (err error) {
func newLastSignState(storer AtomicReadWriter) (*LastSignState, error) {
l := &LastSignState{storer: storer}

bts, err := l.storer.Read()
if err != nil {
return err
return nil, err
}

if bts == nil {
l.setZero()
return nil
if len(bts) == 0 {
return l, nil
}

return json.Unmarshal(bts, l)
}

// setZero sets all fields to zero values
func (l *LastSignState) setZero() {
l.Height = 0
l.Round = 0
l.Step = 0
l.Signature = nil
l.SignBytes = nil
if err = json.Unmarshal(bts, l); err != nil {
return nil, err
}
return l, nil
}

// checkHRS checks that the given height, round, and step match the lastSignState.
Expand Down Expand Up @@ -295,60 +288,59 @@ func (lss *LastSignState) checkHRS(height int64, round int32, step int8) (bool,
// and vote extension signatures).
func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {
var lastVote, newVote tendermintTypes.CanonicalVote
if err := protoio.UnmarshalDelimited(lastSignBytes, &lastVote); err != nil {
if err := abciTypes.ReadMessage(bytes.NewReader(lastSignBytes), &lastVote); err != nil {
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into vote: %v", err))
}
if err := protoio.UnmarshalDelimited(newSignBytes, &newVote); err != nil {
if err := abciTypes.ReadMessage(bytes.NewReader(newSignBytes), &newVote); err != nil {
panic(fmt.Sprintf("signBytes cannot be unmarshalled into vote: %v", err))
}

lastTime := lastVote.Timestamp
// set the times to the same value and check equality
now := cmttime.Now()
now := time.Now().UTC()
lastVote.Timestamp = now
newVote.Timestamp = now

return lastTime, proto.Equal(&newVote, &lastVote)
return lastTime, proto.Equal(protoadapt.MessageV2Of(&newVote), protoadapt.MessageV2Of(&lastVote))
}

// returns the timestamp from the lastSignBytes.
// returns true if the only difference in the proposals is their timestamp
func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) {
var lastProposal, newProposal tendermintTypes.CanonicalProposal
if err := protoio.UnmarshalDelimited(lastSignBytes, &lastProposal); err != nil {
if err := abciTypes.ReadMessage(bytes.NewReader(lastSignBytes), &lastProposal); err != nil {
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into proposal: %v", err))
}
if err := protoio.UnmarshalDelimited(newSignBytes, &newProposal); err != nil {
if err := abciTypes.ReadMessage(bytes.NewReader(newSignBytes), &newProposal); err != nil {
panic(fmt.Sprintf("signBytes cannot be unmarshalled into proposal: %v", err))
}

lastTime := lastProposal.Timestamp
// set the times to the same value and check equality
now := cmttime.Now()
now := time.Now().UTC()
lastProposal.Timestamp = now
newProposal.Timestamp = now

return lastTime, proto.Equal(&newProposal, &lastProposal)
return lastTime, proto.Equal(protoadapt.MessageV2Of(&newProposal), protoadapt.MessageV2Of(&lastProposal))
}

// this should be unexported, but is needed for testing
// A vote is either stepPrevote or stepPrecommit.
func VoteToStep(vote *tendermintTypes.Vote) int8 {
func voteToStep(vote *tendermintTypes.Vote) (int8, error) {
switch vote.Type {
case tendermintTypes.PrevoteType:
return stepPrevote
return stepPrevote, nil
case tendermintTypes.PrecommitType:
return stepPrecommit
return stepPrecommit, nil
default:
panic(fmt.Sprintf("Unknown vote type: %v", vote.Type))
return 0, fmt.Errorf("%w: %v", ErrUnknownVoteType, vote.Type)
}
}

const (
stepNone int8 = 0 // Used to distinguish the initial state
stepPropose int8 = 1
stepPrevote int8 = 2
stepPrecommit int8 = 3
stepNone int8 = iota // Used to distinguish the initial state
stepPropose
stepPrevote
stepPrecommit
)

// AtomicReadWriter is an interface for any store
Expand All @@ -366,4 +358,5 @@ var (
ErrRoundRegression = errors.New("round regression")
ErrStepRegression = errors.New("step regression")
ErrNilSignature = errors.New("signature is nil")
ErrUnknownVoteType = errors.New("unknown vote type")
)
Loading

0 comments on commit bae8cfb

Please sign in to comment.