Browse Source

state sync: cleanup (#5776)

pull/5778/head
Aleksandr Bezobchuk 3 years ago
committed by GitHub
parent
commit
0565eb5943
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 76 deletions
  1. +114
    -24
      proto/tendermint/statesync/message_test.go
  2. +0
    -16
      statesync/messages.go
  3. +0
    -36
      statesync/messages_test.go
  4. +7
    -0
      statesync/reactor.go

+ 114
- 24
proto/tendermint/statesync/message_test.go View File

@ -1,6 +1,7 @@
package statesync_test
import (
"encoding/hex"
"testing"
proto "github.com/gogo/protobuf/proto"
@ -12,69 +13,103 @@ import (
func TestValidateMsg(t *testing.T) {
testcases := map[string]struct {
msg proto.Message
valid bool
msg proto.Message
validMsg bool
valid bool
}{
"nil": {nil, false},
"unrelated": {&tmproto.Block{}, false},
"nil": {nil, false, false},
"unrelated": {&tmproto.Block{}, false, false},
"ChunkRequest valid": {&ssproto.ChunkRequest{Height: 1, Format: 1, Index: 1}, true},
"ChunkRequest 0 height": {&ssproto.ChunkRequest{Height: 0, Format: 1, Index: 1}, false},
"ChunkRequest 0 format": {&ssproto.ChunkRequest{Height: 1, Format: 0, Index: 1}, true},
"ChunkRequest 0 chunk": {&ssproto.ChunkRequest{Height: 1, Format: 1, Index: 0}, true},
"ChunkRequest valid": {&ssproto.ChunkRequest{Height: 1, Format: 1, Index: 1}, true, true},
"ChunkRequest 0 height": {&ssproto.ChunkRequest{Height: 0, Format: 1, Index: 1}, true, false},
"ChunkRequest 0 format": {&ssproto.ChunkRequest{Height: 1, Format: 0, Index: 1}, true, true},
"ChunkRequest 0 chunk": {&ssproto.ChunkRequest{Height: 1, Format: 1, Index: 0}, true, true},
"ChunkResponse valid": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Chunk: []byte{1}},
true},
true,
true,
},
"ChunkResponse 0 height": {
&ssproto.ChunkResponse{Height: 0, Format: 1, Index: 1, Chunk: []byte{1}},
false},
true,
false,
},
"ChunkResponse 0 format": {
&ssproto.ChunkResponse{Height: 1, Format: 0, Index: 1, Chunk: []byte{1}},
true},
true,
true,
},
"ChunkResponse 0 chunk": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 0, Chunk: []byte{1}},
true},
true,
true,
},
"ChunkResponse empty body": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Chunk: []byte{}},
true},
true,
true,
},
"ChunkResponse nil body": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Chunk: nil},
false},
true,
false,
},
"ChunkResponse missing": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Missing: true},
true},
true,
true,
},
"ChunkResponse missing with empty": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Missing: true, Chunk: []byte{}},
true},
true,
true,
},
"ChunkResponse missing with body": {
&ssproto.ChunkResponse{Height: 1, Format: 1, Index: 1, Missing: true, Chunk: []byte{1}},
false},
true,
false,
},
"SnapshotsRequest valid": {&ssproto.SnapshotsRequest{}, true},
"SnapshotsRequest valid": {&ssproto.SnapshotsRequest{}, true, true},
"SnapshotsResponse valid": {
&ssproto.SnapshotsResponse{Height: 1, Format: 1, Chunks: 2, Hash: []byte{1}},
true},
true,
true,
},
"SnapshotsResponse 0 height": {
&ssproto.SnapshotsResponse{Height: 0, Format: 1, Chunks: 2, Hash: []byte{1}},
false},
true,
false,
},
"SnapshotsResponse 0 format": {
&ssproto.SnapshotsResponse{Height: 1, Format: 0, Chunks: 2, Hash: []byte{1}},
true},
true,
true,
},
"SnapshotsResponse 0 chunks": {
&ssproto.SnapshotsResponse{Height: 1, Format: 1, Hash: []byte{1}},
false},
true,
false,
},
"SnapshotsResponse no hash": {
&ssproto.SnapshotsResponse{Height: 1, Format: 1, Chunks: 2, Hash: []byte{}},
false},
true,
false,
},
}
for name, tc := range testcases {
tc := tc
t.Run(name, func(t *testing.T) {
msg := new(ssproto.Message)
_ = msg.Wrap(tc.msg)
if tc.validMsg {
require.NoError(t, msg.Wrap(tc.msg))
} else {
require.Error(t, msg.Wrap(tc.msg))
}
if tc.valid {
require.NoError(t, msg.Validate())
@ -84,3 +119,58 @@ func TestValidateMsg(t *testing.T) {
})
}
}
func TestStateSyncVectors(t *testing.T) {
testCases := []struct {
testName string
msg proto.Message
expBytes string
}{
{
"SnapshotsRequest",
&ssproto.SnapshotsRequest{},
"0a00",
},
{
"SnapshotsResponse",
&ssproto.SnapshotsResponse{
Height: 1,
Format: 2,
Chunks: 3,
Hash: []byte("chuck hash"),
Metadata: []byte("snapshot metadata"),
},
"1225080110021803220a636875636b20686173682a11736e617073686f74206d65746164617461",
},
{
"ChunkRequest",
&ssproto.ChunkRequest{
Height: 1,
Format: 2,
Index: 3,
},
"1a06080110021803",
},
{
"ChunkResponse",
&ssproto.ChunkResponse{
Height: 1,
Format: 2,
Index: 3,
Chunk: []byte("it's a chunk"),
},
"2214080110021803220c697427732061206368756e6b",
},
}
for _, tc := range testCases {
tc := tc
msg := new(ssproto.Message)
require.NoError(t, msg.Wrap(tc.msg))
bz, err := msg.Marshal()
require.NoError(t, err)
require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName)
}
}

+ 0
- 16
statesync/messages.go View File

@ -1,16 +0,0 @@
package statesync
import (
"github.com/tendermint/tendermint/p2p"
ssproto "github.com/tendermint/tendermint/proto/tendermint/statesync"
)
const (
// snapshotMsgSize is the maximum size of a snapshotResponseMessage
snapshotMsgSize = int(4e6)
// chunkMsgSize is the maximum size of a chunkResponseMessage
chunkMsgSize = int(16e6)
)
// assert Wrapper interface implementation of the state sync proto message type.
var _ p2p.Wrapper = (*ssproto.Message)(nil)

+ 0
- 36
statesync/messages_test.go View File

@ -1,36 +0,0 @@
package statesync
import (
"encoding/hex"
"testing"
"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/require"
ssproto "github.com/tendermint/tendermint/proto/tendermint/statesync"
)
//nolint:lll // ignore line length
func TestStateSyncVectors(t *testing.T) {
testCases := []struct {
testName string
msg proto.Message
expBytes string
}{
{"SnapshotsRequest", &ssproto.SnapshotsRequest{}, "0a00"},
{"SnapshotsResponse", &ssproto.SnapshotsResponse{Height: 1, Format: 2, Chunks: 3, Hash: []byte("chuck hash"), Metadata: []byte("snapshot metadata")}, "1225080110021803220a636875636b20686173682a11736e617073686f74206d65746164617461"},
{"ChunkRequest", &ssproto.ChunkRequest{Height: 1, Format: 2, Index: 3}, "1a06080110021803"},
{"ChunkResponse", &ssproto.ChunkResponse{Height: 1, Format: 2, Index: 3, Chunk: []byte("it's a chunk")}, "2214080110021803220c697427732061206368756e6b"},
}
for _, tc := range testCases {
tc := tc
msg := new(ssproto.Message)
require.NoError(t, msg.Wrap(tc.msg))
bz, err := msg.Marshal()
require.NoError(t, err)
require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName)
}
}

+ 7
- 0
statesync/reactor.go View File

@ -20,6 +20,7 @@ import (
var (
_ service.Service = (*Reactor)(nil)
_ p2p.Wrapper = (*ssproto.Message)(nil)
// ChannelShims contains a map of ChannelDescriptorShim objects, where each
// object wraps a reference to a legacy p2p ChannelDescriptor and the corresponding
@ -59,6 +60,12 @@ const (
// recentSnapshots is the number of recent snapshots to send and receive per peer.
recentSnapshots = 10
// snapshotMsgSize is the maximum size of a snapshotResponseMessage
snapshotMsgSize = int(4e6)
// chunkMsgSize is the maximum size of a chunkResponseMessage
chunkMsgSize = int(16e6)
)
// Reactor handles state sync, both restoring snapshots for the local node and serving snapshots


Loading…
Cancel
Save