Implement new waku/0 handshake (#1848)
This commit is contained in:
parent
da4f30ffd2
commit
1b515a5a5e
3
Makefile
3
Makefile
|
@ -261,7 +261,8 @@ test-unit: UNIT_TEST_PACKAGES = $(shell go list ./... | \
|
|||
grep -v /lib | \
|
||||
grep -v /transactions/fake )
|
||||
test-unit: ##@tests Run unit and integration tests
|
||||
go test -v -failfast $(UNIT_TEST_PACKAGES) $(gotest_extraflags) && cd ./protocol && $(MAKE) test
|
||||
go test -v -failfast $(UNIT_TEST_PACKAGES) $(gotest_extraflags)
|
||||
cd ./waku && go test -v -failfast ./... $(gotest_extraflags)
|
||||
|
||||
test-unit-race: gotest_extraflags=-race
|
||||
test-unit-race: test-unit ##@tests Run unit and integration tests with -race flag
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
GO111MODULE = on
|
||||
|
||||
ENABLE_METRICS ?= true
|
||||
BUILD_FLAGS ?= $(shell echo "-ldflags '\
|
||||
-X github.com/status-im/status-go/protocol/vendor/github.com/ethereum/go-ethereum/metrics.EnabledStr=$(ENABLE_METRICS)'")
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
.PHONY: test
|
||||
|
||||
test-race:
|
||||
go test -race ./...
|
||||
.PHONY: test-race
|
||||
|
||||
lint:
|
||||
golangci-lint run -v
|
||||
.PHONY: lint
|
||||
|
||||
install-linter:
|
||||
# install linter
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.21.0
|
||||
.PHONY: install-linter
|
||||
|
||||
install-dev:
|
||||
# a tool to vendor non-go files
|
||||
go get github.com/goware/modvendor@latest
|
||||
|
||||
go get github.com/golang/mock/gomock@latest
|
||||
go install github.com/golang/mock/mockgen
|
||||
|
||||
go get github.com/kevinburke/go-bindata/go-bindata@v3.13.0
|
||||
go get github.com/golang/protobuf/protoc-gen-go@v1.3.1
|
||||
.PHONY: install-dev
|
||||
|
||||
generate:
|
||||
go generate ./...
|
||||
.PHONY: generate
|
||||
|
||||
new-migration:
|
||||
@if [ -z "$$DIR" ]; then \
|
||||
echo 'missing DIR var'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
@if [ -z "$$NAME" ]; then \
|
||||
echo 'missing NAME var'; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
mkdir -p $(DIR)
|
||||
touch $(DIR)/`date +"%s"`_$(NAME).down.sql ./$(DIR)/`date +"%s"`_$(NAME).up.sql
|
||||
.PHONY: create-migration
|
|
@ -2,7 +2,7 @@ module github.com/status-im/status-go/waku
|
|||
|
||||
go 1.13
|
||||
|
||||
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.6
|
||||
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.7
|
||||
|
||||
require (
|
||||
github.com/aristanetworks/goarista v0.0.0-20191106175434-873d404c7f40 // indirect
|
||||
|
|
|
@ -27,6 +27,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/btcsuite/btcd v0.20.0-beta h1:DnZGUjFbRkpytojHWwy6nfUSA7vFrzWXDLpFNzt74ZA=
|
||||
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
|
@ -191,6 +192,9 @@ github.com/status-im/go-ethereum v1.9.5-status.5 h1:d2RJC6ltNZJM2mrAW6kDWYdzewF8
|
|||
github.com/status-im/go-ethereum v1.9.5-status.5/go.mod h1:g2+E89NWtyA+55p6XEl5Sdt7Mtez3V0T3+Y7mJNb+tI=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.6 h1:ytuTO1yBIAuTVRtRQoc2mrdyngtP+XOQ9IHIibbz7/I=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.6/go.mod h1:08JvQWE+IOnAFSe4UD4ACLNe2fDd9XmWMCq5Yzy9mk0=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g=
|
||||
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
|
@ -226,6 +230,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
|
||||
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
package waku
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
// statusOptions defines additional information shared between peers
|
||||
// during the handshake.
|
||||
// There might be more options provided then fields in statusOptions
|
||||
// and they should be ignored during deserialization to stay forward compatible.
|
||||
// In the case of RLP, options should be serialized to an array of tuples
|
||||
// where the first item is a field name and the second is a RLP-serialized value.
|
||||
type statusOptions struct {
|
||||
PoWRequirement uint64 `rlp:"key=0"` // RLP does not support float64 natively
|
||||
BloomFilter []byte `rlp:"key=1"`
|
||||
LightNodeEnabled bool `rlp:"key=2"`
|
||||
ConfirmationsEnabled bool `rlp:"key=3"`
|
||||
RateLimits RateLimits `rlp:"key=4"`
|
||||
TopicInterest []TopicType `rlp:"key=5"`
|
||||
}
|
||||
|
||||
var idxFieldKey = make(map[int]string)
|
||||
var keyFieldIdx = func() map[string]int {
|
||||
result := make(map[string]int)
|
||||
opts := statusOptions{}
|
||||
v := reflect.ValueOf(opts)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
// skip unexported fields
|
||||
if !v.Field(i).CanInterface() {
|
||||
continue
|
||||
}
|
||||
rlpTag := v.Type().Field(i).Tag.Get("rlp")
|
||||
// skip fields without rlp field tag
|
||||
if rlpTag == "" {
|
||||
continue
|
||||
}
|
||||
key := strings.Split(rlpTag, "=")[1]
|
||||
result[key] = i
|
||||
idxFieldKey[i] = key
|
||||
}
|
||||
return result
|
||||
}()
|
||||
|
||||
func (o statusOptions) PoWRequirementF() float64 {
|
||||
return math.Float64frombits(o.PoWRequirement)
|
||||
}
|
||||
|
||||
func (o *statusOptions) SetPoWRequirementFromF(val float64) {
|
||||
o.PoWRequirement = math.Float64bits(val)
|
||||
}
|
||||
|
||||
func (o statusOptions) EncodeRLP(w io.Writer) error {
|
||||
v := reflect.ValueOf(o)
|
||||
optionsList := make([]interface{}, 0, v.NumField())
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
value := v.Field(i).Interface()
|
||||
key, ok := idxFieldKey[i]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
optionsList = append(optionsList, []interface{}{key, value})
|
||||
}
|
||||
return rlp.Encode(w, optionsList)
|
||||
}
|
||||
|
||||
func (o *statusOptions) DecodeRLP(s *rlp.Stream) error {
|
||||
_, err := s.List()
|
||||
if err != nil {
|
||||
return fmt.Errorf("expected an outer list: %w", err)
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(o)
|
||||
|
||||
loop:
|
||||
for {
|
||||
_, err := s.List()
|
||||
switch err {
|
||||
case nil:
|
||||
// continue to decode a key
|
||||
case rlp.EOL:
|
||||
break loop
|
||||
default:
|
||||
return fmt.Errorf("expected an inner list: %w", err)
|
||||
}
|
||||
var key string
|
||||
if err := s.Decode(&key); err != nil {
|
||||
return fmt.Errorf("invalid key: %w", err)
|
||||
}
|
||||
// Skip processing if a key does not exist.
|
||||
// It might happen when there is a new peer
|
||||
// which supports a new option with
|
||||
// a higher index.
|
||||
idx, ok := keyFieldIdx[key]
|
||||
if !ok {
|
||||
// Read the rest of the list items and dump them.
|
||||
_, err := s.Raw()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read the value of key %s: %w", key, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := s.Decode(v.Elem().Field(idx).Addr().Interface()); err != nil {
|
||||
return fmt.Errorf("failed to decode an option %s: %w", key, err)
|
||||
}
|
||||
if err := s.ListEnd(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return s.ListEnd()
|
||||
}
|
||||
|
||||
func (o statusOptions) Validate() error {
|
||||
if len(o.TopicInterest) > 1000 {
|
||||
return errors.New("topic interest is limited by 1000 items")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package waku
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeRLP(t *testing.T) {
|
||||
opts := statusOptions{
|
||||
PoWRequirement: math.Float64bits(6.02),
|
||||
BloomFilter: TopicToBloom(TopicType{0xaa, 0xbb, 0xcc, 0xdd}),
|
||||
LightNodeEnabled: true,
|
||||
ConfirmationsEnabled: true,
|
||||
RateLimits: RateLimits{
|
||||
IPLimits: 10,
|
||||
PeerIDLimits: 5,
|
||||
TopicLimits: 1,
|
||||
},
|
||||
TopicInterest: []TopicType{{0x01}, {0x02}, {0x03}, {0x04}},
|
||||
}
|
||||
data, err := rlp.EncodeToBytes(opts)
|
||||
require.NoError(t, err)
|
||||
|
||||
var optsDecoded statusOptions
|
||||
err = rlp.DecodeBytes(data, &optsDecoded)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, opts, optsDecoded)
|
||||
}
|
||||
|
||||
func TestBackwardCompatibility(t *testing.T) {
|
||||
alist := []interface{}{
|
||||
[]interface{}{"0", math.Float64bits(2.05)},
|
||||
}
|
||||
data, err := rlp.EncodeToBytes(alist)
|
||||
require.NoError(t, err)
|
||||
|
||||
var optsDecoded statusOptions
|
||||
err = rlp.DecodeBytes(data, &optsDecoded)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, statusOptions{PoWRequirement: math.Float64bits(2.05)}, optsDecoded)
|
||||
}
|
||||
|
||||
func TestForwardCompatibility(t *testing.T) {
|
||||
alist := []interface{}{
|
||||
[]interface{}{"0", math.Float64bits(2.05)},
|
||||
[]interface{}{"99", uint(10)}, // some future option
|
||||
}
|
||||
data, err := rlp.EncodeToBytes(alist)
|
||||
require.NoError(t, err)
|
||||
|
||||
var optsDecoded statusOptions
|
||||
err = rlp.DecodeBytes(data, &optsDecoded)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, statusOptions{PoWRequirement: math.Float64bits(2.05)}, optsDecoded)
|
||||
}
|
95
waku/peer.go
95
waku/peer.go
|
@ -96,13 +96,15 @@ func (p *Peer) handshake() error {
|
|||
isLightNode := p.host.LightClientMode()
|
||||
isRestrictedLightNodeConnection := p.host.LightClientModeConnectionRestricted()
|
||||
go func() {
|
||||
pow := p.host.MinPow()
|
||||
powConverted := math.Float64bits(pow)
|
||||
bloom := p.host.BloomFilter()
|
||||
confirmationsEnabled := p.host.ConfirmationsEnabled()
|
||||
rateLimits := p.host.RateLimits()
|
||||
|
||||
errc <- p2p.SendItems(p.ws, statusCode, ProtocolVersion, powConverted, bloom, isLightNode, confirmationsEnabled, rateLimits)
|
||||
opts := statusOptions{
|
||||
BloomFilter: p.host.BloomFilter(),
|
||||
LightNodeEnabled: isLightNode,
|
||||
ConfirmationsEnabled: p.host.ConfirmationsEnabled(),
|
||||
RateLimits: p.host.RateLimits(),
|
||||
TopicInterest: nil,
|
||||
}
|
||||
opts.SetPoWRequirementFromF(p.host.MinPow())
|
||||
errc <- p2p.SendItems(p.ws, statusCode, ProtocolVersion, opts)
|
||||
}()
|
||||
|
||||
// Fetch the remote status packet and verify protocol match
|
||||
|
@ -113,56 +115,51 @@ func (p *Peer) handshake() error {
|
|||
if packet.Code != statusCode {
|
||||
return fmt.Errorf("p [%x] sent packet %x before status packet", p.ID(), packet.Code)
|
||||
}
|
||||
s := rlp.NewStream(packet.Payload, uint64(packet.Size))
|
||||
_, err = s.List()
|
||||
if err != nil {
|
||||
return fmt.Errorf("p [%x] sent bad status message: %v", p.ID(), err)
|
||||
}
|
||||
peerVersion, err := s.Uint()
|
||||
if err != nil {
|
||||
return fmt.Errorf("p [%x] sent bad status message (unable to decode version): %v", p.ID(), err)
|
||||
}
|
||||
if peerVersion != ProtocolVersion {
|
||||
return fmt.Errorf("p [%x]: protocol version mismatch %d != %d", p.ID(), peerVersion, ProtocolVersion)
|
||||
}
|
||||
|
||||
// only version is mandatory, subsequent parameters are optional
|
||||
powRaw, err := s.Uint()
|
||||
if err == nil {
|
||||
pow := math.Float64frombits(powRaw)
|
||||
var (
|
||||
peerProtocolVersion uint64
|
||||
peerOptions statusOptions
|
||||
)
|
||||
s := rlp.NewStream(packet.Payload, uint64(packet.Size))
|
||||
if _, err := s.List(); err != nil {
|
||||
return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err)
|
||||
}
|
||||
// Validate protocol version.
|
||||
if err := s.Decode(&peerProtocolVersion); err != nil {
|
||||
return fmt.Errorf("p [%x]: failed to decode peer protocol version: %w", p.ID(), err)
|
||||
}
|
||||
if peerProtocolVersion != ProtocolVersion {
|
||||
return fmt.Errorf("p [%x]: protocol version mismatch %d != %d", p.ID(), peerProtocolVersion, ProtocolVersion)
|
||||
}
|
||||
// Decode and validate other status packet options.
|
||||
if err := s.Decode(&peerOptions); err != nil {
|
||||
return fmt.Errorf("p [%x]: failed to decode status options: %w", p.ID(), err)
|
||||
}
|
||||
if err := s.ListEnd(); err != nil {
|
||||
return fmt.Errorf("p [%x]: failed to decode status packet: %w", p.ID(), err)
|
||||
}
|
||||
if err := peerOptions.Validate(); err != nil {
|
||||
return fmt.Errorf("p [%x]: sent invalid options: %w", p.ID(), err)
|
||||
}
|
||||
// Validate and save peer's PoW.
|
||||
pow := peerOptions.PoWRequirementF()
|
||||
if math.IsInf(pow, 0) || math.IsNaN(pow) || pow < 0.0 {
|
||||
return fmt.Errorf("p [%x] sent bad status message: invalid pow", p.ID())
|
||||
return fmt.Errorf("p [%x]: sent bad status message: invalid pow", p.ID())
|
||||
}
|
||||
p.powRequirement = pow
|
||||
|
||||
var bloom []byte
|
||||
err = s.Decode(&bloom)
|
||||
if err == nil {
|
||||
sz := len(bloom)
|
||||
if sz != BloomFilterSize && sz != 0 {
|
||||
return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), sz)
|
||||
// Validate and save peer's bloom filters.
|
||||
bloom := peerOptions.BloomFilter
|
||||
bloomSize := len(bloom)
|
||||
if bloomSize != 0 && bloomSize != BloomFilterSize {
|
||||
return fmt.Errorf("p [%x] sent bad status message: wrong bloom filter size %d", p.ID(), bloomSize)
|
||||
}
|
||||
p.setBloomFilter(bloom)
|
||||
}
|
||||
}
|
||||
|
||||
isRemotePeerLightNode, _ := s.Bool()
|
||||
if isRemotePeerLightNode && isLightNode && isRestrictedLightNodeConnection {
|
||||
// Validate and save other peer's options.
|
||||
if peerOptions.LightNodeEnabled && isLightNode && isRestrictedLightNodeConnection {
|
||||
return fmt.Errorf("p [%x] is useless: two light client communication restricted", p.ID())
|
||||
}
|
||||
confirmationsEnabled, err := s.Bool()
|
||||
if err != nil || !confirmationsEnabled {
|
||||
p.logger.Info("confirmations are disabled for peer", zap.Binary("peer", p.ID()))
|
||||
} else {
|
||||
p.confirmationsEnabled = confirmationsEnabled
|
||||
}
|
||||
|
||||
var rateLimits RateLimits
|
||||
if err := s.Decode(&rateLimits); err != nil {
|
||||
p.logger.Info("rate limiting is disabled for peer", zap.Binary("peer", p.ID()))
|
||||
} else {
|
||||
p.setRateLimits(rateLimits)
|
||||
}
|
||||
p.confirmationsEnabled = peerOptions.ConfirmationsEnabled
|
||||
p.setRateLimits(peerOptions.RateLimits)
|
||||
|
||||
if err := <-errc; err != nil {
|
||||
return fmt.Errorf("p [%x] failed to send status packet: %v", p.ID(), err)
|
||||
|
|
|
@ -514,7 +514,10 @@ func TestPeerHandshakeWithTwoFullNode(t *testing.T) {
|
|||
p1 := newPeer(
|
||||
&w1,
|
||||
p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}),
|
||||
&rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize), false}},
|
||||
&rwStub{[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{PoWRequirement: 123},
|
||||
}},
|
||||
nil,
|
||||
)
|
||||
err := p1.handshake()
|
||||
|
@ -529,7 +532,10 @@ func TestHandshakeWithOldVersionWithoutLightModeFlag(t *testing.T) {
|
|||
p1 := newPeer(
|
||||
&w1,
|
||||
p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}),
|
||||
&rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize)}},
|
||||
&rwStub{[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{PoWRequirement: 123},
|
||||
}},
|
||||
nil,
|
||||
)
|
||||
err := p1.handshake()
|
||||
|
@ -546,7 +552,10 @@ func TestTwoLightPeerHandshakeRestrictionOff(t *testing.T) {
|
|||
p1 := newPeer(
|
||||
&w1,
|
||||
p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}),
|
||||
&rwStub{[]interface{}{ProtocolVersion, uint64(123), make([]byte, BloomFilterSize), true}},
|
||||
&rwStub{[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{PoWRequirement: 123, LightNodeEnabled: true},
|
||||
}},
|
||||
nil,
|
||||
)
|
||||
err := p1.handshake()
|
||||
|
|
|
@ -28,6 +28,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
@ -913,6 +915,7 @@ func TestSendP2PDirect(t *testing.T) {
|
|||
|
||||
rwStub := &rwP2PMessagesStub{}
|
||||
peerW := newPeer(w, p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), rwStub, nil)
|
||||
w.peers[peerW] = struct{}{}
|
||||
|
||||
params, err := generateMessageParams()
|
||||
if err != nil {
|
||||
|
@ -929,7 +932,7 @@ func TestSendP2PDirect(t *testing.T) {
|
|||
t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
|
||||
}
|
||||
|
||||
err = w.SendP2PDirect(peerW, env, env, env)
|
||||
err = w.SendP2PDirect(peerW.ID(), env, env, env)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
|
||||
}
|
||||
|
@ -1053,7 +1056,14 @@ func testConfirmationsHandshake(t *testing.T, expectConfirmations bool) {
|
|||
p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, expectConfirmations, RateLimits{}},
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
LightNodeEnabled: false,
|
||||
ConfirmationsEnabled: expectConfirmations,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -1067,12 +1077,14 @@ func TestHandshakeWithConfirmationsDisabled(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfirmationReceived(t *testing.T) {
|
||||
logger, err := zap.NewDevelopment()
|
||||
require.NoError(t, err)
|
||||
conf := &Config{
|
||||
MinimumAcceptedPoW: 0,
|
||||
MaxMessageSize: 10 << 20,
|
||||
EnableConfirmations: true,
|
||||
}
|
||||
w := New(conf, nil)
|
||||
w := New(conf, logger)
|
||||
p := p2p.NewPeer(enode.ID{1}, "1", []p2p.Cap{{"waku", 0}})
|
||||
rw1, rw2 := p2p.MsgPipe()
|
||||
errorc := make(chan error, 1)
|
||||
|
@ -1080,15 +1092,27 @@ func TestConfirmationReceived(t *testing.T) {
|
|||
err := w.HandlePeer(p, rw2)
|
||||
errorc <- err
|
||||
}()
|
||||
time.AfterFunc(5*time.Second, func() {
|
||||
go func() {
|
||||
select {
|
||||
case err := <-errorc:
|
||||
t.Log(err)
|
||||
case <-time.After(time.Second * 5):
|
||||
rw1.Close()
|
||||
})
|
||||
}
|
||||
}()
|
||||
require.NoError(
|
||||
t,
|
||||
p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, true, RateLimits{}},
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
require.NoError(
|
||||
|
@ -1097,10 +1121,12 @@ func TestConfirmationReceived(t *testing.T) {
|
|||
rw1,
|
||||
statusCode,
|
||||
ProtocolVersion,
|
||||
math.Float64bits(w.MinPow()),
|
||||
w.BloomFilter(),
|
||||
true,
|
||||
true,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
LightNodeEnabled: true,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -1142,7 +1168,14 @@ func TestMessagesResponseWithError(t *testing.T) {
|
|||
p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, true, RateLimits{}},
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
require.NoError(
|
||||
|
@ -1151,10 +1184,12 @@ func TestMessagesResponseWithError(t *testing.T) {
|
|||
rw1,
|
||||
statusCode,
|
||||
ProtocolVersion,
|
||||
math.Float64bits(w.MinPow()), w.BloomFilter(),
|
||||
true,
|
||||
true,
|
||||
RateLimits{},
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
LightNodeEnabled: true,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -1204,9 +1239,29 @@ func testConfirmationEvents(t *testing.T, envelope Envelope, envelopeErrors []En
|
|||
time.AfterFunc(5*time.Second, func() {
|
||||
rw1.Close()
|
||||
})
|
||||
require.NoError(t, p2p.ExpectMsg(rw1, statusCode, []interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, true, RateLimits{}}))
|
||||
require.NoError(t, p2p.SendItems(rw1, statusCode, ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), true, true))
|
||||
|
||||
require.NoError(t, p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
},
|
||||
},
|
||||
))
|
||||
require.NoError(t, p2p.SendItems(
|
||||
rw1,
|
||||
statusCode,
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
ConfirmationsEnabled: true,
|
||||
LightNodeEnabled: true,
|
||||
},
|
||||
))
|
||||
require.NoError(t, w.Send(&envelope))
|
||||
require.NoError(t, p2p.ExpectMsg(rw1, messagesCode, []*Envelope{&envelope}))
|
||||
|
||||
|
@ -1286,7 +1341,13 @@ func TestEventsWithoutConfirmation(t *testing.T) {
|
|||
p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, false, RateLimits{}},
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
require.NoError(
|
||||
|
@ -1295,11 +1356,11 @@ func TestEventsWithoutConfirmation(t *testing.T) {
|
|||
rw1,
|
||||
statusCode,
|
||||
ProtocolVersion,
|
||||
math.Float64bits(w.MinPow()),
|
||||
w.BloomFilter(),
|
||||
true,
|
||||
false,
|
||||
RateLimits{},
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
LightNodeEnabled: true,
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -1464,10 +1525,17 @@ func TestRateLimiterIntegration(t *testing.T) {
|
|||
p2p.ExpectMsg(
|
||||
rw1,
|
||||
statusCode,
|
||||
[]interface{}{ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, false, RateLimits{
|
||||
[]interface{}{
|
||||
ProtocolVersion,
|
||||
statusOptions{
|
||||
PoWRequirement: math.Float64bits(w.MinPow()),
|
||||
BloomFilter: w.BloomFilter(),
|
||||
RateLimits: RateLimits{
|
||||
IPLimits: 10,
|
||||
PeerIDLimits: 5,
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
)
|
||||
select {
|
||||
|
|
|
@ -911,6 +911,7 @@ func TestSendP2PDirect(t *testing.T) {
|
|||
|
||||
rwStub := &rwP2PMessagesStub{}
|
||||
peerW := newPeer(w, p2p.NewPeer(enode.ID{}, "test", []p2p.Cap{}), rwStub)
|
||||
w.peers[peerW] = struct{}{}
|
||||
|
||||
params, err := generateMessageParams()
|
||||
if err != nil {
|
||||
|
@ -928,7 +929,7 @@ func TestSendP2PDirect(t *testing.T) {
|
|||
}
|
||||
|
||||
// verify sending a single envelope
|
||||
err = w.SendP2PDirect(peerW, env)
|
||||
err = w.SendP2PDirect(peerW.ID(), env)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue