github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/types/node_info_test.go (about)

     1  package types
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/ari-anchor/sei-tendermint/crypto/ed25519"
    11  	tmnet "github.com/ari-anchor/sei-tendermint/libs/net"
    12  	"github.com/ari-anchor/sei-tendermint/version"
    13  )
    14  
    15  const testCh = 0x01
    16  
    17  func TestNodeInfoValidate(t *testing.T) {
    18  
    19  	// empty fails
    20  	ni := NodeInfo{}
    21  	assert.Error(t, ni.Validate())
    22  
    23  	channels := make([]byte, maxNumChannels)
    24  	for i := 0; i < maxNumChannels; i++ {
    25  		channels[i] = byte(i)
    26  	}
    27  	dupChannels := make([]byte, 5)
    28  	copy(dupChannels, channels[:5])
    29  	dupChannels = append(dupChannels, testCh)
    30  
    31  	nonASCII := "¢§µ"
    32  	emptyTab := "\t"
    33  	emptySpace := "  "
    34  
    35  	testCases := []struct {
    36  		testName         string
    37  		malleateNodeInfo func(*NodeInfo)
    38  		expectErr        bool
    39  	}{
    40  		{
    41  			"Too Many Channels",
    42  			func(ni *NodeInfo) { ni.Channels = append(channels, byte(maxNumChannels)) }, // nolint: gocritic
    43  			true,
    44  		},
    45  		{"Duplicate Channel", func(ni *NodeInfo) { ni.Channels = dupChannels }, true},
    46  		{"Good Channels", func(ni *NodeInfo) { ni.Channels = ni.Channels[:5] }, false},
    47  
    48  		{"Invalid NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "not-an-address" }, true},
    49  		{"Good NetAddress", func(ni *NodeInfo) { ni.ListenAddr = "0.0.0.0:26656" }, false},
    50  
    51  		{"Non-ASCII Version", func(ni *NodeInfo) { ni.Version = nonASCII }, true},
    52  		{"Empty tab Version", func(ni *NodeInfo) { ni.Version = emptyTab }, true},
    53  		{"Empty space Version", func(ni *NodeInfo) { ni.Version = emptySpace }, true},
    54  		{"Empty Version", func(ni *NodeInfo) { ni.Version = "" }, false},
    55  
    56  		{"Non-ASCII Moniker", func(ni *NodeInfo) { ni.Moniker = nonASCII }, true},
    57  		{"Empty tab Moniker", func(ni *NodeInfo) { ni.Moniker = emptyTab }, true},
    58  		{"Empty space Moniker", func(ni *NodeInfo) { ni.Moniker = emptySpace }, true},
    59  		{"Empty Moniker", func(ni *NodeInfo) { ni.Moniker = "" }, true},
    60  		{"Good Moniker", func(ni *NodeInfo) { ni.Moniker = "hey its me" }, false},
    61  
    62  		{"Non-ASCII TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = nonASCII }, true},
    63  		{"Empty tab TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptyTab }, true},
    64  		{"Empty space TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = emptySpace }, true},
    65  		{"Empty TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "" }, false},
    66  		{"Off TxIndex", func(ni *NodeInfo) { ni.Other.TxIndex = "off" }, false},
    67  
    68  		{"Non-ASCII RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = nonASCII }, true},
    69  		{"Empty tab RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptyTab }, true},
    70  		{"Empty space RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = emptySpace }, true},
    71  		{"Empty RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "" }, false},
    72  		{"Good RPCAddress", func(ni *NodeInfo) { ni.Other.RPCAddress = "0.0.0.0:26657" }, false},
    73  	}
    74  
    75  	nodeKeyID := testNodeID()
    76  	name := "testing"
    77  
    78  	// test case passes
    79  	ni = testNodeInfo(t, nodeKeyID, name)
    80  	ni.Channels = channels
    81  	assert.NoError(t, ni.Validate())
    82  
    83  	for _, tc := range testCases {
    84  		t.Run(tc.testName, func(t *testing.T) {
    85  			ni := testNodeInfo(t, nodeKeyID, name)
    86  			ni.Channels = channels
    87  			tc.malleateNodeInfo(&ni)
    88  			err := ni.Validate()
    89  			if tc.expectErr {
    90  				assert.Error(t, err, tc.testName)
    91  			} else {
    92  				assert.NoError(t, err, tc.testName)
    93  			}
    94  		})
    95  
    96  	}
    97  
    98  }
    99  
   100  func testNodeID() NodeID {
   101  	return NodeIDFromPubKey(ed25519.GenPrivKey().PubKey())
   102  }
   103  
   104  func testNodeInfo(t *testing.T, id NodeID, name string) NodeInfo {
   105  	return testNodeInfoWithNetwork(t, id, name, "testing")
   106  }
   107  
   108  func testNodeInfoWithNetwork(t *testing.T, id NodeID, name, network string) NodeInfo {
   109  	t.Helper()
   110  	return NodeInfo{
   111  		ProtocolVersion: ProtocolVersion{
   112  			P2P:   version.P2PProtocol,
   113  			Block: version.BlockProtocol,
   114  			App:   0,
   115  		},
   116  		NodeID:     id,
   117  		ListenAddr: fmt.Sprintf("127.0.0.1:%d", getFreePort(t)),
   118  		Network:    network,
   119  		Version:    "1.2.3-rc0-deadbeef",
   120  		Channels:   []byte{testCh},
   121  		Moniker:    name,
   122  		Other: NodeInfoOther{
   123  			TxIndex:    "on",
   124  			RPCAddress: fmt.Sprintf("127.0.0.1:%d", getFreePort(t)),
   125  		},
   126  	}
   127  }
   128  
   129  func getFreePort(t *testing.T) int {
   130  	t.Helper()
   131  	port, err := tmnet.GetFreePort()
   132  	require.NoError(t, err)
   133  	return port
   134  }
   135  
   136  func TestNodeInfoCompatible(t *testing.T) {
   137  	nodeKey1ID := testNodeID()
   138  	nodeKey2ID := testNodeID()
   139  	name := "testing"
   140  
   141  	var newTestChannel byte = 0x2
   142  
   143  	// test NodeInfo is compatible
   144  	ni1 := testNodeInfo(t, nodeKey1ID, name)
   145  	ni2 := testNodeInfo(t, nodeKey2ID, name)
   146  	assert.NoError(t, ni1.CompatibleWith(ni2))
   147  
   148  	// add another channel; still compatible
   149  	ni2.Channels = []byte{newTestChannel, testCh}
   150  	assert.NoError(t, ni1.CompatibleWith(ni2))
   151  
   152  	testCases := []struct {
   153  		testName         string
   154  		malleateNodeInfo func(*NodeInfo)
   155  	}{
   156  		{"Wrong block version", func(ni *NodeInfo) { ni.ProtocolVersion.Block++ }},
   157  		{"Wrong network", func(ni *NodeInfo) { ni.Network += "-wrong" }},
   158  		{"No common channels", func(ni *NodeInfo) { ni.Channels = []byte{newTestChannel} }},
   159  	}
   160  
   161  	for _, tc := range testCases {
   162  		ni := testNodeInfo(t, nodeKey2ID, name)
   163  		tc.malleateNodeInfo(&ni)
   164  		assert.Error(t, ni1.CompatibleWith(ni))
   165  	}
   166  }
   167  
   168  func TestNodeInfoAddChannel(t *testing.T) {
   169  	nodeInfo := testNodeInfo(t, testNodeID(), "testing")
   170  	nodeInfo.Channels = []byte{}
   171  	require.Empty(t, nodeInfo.Channels)
   172  
   173  	nodeInfo.AddChannel(2)
   174  	require.Contains(t, nodeInfo.Channels, byte(0x02))
   175  
   176  	// adding the same channel again shouldn't be a problem
   177  	nodeInfo.AddChannel(2)
   178  	require.Contains(t, nodeInfo.Channels, byte(0x02))
   179  }
   180  
   181  func TestParseAddressString(t *testing.T) {
   182  	testCases := []struct {
   183  		name     string
   184  		addr     string
   185  		expected string
   186  		correct  bool
   187  	}{
   188  		{"no node id and no protocol", "127.0.0.1:8080", "", false},
   189  		{"no node id w/ tcp input", "tcp://127.0.0.1:8080", "", false},
   190  		{"no node id w/ udp input", "udp://127.0.0.1:8080", "", false},
   191  
   192  		{
   193  			"no protocol",
   194  			"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   195  			"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   196  			true,
   197  		},
   198  		{
   199  			"tcp input",
   200  			"tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   201  			"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   202  			true,
   203  		},
   204  		{
   205  			"udp input",
   206  			"udp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   207  			"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   208  			true,
   209  		},
   210  		{"malformed tcp input", "tcp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false},
   211  		{"malformed udp input", "udp//deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false},
   212  
   213  		// {"127.0.0:8080", false},
   214  		{"invalid host", "notahost", "", false},
   215  		{"invalid port", "127.0.0.1:notapath", "", false},
   216  		{"invalid host w/ port", "notahost:8080", "", false},
   217  		{"just a port", "8082", "", false},
   218  		{"non-existent port", "127.0.0:8080000", "", false},
   219  
   220  		{"too short nodeId", "deadbeef@127.0.0.1:8080", "", false},
   221  		{"too short, not hex nodeId", "this-isnot-hex@127.0.0.1:8080", "", false},
   222  		{"not hex nodeId", "xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false},
   223  
   224  		{"too short nodeId w/tcp", "tcp://deadbeef@127.0.0.1:8080", "", false},
   225  		{"too short notHex nodeId w/tcp", "tcp://this-isnot-hex@127.0.0.1:8080", "", false},
   226  		{"notHex nodeId w/tcp", "tcp://xxxxbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", "", false},
   227  		{
   228  			"correct nodeId w/tcp",
   229  			"tcp://deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   230  			"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080",
   231  			true,
   232  		},
   233  
   234  		{"no node id", "tcp://@127.0.0.1:8080", "", false},
   235  		{"no node id or IP", "tcp://@", "", false},
   236  		{"tcp no host, w/ port", "tcp://:26656", "", false},
   237  		{"empty", "", "", false},
   238  		{"node id delimiter 1", "@", "", false},
   239  		{"node id delimiter 2", " @", "", false},
   240  		{"node id delimiter 3", " @ ", "", false},
   241  	}
   242  
   243  	for _, tc := range testCases {
   244  		tc := tc
   245  		t.Run(tc.name, func(t *testing.T) {
   246  			addr, port, err := ParseAddressString(tc.addr)
   247  			if tc.correct {
   248  				require.NoError(t, err, tc.addr)
   249  				assert.Contains(t, tc.expected, addr.String())
   250  				assert.Contains(t, tc.expected, fmt.Sprint(port))
   251  			} else {
   252  				assert.Error(t, err, "%v", tc.addr)
   253  			}
   254  		})
   255  	}
   256  }