Skip to content

Commit

Permalink
test(types): sign_bytes tests synchronized with rs-tenderdash-abci (#623
Browse files Browse the repository at this point in the history
)

* test(types): sign_bytes tests synchronized with rs-tenderdash-abci

* test(types): make some tests deterministic
  • Loading branch information
lklimek authored Apr 18, 2023
1 parent a8ff41f commit 55bb222
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 28 deletions.
10 changes: 10 additions & 0 deletions internal/consensus/vote_signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"

bls "github.com/dashpay/bls-signatures/go-bindings"

cstypes "github.com/tendermint/tendermint/internal/consensus/types"
sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/state/mocks"
Expand Down Expand Up @@ -133,6 +135,14 @@ func TestVoteSigner_signAddVote(t *testing.T) {
Return(nil)
vote := signer.signAddVote(ctx, &stateData, tc.msgType, tc.blockID)
assert.NotNil(t, vote)
key, err := privVal.GetPubKey(ctx, valSet.QuorumHash)
assert.NoError(t, err)

key1, err := bls.G1ElementFromBytes(key.Bytes())
assert.NoError(t, err)

t.Logf("key: %x", key1.Serialize())
t.Logf("%+v", vote.VoteExtensions[tmproto.VoteExtensionType_THRESHOLD_RECOVER])
})
}
}
99 changes: 76 additions & 23 deletions proto/tendermint/types/types_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"bytes"
"encoding/hex"
"strconv"
"testing"
time "time"
Expand All @@ -9,39 +11,90 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/internal/libs/protoio"
"github.com/tendermint/tendermint/libs/rand"
)

// TestVoteSignBytes checks if sign bytes are generated correctly.
//
// This test is synchronized with tests in github.com/dashpay/rs-tenderdash-abci
func TestVoteSignBytes(t *testing.T) {
const (
height = 1
round = 2
height = 1
round = 2
chainID = "some-chain"
)
h := rand.Bytes(crypto.HashSize)
stateID := StateID{
AppVersion: 2,
Height: height,
AppHash: h,
CoreChainLockedHeight: 1,
Time: *gogotypes.TimestampNow(),
ts := &gogotypes.Timestamp{}
h := bytes.Repeat([]byte{1, 2, 3, 4}, 8)

type testCase struct {
stateID StateID
vote Vote
expectHex string
}
sidHash := stateID.Hash()
v := Vote{
Type: PrecommitType,
Height: height,
Round: round,
BlockID: BlockID{
Hash: h,
PartSetHeader: PartSetHeader{Total: 1, Hash: h},
StateID: sidHash,

testCases := []testCase{
0: {
stateID: StateID{
AppVersion: 2,
Height: height,
AppHash: h,
CoreChainLockedHeight: 1,
Time: *ts,
},
vote: Vote{
Type: PrevoteType,
Height: height,
Round: round,
BlockID: BlockID{
Hash: h,
PartSetHeader: PartSetHeader{Total: 1, Hash: h},
StateID: []byte{}, // filled later
},
},
expectHex: "0100000001000000000000000200000000000000fb7c89bf010a91d50f890455582b7fed0c346e53ab" +
"33df7da0bcd85c10fa92ead7509905b5407ee72dadd93b4ae70a24ad8a7755fc677acd2b215710a05cfc47736" +
"f6d652d636861696e",
},
1: {
stateID: StateID{
AppVersion: 2,
Height: height,
AppHash: h,
CoreChainLockedHeight: 1,
Time: *ts,
},
vote: Vote{
Type: PrecommitType,
Height: height,
Round: round,
BlockID: BlockID{
Hash: h,
PartSetHeader: PartSetHeader{Total: 1, Hash: h},
StateID: []byte{}, // filled later
},
},
expectHex: "0200000001000000000000000200000000000000fb7c89bf010a91d50f8904" +
"55582b7fed0c346e53ab33df7da0bcd85c10fa92ead7509905b5407ee72dadd93b4ae70a2" +
"4ad8a7755fc677acd2b215710a05cfc47736f6d652d636861696e",
},
}
const chainID = "some-chain"
sb, err := v.SignBytes(chainID)
require.NoError(t, err)
assert.Len(t, sb, 4+8+8+32+32+len(chainID)) // type(4) + height(8) + round(8) + blockID(32) + stateID(32)

for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
vote := tc.vote
vote.BlockID.StateID = tc.stateID.Hash()
expected, err := hex.DecodeString(tc.expectHex)
require.NoError(t, err)

sb, err := vote.SignBytes(chainID)
require.NoError(t, err)
assert.Len(t, sb, 4+8+8+32+32+len(chainID)) // type(4) + height(8) + round(8) + blockID(32) + stateID(32)
assert.EqualValues(t, expected, sb)

t.Logf("state ID hash: %x sign bytes: %x", vote.BlockID.StateID, sb)
})
}
}

func TestStateID_Equals(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions types/quorum_sign_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ import (
"github.com/tendermint/tendermint/proto/tendermint/types"
)

func TestBlockRequestID(t *testing.T) {
expected := tmbytes.MustHexDecode("28277743e77872951df01bda93a344feca2435e113b8824ce636eada665aadd5")
got := BlockRequestID(12, 34)
assert.EqualValues(t, expected, got)
}

func TestMakeBlockSignID(t *testing.T) {
const chainID = "dash-platform"
testCases := []struct {
Expand Down
49 changes: 44 additions & 5 deletions types/vote_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package types

import (
"bytes"
"context"
"fmt"
"testing"

bls "github.com/dashpay/bls-signatures/go-bindings"
"github.com/dashpay/dashd-go/btcjson"
"github.com/gogo/protobuf/proto"
gogotypes "github.com/gogo/protobuf/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -44,19 +47,31 @@ func examplePrecommit(t testing.TB) *Vote {
}

func exampleVote(tb testing.TB, t byte) *Vote {
tb.Helper()
const (
height = 12345
round = 2
)
appHash := bytes.Repeat([]byte{1, 2, 3, 4}, 8)

tb.Helper()
stateID := tmproto.StateID{
Height: height,
AppHash: appHash,
AppVersion: StateIDVersion,
CoreChainLockedHeight: 3,
Time: gogotypes.Timestamp{},
}
return &Vote{
Type: tmproto.SignedMsgType(t),
Height: 12345,
Round: 2,
Height: height,
Round: round,
BlockID: BlockID{
Hash: crypto.Checksum([]byte("blockID_hash")),
PartSetHeader: PartSetHeader{
Total: 1000000,
Hash: crypto.Checksum([]byte("blockID_part_set_header_hash")),
},
StateID: RandStateID().Hash(),
StateID: stateID.Hash(),
},
ValidatorProTxHash: crypto.ProTxHashFromSeedBytes([]byte("validator_pro_tx_hash")),
ValidatorIndex: 56789,
Expand Down Expand Up @@ -253,7 +268,7 @@ func TestVoteVerifySignature(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

quorumHash := crypto.RandQuorumHash()
quorumHash := make([]byte, 32)
privVal := NewMockPVForQuorum(quorumHash)
pubkey, err := privVal.GetPubKey(context.Background(), quorumHash)
require.NoError(t, err)
Expand All @@ -271,6 +286,15 @@ func TestVoteVerifySignature(t *testing.T) {
valid := pubkey.VerifySignatureDigest(signID, v.BlockSignature)
require.True(t, valid)

g1, err := bls.G1ElementFromBytes(pubkey.Bytes())
require.NoError(t, err)
signBytes, err := v.SignBytes("test_chain_id")
require.NoError(t, err)
t.Logf("-> pubkey: %s\n-> sign bytes: %x\n-> signID: %x\n-> signature: %x",
g1.HexString(),
signBytes,
signID,
v.BlockSignature)
// serialize, deserialize and verify again....
precommit := new(tmproto.Vote)
bs, err := proto.Marshal(v)
Expand Down Expand Up @@ -615,6 +639,21 @@ func TestInvalidPrecommitExtensions(t *testing.T) {
}
}

// TestVoteExtensionsSignBytes checks if vote extension sign bytes are generated correctly.
//
// This test is synchronized with tests from github.com/dashpay/rs-tenderdash-abci
func TestVoteExtensionsSignBytes(t *testing.T) {
expect := hexBytesFromString(t, "2a0a080102030405060708110100000000000000190200000000000000220a736f6d652d636861696e2801")
ve := tmproto.VoteExtension{
Extension: []byte{1, 2, 3, 4, 5, 6, 7, 8},
Signature: []byte{},
Type: tmproto.VoteExtensionType_THRESHOLD_RECOVER,
}
actual := VoteExtensionSignBytes("some-chain", 1, 2, &ve)
t.Logf("sign bytes: %x", actual)
assert.EqualValues(t, expect, actual)
}

func TestVoteProtobuf(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down

0 comments on commit 55bb222

Please sign in to comment.