Skip to content
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

feat(crypto/bls12381): signature aggregation #11

Merged
merged 127 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
ecaeb63
feat(crypto/bls12381): signature aggregation
melekes Jan 7, 2025
ca71e12
add a test for MakeBLSCommit
melekes Jan 7, 2025
36b7c72
fix TestDifferByTimestamp
melekes Jan 7, 2025
654bc38
actually verify the commit
melekes Jan 7, 2025
4511acd
do not check the 2nd sig if it's empty
melekes Jan 7, 2025
a535f96
Merge branch 'bera-v1.x' into melekes/bls-signature-aggregation
melekes Jan 7, 2025
4b2afec
fix linter errors
melekes Jan 7, 2025
fcb300b
attempt to verify agg commits first
melekes Jan 8, 2025
80d8359
add sergio comment
melekes Jan 8, 2025
141d1a2
refactor verifyAggregatedCommit
melekes Jan 8, 2025
94b8fd6
allow empty signatures
melekes Jan 8, 2025
f3b1bb7
guard against nil PubKey
melekes Jan 8, 2025
6b0b06e
leave the possibility of using vote extensions
melekes Jan 8, 2025
f752e1e
add separate blockid flags
melekes Jan 8, 2025
0c7153f
remove tags from generator and runner targets
melekes Jan 8, 2025
0800a7e
comment out test
melekes Jan 8, 2025
12c0ad1
remove Timestamp from Vote and CommitSig
melekes Jan 9, 2025
8f82994
fix TestPrivvalVectors
melekes Jan 9, 2025
7ed479b
fix evidence tests and add reserved field
melekes Jan 9, 2025
0093df8
fix TestEvidencePoolBasic, TestEvidenceVectors
melekes Jan 9, 2025
cd6f8ad
reserve field
melekes Jan 9, 2025
e5932a4
check we have signatures for nil before verifying
melekes Jan 9, 2025
089d45e
allow BLS keys for execution
melekes Jan 9, 2025
ae6c643
change key_type to bls12_381 in ci.toml
melekes Jan 9, 2025
a2e8326
add bls12381 tag to runner
melekes Jan 9, 2025
c925031
Updated `go-git` dep to address vulnerabilities.
alesforz Jan 9, 2025
427e875
fix Ci err
melekes Jan 9, 2025
87e3312
fix
melekes Jan 9, 2025
38f96e3
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
alesforz Jan 9, 2025
092cb5b
updated e2e Dockerfile to fix pkg download error
alesforz Jan 9, 2025
b56a29e
validation.go functions panic if keys aren't BLS12_381
alesforz Jan 9, 2025
fb07cde
deleted dead code in validation.go
alesforz Jan 9, 2025
2b2d2d5
removed bls1381 build flag
alesforz Jan 9, 2025
1fd3cd1
added more panics if keys aren't BLS12-381
alesforz Jan 9, 2025
12ba08a
Removed skipping verification
jmalicevic Jan 9, 2025
87fd68b
Added ifs before panic
jmalicevic Jan 9, 2025
8d7ce78
Re-introduce timestamp in Vote
jmalicevic Jan 9, 2025
5905680
Partially removed fromtests
jmalicevic Jan 10, 2025
9c90795
Fixed more tests
jmalicevic Jan 10, 2025
a9349b3
Revert "Fixed more tests"
melekes Jan 10, 2025
71458b0
Revert "Partially removed fromtests"
melekes Jan 10, 2025
641d6ac
Revert "Added ifs before panic"
melekes Jan 10, 2025
21a0137
Revert "added more panics if keys aren't BLS12-381"
melekes Jan 10, 2025
97cf653
Revert "deleted dead code in validation.go"
melekes Jan 10, 2025
edc92e2
Revert "validation.go functions panic if keys aren't BLS12_381"
melekes Jan 10, 2025
3881bf3
only allow ed25519 in tests
melekes Jan 10, 2025
6677c0c
fix tests
melekes Jan 10, 2025
c66534e
fix remaining tests
melekes Jan 10, 2025
f53d1ca
fix remaining comments
melekes Jan 10, 2025
b24e14c
fix TestConsMsgsVectors
melekes Jan 10, 2025
b01383a
comment out lunatic attack tests
melekes Jan 10, 2025
ab29251
updated Makefile for ARM architectures
alesforz Jan 10, 2025
6a9e7bd
Update light/client.go
melekes Jan 10, 2025
5463386
Apply suggestions from code review
melekes Jan 10, 2025
c8ccadf
set default key to bls12381
melekes Jan 10, 2025
0792f63
return err if aggregated commit didn't pass isAggregatedCommit
melekes Jan 10, 2025
5605bca
guard against dup sigs
melekes Jan 10, 2025
40f5816
types: apply Timestamp check to all sigs
melekes Jan 10, 2025
8139212
fix(e2e): fix BLS-related failures (#3726)
sergio-mena Aug 16, 2024
95455d5
Disabled ARM from build process
alesforz Jan 10, 2025
de99d54
bls12381 Pubkey() now returns a pointer
alesforz Jan 10, 2025
1f478ec
Fix syntax to please the linter
alesforz Jan 10, 2025
4fffebf
fixed TestPubKey_MarshalJSON panic
alesforz Jan 10, 2025
256a329
Fixed panicing tests because of incorrect signature timestamp
alesforz Jan 10, 2025
3c4c3a8
Revert "bls12381 Pubkey() now returns a pointer"
alesforz Jan 10, 2025
c71b2cc
Fixed panicing tests because of incorrect PubKey type
alesforz Jan 10, 2025
82930be
Revert "fixed TestPubKey_MarshalJSON panic"
alesforz Jan 10, 2025
0203b88
Disabled vote extension in ci.toml
alesforz Jan 10, 2025
701204d
Added bool flag to enable/disable signature verification when convert…
alesforz Jan 10, 2025
c4a6f43
Revert "Added bool flag to enable/disable signature verification when…
sergio-mena Jan 11, 2025
46423c8
First part: adapt structures to support commits as
sergio-mena Jan 11, 2025
1a36a1b
Added Commit message and send this instead of Vote when aggregated co…
jmalicevic Jan 11, 2025
b9c5a03
revert log level and script change
jmalicevic Jan 11, 2025
2670544
Fixed block_test and validation_test
jmalicevic Jan 11, 2025
b48a625
Implement AddCommit in Consensus state
sergio-mena Jan 11, 2025
42d65c8
Call AddCommit when a new commit comes in during catchup
jmalicevic Jan 11, 2025
5293186
address comment. fixed missing enterNewRound
sergio-mena Jan 11, 2025
d0de97d
register json CommitMessage
sergio-mena Jan 11, 2025
d3c58c7
Block marshal test and addressed PR comments
jmalicevic Jan 11, 2025
236829e
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
jmalicevic Jan 11, 2025
cfed49b
Removed commit validation from message receive function
jmalicevic Jan 11, 2025
8650f2d
Commented out added
jmalicevic Jan 11, 2025
81fc562
minor changes
sergio-mena Jan 11, 2025
303a6be
Added validation
jmalicevic Jan 11, 2025
10d7cd9
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
jmalicevic Jan 11, 2025
2e27d2d
check commit is aggregated
sergio-mena Jan 11, 2025
d98fefc
fix PBTS on e2e generator
sergio-mena Jan 11, 2025
9739076
use the right aggregated commit checker
sergio-mena Jan 11, 2025
6266c88
Fixed race condition in Commit; fixed wrong cast check to BLS pub key
sergio-mena Jan 11, 2025
15e1cfc
remove some TODOs addressed
sergio-mena Jan 11, 2025
3caca93
get uts to compile
jmalicevic Jan 11, 2025
ebfba32
reduce log verbosity
sergio-mena Jan 11, 2025
ff1a813
fixed bug: unaggregated commit at the end of Consensus
sergio-mena Jan 11, 2025
c30e164
Fixed JSON Marshalling
jmalicevic Jan 11, 2025
9af3d65
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
jmalicevic Jan 11, 2025
f314951
Fixed bug: late nodes overwhelmed with Commits, and they verify all o…
sergio-mena Jan 12, 2025
b4e8af3
Revert "Fixed JSON Marshalling"
sergio-mena Jan 12, 2025
af1d05f
Fixed consensus dump RPC
sergio-mena Jan 12, 2025
eb5a08d
Fixed TestReactorValidatorSetChanges
sergio-mena Jan 12, 2025
1217b48
More UT fixes
sergio-mena Jan 12, 2025
4cead62
Fixed WALCrashTest and properly set genesis file ot use bls
jmalicevic Jan 12, 2025
fe2b097
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
jmalicevic Jan 12, 2025
d53342f
revert test timout wait time
jmalicevic Jan 12, 2025
4f7bd20
More UT fixes
sergio-mena Jan 12, 2025
603ac3c
TestConsensusParamsUpdate_EnableHeight
jmalicevic Jan 12, 2025
b44473b
TestConsensusParamsUpdate`
jmalicevic Jan 12, 2025
9d7c8a3
Fix TestProtoUpgrade
jmalicevic Jan 12, 2025
78b03f6
Deleted TestLastCommitJSON`
jmalicevic Jan 12, 2025
d0c6115
Deleted TestLastCommitJSON`
jmalicevic Jan 12, 2025
804d022
Fixed TestBasicGenesisDoc
jmalicevic Jan 12, 2025
ffbba5e
Fix more UTs
sergio-mena Jan 12, 2025
bf4c3b5
one more UT
sergio-mena Jan 12, 2025
68ffc1b
One more
sergio-mena Jan 12, 2025
1ac3231
more UTs
sergio-mena Jan 12, 2025
2183f4e
one more UT
sergio-mena Jan 12, 2025
15b4667
two more UTs
sergio-mena Jan 12, 2025
faedd63
Appease linter
sergio-mena Jan 12, 2025
27ccb72
fix build
sergio-mena Jan 12, 2025
8893054
Appease linter part II
sergio-mena Jan 12, 2025
c3341da
fix abci tests
sergio-mena Jan 12, 2025
0253b40
Appease linter part III
sergio-mena Jan 12, 2025
4dea906
Use bls in validator update of kvstore
jmalicevic Jan 12, 2025
12195a8
Merge branch 'melekes/bls-signature-aggregation' of github.com:meleke…
jmalicevic Jan 12, 2025
9bb2dfc
removed unused import
jmalicevic Jan 12, 2025
156f344
reduce verbosity
sergio-mena Jan 12, 2025
235ba07
Fixed bug that caused blocks to be incorrectly marked as 'missed'.
alesforz Jan 13, 2025
b7a9fdf
Merge remote-tracking branch 'origin/bera-v1.x' into melekes/bls-sign…
alesforz Jan 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions crypto/bls12381/aggregation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//go:build bls12381

package bls12381

import (
"errors"

blst "github.com/supranational/blst/bindings/go"
)

// ErrAggregation is returned when aggregation fails.
var ErrAggregation = errors.New("bls12381: failed to aggregate signatures")

// For minimal-pubkey-size operations.
//
// Changing this to 'minimal-signature-size' would render CometBFT not Ethereum
// compatible.
type (
blstAggregateSignature = blst.P2Aggregate
)

// AggregateSignatures aggregates the given compressed signatures.
//
// Does not group-check the signatures.
func AggregateSignatures(sigsToAgg [][]byte) ([]byte, error) {
var agProj blstAggregateSignature
if !agProj.AggregateCompressed(sigsToAgg, false) {
melekes marked this conversation as resolved.
Show resolved Hide resolved
return nil, ErrAggregation
}
agSig := agProj.ToAffine()
return agSig.Compress(), nil
}

// VerifyAggregateSignature verifies the given compressed aggregate signature.
//
// Group-checks the signature.
func VerifyAggregateSignature(agSigCompressed []byte, pubks []*PubKey, msg []byte) bool {
agSig := new(blstSignature).Uncompress(agSigCompressed)
if agSig == nil {
return false
}
blsPubKeys := make([]*blstPublicKey, len(pubks))
for i, pubk := range pubks {
blsPubKeys[i] = pubk.pk
}
return agSig.FastAggregateVerify(true, blsPubKeys, msg, dstMinPk)
}
15 changes: 15 additions & 0 deletions crypto/bls12381/aggregation_nop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//go:build !bls12381

package bls12381

import "errors"

// AggregateSignatures is a nop.
func AggregateSignatures([][]byte) ([]byte, error) {
return nil, errors.New("bls12381 is disabled")
}

// VerifyAggregateSignature is a nop.
func VerifyAggregateSignature([]byte, []*PubKey, []byte) bool {
return false
}
59 changes: 59 additions & 0 deletions crypto/bls12381/aggregation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//go:build bls12381

package bls12381_test

import (
"testing"

"github.com/cometbft/cometbft/crypto/bls12381"
"github.com/stretchr/testify/require"
)

func TestAggregateAndVerify(t *testing.T) {
// Generate private keys.
genPrivKeyFn := func() *bls12381.PrivKey {
k, err := bls12381.GenPrivKey()
if err != nil {
panic(err)
}
melekes marked this conversation as resolved.
Show resolved Hide resolved
return k
}

privateKeys := []*bls12381.PrivKey{
genPrivKeyFn(),
genPrivKeyFn(),
genPrivKeyFn(),
}

msg := []byte("hello world")

// Generate signatures.
signatures := make([][]byte, len(privateKeys))
for i, privKey := range privateKeys {
sig, err := privKey.Sign(msg)
require.NoError(t, err)
signatures[i] = sig

valid := privKey.PubKey().VerifySignature(msg, sig)
require.True(t, valid)
}

// Aggregate signatures.
aggregatedSignature, err := bls12381.AggregateSignatures(signatures)
require.NoError(t, err)
require.NotNil(t, aggregatedSignature)

pubKeys := make([]*bls12381.PubKey, len(privateKeys))
for i, privKey := range privateKeys {
pubKeys[i] = privKey.PubKey().(*bls12381.PubKey)
}

// Verify aggregated signature
valid := bls12381.VerifyAggregateSignature(aggregatedSignature, pubKeys, msg)
require.True(t, valid)

// Test with invalid aggregated signature
invalidSignature := []byte("Invalid")
valid = bls12381.VerifyAggregateSignature(invalidSignature, pubKeys, msg)
require.False(t, valid)
}
melekes marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions crypto/bls12381/doc.go
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
// bls12-381 curve implementation using github.com/supranational/blst under the
// hood.
//
// This package is disabled by default. To enable it, use the `bls12381` build tag.
package bls12381
12 changes: 5 additions & 7 deletions crypto/bls12381/key_bls12381.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,16 @@ var (
// of a more comprehensive subgroup check on the key.
ErrInfinitePubKey = errors.New("bls12381: pubkey is infinite")

dstMinSig = []byte("BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_")
dstMinPk = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_")
melekes marked this conversation as resolved.
Show resolved Hide resolved
)

// For minimal-pubkey-size operations.
//
// Changing this to 'minimal-signature-size' would render CometBFT not Ethereum
// compatible.
type (
blstPublicKey = blst.P1Affine
blstSignature = blst.P2Affine
blstAggregateSignature = blst.P1Aggregate
blstAggregatePublicKey = blst.P2Aggregate
blstPublicKey = blst.P1Affine
blstSignature = blst.P2Affine
)

// -------------------------------------.
Expand Down Expand Up @@ -103,7 +101,7 @@ func (PrivKey) Type() string {

// Sign signs the given byte array.
func (privKey PrivKey) Sign(msg []byte) ([]byte, error) {
signature := new(blstSignature).Sign(privKey.sk, msg, dstMinSig)
signature := new(blstSignature).Sign(privKey.sk, msg, dstMinPk)
melekes marked this conversation as resolved.
Show resolved Hide resolved
return signature.Compress(), nil
}

Expand Down Expand Up @@ -207,7 +205,7 @@ func (pubKey PubKey) VerifySignature(msg, sig []byte) bool {
return false
}

return signature.Verify(false, pubKey.pk, false, msg, dstMinSig)
return signature.Verify(false, pubKey.pk, false, msg, dstMinPk)
}

// Bytes returns the byte format.
Expand Down
12 changes: 12 additions & 0 deletions docs/guides/app-dev/app-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,15 @@ See the following for more extensive documentation:
- [CometBFT RPC Docs](https://docs.cometbft.com/main/rpc/)
- [CometBFT in Production](../../explanation/core/running-in-production.md)
- [ABCI spec](https://github.com/cometbft/cometbft/tree/main/spec/abci)

## BLS12-381 aggregation

CometBFT supports aggregation for BLS12-381 signatures. This drastically
reduces the size of the blockchain and verification time.

The aggregation won't work if vote extensions are enabled!

To prevent [Rogue Key
Attacks](https://hackmd.io/@benjaminion/bls12-381#Rogue-key-attacks) a proof of
possession (PoP) must be required from validators upon the registration. This
is left to the ABCI application to implement.
18 changes: 16 additions & 2 deletions internal/consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
cmtproto "github.com/cometbft/cometbft/api/cometbft/types/v1"
cfg "github.com/cometbft/cometbft/config"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/crypto/bls12381"
cstypes "github.com/cometbft/cometbft/internal/consensus/types"
cmtevents "github.com/cometbft/cometbft/internal/events"
"github.com/cometbft/cometbft/internal/fail"
Expand Down Expand Up @@ -1310,8 +1311,21 @@ func (cs *State) createProposalBlock(ctx context.Context) (*types.Block, error)
lastExtCommit = &types.ExtendedCommit{}

case cs.LastCommit.HasTwoThirdsMajority():
// Make the commit from LastCommit
lastExtCommit = cs.LastCommit.MakeExtendedCommit(cs.state.ConsensusParams.Feature)
// Make the commit from LastCommit.
//
// Note we can't aggregate a commit when vote extensions are enabled
// because votes are different.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, I might be wrong, but I don't agree with this.
When vote extensions are enabled, there is one signature for the vote and another signature for the vote extension.
I agree the extension signatures cannot be aggregated, as the extensions can be different.
But the vote themselves can still be aggregated (assuming you remove the timestamp field, or set it always to 0-time).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. But then again, who is going to verify vote extensions? There's no point in aggregating votes if you need to verify vote extensions using individual verification (signature.Verify).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the 2nd thought, we don't verify vote extensions in VerifyCommit, so I think using them while aggregating vote signatures is okay. 6b0b06e (#11)

_, blsKey := cs.privValidatorPubKey.(*bls12381.PubKey)
melekes marked this conversation as resolved.
Show resolved Hide resolved
canBeAggregated := blsKey &&
melekes marked this conversation as resolved.
Show resolved Hide resolved
cs.state.Validators.AllKeysHaveSameType()
if canBeAggregated {
if cs.state.ConsensusParams.Feature.VoteExtensionsEnabled(cs.Height) {
panic("VoteExtensions are not supported with BLS aggregation")
}
lastExtCommit = cs.LastCommit.MakeBLSCommit()
} else {
lastExtCommit = cs.LastCommit.MakeExtendedCommit(cs.state.ConsensusParams.Feature)
}

default: // This shouldn't happen.
return nil, ErrProposalWithoutPreviousCommit
Expand Down
52 changes: 26 additions & 26 deletions privval/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,32 +358,32 @@ func TestDifferByTimestamp(t *testing.T) {
}

// test vote
{
voteType := types.PrevoteType
blockID := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{}}
vote := newVote(privVal.Key.Address, height, round, voteType, blockID)
v := vote.ToProto()
err := privVal.SignVote("mychainid", v, false)
require.NoError(t, err, "expected no error signing vote")

signBytes := types.VoteSignBytes(chainID, v)
sig := v.Signature
extSig := v.ExtensionSignature
timeStamp := vote.Timestamp

// manipulate the timestamp. should get changed back
v.Timestamp = v.Timestamp.Add(time.Millisecond)
var emptySig []byte
v.Signature = emptySig
v.ExtensionSignature = emptySig
err = privVal.SignVote("mychainid", v, false)
require.NoError(t, err, "expected no error on signing same vote")

assert.Equal(t, timeStamp, v.Timestamp)
assert.Equal(t, signBytes, types.VoteSignBytes(chainID, v))
assert.Equal(t, sig, v.Signature)
assert.Equal(t, extSig, v.ExtensionSignature)
}
// {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we delete this or modify it so it works with the new scheme?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove

// voteType := types.PrevoteType
// blockID := types.BlockID{Hash: randbytes, PartSetHeader: types.PartSetHeader{}}
// vote := newVote(privVal.Key.Address, height, round, voteType, blockID)
// v := vote.ToProto()
// err := privVal.SignVote("mychainid", v, false)
// require.NoError(t, err, "expected no error signing vote")

// signBytes := types.VoteSignBytes(chainID, v)
// sig := v.Signature
// extSig := v.ExtensionSignature
// timeStamp := vote.Timestamp

// // manipulate the timestamp. should get changed back
// v.Timestamp = v.Timestamp.Add(time.Millisecond)
// var emptySig []byte
// v.Signature = emptySig
// v.ExtensionSignature = emptySig
// err = privVal.SignVote("mychainid", v, false)
// require.NoError(t, err, "expected no error on signing same vote")

// assert.Equal(t, timeStamp, v.Timestamp)
// assert.Equal(t, signBytes, types.VoteSignBytes(chainID, v))
// assert.Equal(t, sig, v.Signature)
// assert.Equal(t, extSig, v.ExtensionSignature)
// }
}

func TestVoteExtensionsAreSignedIfSignExtensionIsTrue(t *testing.T) {
Expand Down
5 changes: 2 additions & 3 deletions test/e2e/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
COMETBFT_BUILD_OPTIONS += badgerdb,rocksdb,clock_skew,bls12381
IMAGE_TAG=cometbft/e2e-node:local-version

include ../../common.mk
Expand Down Expand Up @@ -35,10 +34,10 @@ node:
go build -race $(BUILD_FLAGS) -tags '$(BUILD_TAGS)' -o build/node ./node

generator:
go build -o build/generator ./generator
go build -tags '$(BUILD_TAGS)' -o build/generator ./generator

runner:
go build -o build/runner ./runner
go build -tags '$(BUILD_TAGS)' -o build/runner ./runner

lint:
@echo "--> Running linter for E2E"
Expand Down
17 changes: 9 additions & 8 deletions types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

cmtversion "github.com/cometbft/cometbft/api/cometbft/version/v1"
"github.com/cometbft/cometbft/crypto"
"github.com/cometbft/cometbft/crypto/ed25519"
"github.com/cometbft/cometbft/crypto/merkle"
"github.com/cometbft/cometbft/crypto/tmhash"
"github.com/cometbft/cometbft/internal/bits"
Expand All @@ -34,7 +35,7 @@ func TestBlockAddEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)

voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), false)
require.NoError(t, err)

Expand All @@ -55,7 +56,7 @@ func TestBlockValidateBasic(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)

voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false)
voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), false)
require.NoError(t, err)
commit := extCommit.ToCommit()
Expand Down Expand Up @@ -126,7 +127,7 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)

voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), false)
require.NoError(t, err)

Expand All @@ -146,7 +147,7 @@ func TestBlockHashesTo(t *testing.T) {

lastID := makeBlockIDRandom()
h := int64(3)
voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false)
voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), false)
require.NoError(t, err)

Expand Down Expand Up @@ -227,7 +228,7 @@ func TestNilDataHashDoesntCrash(t *testing.T) {
func TestCommit(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, true)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, true, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), true)
require.NoError(t, err)

Expand Down Expand Up @@ -432,7 +433,7 @@ func TestMaxHeaderBytes(t *testing.T) {
func randCommit(now time.Time) *Commit {
lastID := makeBlockIDRandom()
h := int64(3)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false)
voteSet, _, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, false, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, now, false)
if err != nil {
panic(err)
Expand Down Expand Up @@ -608,7 +609,7 @@ func TestExtendedCommitToVoteSet(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)

voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, true)
voteSet, valSet, vals := randVoteSet(h-1, 1, PrecommitType, 10, 1, true, ed25519.KeyType)
extCommit, err := MakeExtCommit(lastID, h-1, 1, voteSet, vals, cmttime.Now(), true)
require.NoError(t, err)

Expand Down Expand Up @@ -668,7 +669,7 @@ func TestCommitToVoteSetWithVotesForNilBlock(t *testing.T) {
}

for _, tc := range testCases {
voteSet, valSet, vals := randVoteSet(height-1, round, PrecommitType, tc.numValidators, 1, false)
voteSet, valSet, vals := randVoteSet(height-1, round, PrecommitType, tc.numValidators, 1, false, ed25519.KeyType)

vi := int32(0)
for n := range tc.blockIDs {
Expand Down
14 changes: 8 additions & 6 deletions types/canonical.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ func CanonicalizeProposal(chainID string, proposal *cmtproto.Proposal) cmtproto.
// relating to vote extensions.
func CanonicalizeVote(chainID string, vote *cmtproto.Vote) cmtproto.CanonicalVote {
return cmtproto.CanonicalVote{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading one previous comment from Jasmina, I realise we need to add the necessary checks to make sure PBTS is active. Because this code no longer works with BFT Time (even if we decided to leave the timestamps in the commit structure, they would no longer be signed, so any full node on the way can now tamper with its value)

Type: vote.Type,
Height: vote.Height, // encoded as sfixed64
Round: int64(vote.Round), // encoded as sfixed64
BlockID: CanonicalizeBlockID(vote.BlockID),
Timestamp: vote.Timestamp,
ChainID: chainID,
Type: vote.Type,
Height: vote.Height, // encoded as sfixed64
Round: int64(vote.Round), // encoded as sfixed64
BlockID: CanonicalizeBlockID(vote.BlockID),
// Timestamp is not included in the canonical vote
// because we won't be able to aggregate votes with different timestamps.
// Timestamp: vote.Timestamp,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is probably the biggest breaking change - removing Timestamp from vote sign bytes

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am double checking, I think it is ok because this is only for the canonical vote. Because vote timestamps are used to compute the block time when using BFT time.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also remove the timestamp field from both vote structures: the one internal to comet, and the protobuf-generated one. Leaving that field there only adds confusion IMO (let me know if you want to discuss)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also remove the timestamp field from both vote structures: the one internal to comet, and the protobuf-generated one. Leaving that field there only adds confusion IMO (let me know if you want to discuss)

Should it go hand in hand with making the PBTS the default choice + ripping off median time?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The decision here was to add preemptive panics so we fail early in case CometBFT is misconfigured.

ChainID: chainID,
}
}

Expand Down
Loading
Loading