From c16eba55f6e04f6a3345e16be42f884b02d3f97f Mon Sep 17 00:00:00 2001 From: Samuel Hawksby-Robinson Date: Thu, 9 Apr 2020 16:26:02 +0100 Subject: [PATCH] Implemented RLP key field initialisation This replaces the statically declared values, which previously replaced function varialbes see https://github.com/status-im/status-go/pull/1931#discussion_r406123786 --- waku/handshake.go | 53 +++++++++++++++++++++---------- waku/handshake_test.go | 72 ++++++++++++++++-------------------------- waku/waku.go | 8 +++++ 3 files changed, 72 insertions(+), 61 deletions(-) diff --git a/waku/handshake.go b/waku/handshake.go index c3ab08382..b3b6336cf 100644 --- a/waku/handshake.go +++ b/waku/handshake.go @@ -7,6 +7,7 @@ import ( "math" "reflect" "strconv" + "strings" "github.com/ethereum/go-ethereum/rlp" ) @@ -25,27 +26,13 @@ type statusOptionKeyToType struct { const ( sOKTS statusOptionKeyType = iota + 1 // Status Option Key Type String - sOKTU // Status Option Key Type Uint + sOKTU // Status Option Key Type Uint ) var ( defaultMinPoW = math.Float64bits(0.001) - idxFieldKey = map[int]statusOptionKey{ - 0: 0, - 1: 1, - 2: 2, - 3: 3, - 4: 4, - 5: 5, - } - keyFieldIdx = map[statusOptionKey]int{ - 0: 0, - 1: 1, - 2: 2, - 3: 3, - 4: 4, - 5: 5, - } + idxFieldKey = make(map[int]statusOptionKey) + keyFieldIdx = make(map[statusOptionKey]int) ) type keyTypeMapping struct { @@ -69,6 +56,38 @@ type statusOptions struct { keyTypeMapping keyTypeMapping } +// initFLPKeyFields initialises the values of `idxFieldKey` and `keyFieldIdx` +func initRLPKeyFields() error { + o := statusOptions{} + v := reflect.ValueOf(o) + + 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 + } + + keys := strings.Split(rlpTag, "=") + + // parse keys[1] as an int + key, err := strconv.ParseUint(keys[1], 10, 64) + if err != nil { + return fmt.Errorf("malformed rlp tag '%s', tag should be formatted 'rlp:\"key=0\"': %v", rlpTag, err) + } + + // typecast key to be of statusOptionKey type + keyFieldIdx[statusOptionKey(key)] = i + idxFieldKey[i] = statusOptionKey(key) + } + + return nil +} + // WithDefaults adds the default values for a given peer. // This are not the host default values, but the default values that ought to // be used when receiving from an update from a peer. diff --git a/waku/handshake_test.go b/waku/handshake_test.go index cbfe2adf0..d6bf3b947 100644 --- a/waku/handshake_test.go +++ b/waku/handshake_test.go @@ -2,9 +2,6 @@ package waku import ( "math" - "reflect" - "strconv" - "strings" "testing" "github.com/stretchr/testify/require" @@ -67,60 +64,47 @@ func TestForwardCompatibility(t *testing.T) { require.EqualValues(t, statusOptions{PoWRequirement: &pow}, optsDecoded) } -func TestStatusOptionKeys(t *testing.T) { - o := statusOptions{} - - kfi := make(map[statusOptionKey]int) - ifk := make(map[int]statusOptionKey) - - v := reflect.ValueOf(o) - - 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 - } - - keys := strings.Split(rlpTag, "=") - require.Equal(t, 2, len(keys)) - - // parse keys[1] as an int - key, err := strconv.ParseUint(keys[1], 10, 64) - require.NoError(t, err) - - // typecast key to be of statusOptionKey type - kfi[statusOptionKey(key)] = i - ifk[i] = statusOptionKey(key) +func TestInitRLPKeyFields(t *testing.T) { + ifk := map[int]statusOptionKey{ + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + } + kfi := map[statusOptionKey]int{ + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, } - // Test that the statusOptions' derived kfi length matches the global keyFieldIdx length - require.Equal(t, len(keyFieldIdx), len(kfi)) + // Test that the kfi length matches the inited global keyFieldIdx length + require.Equal(t, len(kfi), len(keyFieldIdx)) - // Test that each index of the statusOptions' derived kfi values matches the global keyFieldIdx of the same index + // Test that each index of the kfi values matches the inited global keyFieldIdx of the same index for k, v := range kfi { - require.Exactly(t, keyFieldIdx[k], v) + require.Exactly(t, v, keyFieldIdx[k]) } - // Test that each index of the global keyFieldIdx values matches statusOptions' derived kfi values of the same index + // Test that each index of the inited global keyFieldIdx values matches kfi values of the same index for k, v := range keyFieldIdx { - require.Exactly(t, kfi[k], v) + require.Exactly(t, v, kfi[k]) } - // Test that the statusOptions' derived ifk length matches the global idxFieldKey length - require.Equal(t, len(idxFieldKey), len(ifk)) + // Test that the ifk length matches the inited global idxFieldKey length + require.Equal(t, len(ifk), len(idxFieldKey)) - // Test that each index of the statusOptions' derived ifk values matches the global idxFieldKey of the same index + // Test that each index of the ifk values matches the inited global idxFieldKey of the same index for k, v := range ifk { - require.Exactly(t, idxFieldKey[k], v) + require.Exactly(t, v, idxFieldKey[k]) } - // Test that each index of the global idxFieldKey values matches statusOptions' derived ifk values of the same index + // Test that each index of the inited global idxFieldKey values matches ifk values of the same index for k, v := range idxFieldKey { - require.Exactly(t, ifk[k], v) + require.Exactly(t, v, ifk[k]) } } diff --git a/waku/waku.go b/waku/waku.go index b0dee5358..e15eb785c 100644 --- a/waku/waku.go +++ b/waku/waku.go @@ -108,6 +108,14 @@ type Waku struct { logger *zap.Logger } +// init initialises the waku package +func init() { + err := initRLPKeyFields() + if err != nil { + panic(err) + } +} + // New creates a Waku client ready to communicate through the Ethereum P2P network. func New(cfg *Config, logger *zap.Logger) *Waku { if cfg == nil {