From 0b3511722c316b802e42b00fc7e2e2edefb6be14 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Mon, 27 May 2024 11:37:29 -0500 Subject: [PATCH] refactor: merge conflicts --- app/server/start.go | 20 ++++++++- eth/chain_id.go | 48 +++++++++++++++++++- eth/chain_id_test.go | 104 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 158 insertions(+), 14 deletions(-) diff --git a/app/server/start.go b/app/server/start.go index 56cdd579e..0447b85c7 100644 --- a/app/server/start.go +++ b/app/server/start.go @@ -9,7 +9,9 @@ import ( "os" "os/signal" "path/filepath" + "regexp" "runtime/pprof" + "strings" "syscall" "time" @@ -401,7 +403,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, opts StartOpt clientCtx = clientCtx. WithHomeDir(home). - WithChainID(genDoc.ChainID) + WithChainID(hackChainID(genDoc.ChainID)) // Set `GRPCClient` to `clientCtx` to enjoy concurrent grpc query. // only use it if gRPC server is enabled. @@ -504,7 +506,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, opts StartOpt return err } - clientCtx.WithChainID(genDoc.ChainID) + clientCtx := clientCtx.WithChainID(hackChainID(genDoc.ChainID)) tmEndpoint := "/websocket" tmRPCAddr := cfg.RPC.ListenAddress @@ -657,3 +659,17 @@ func wrapCPUProfile(ctx *server.Context, callback func() error) error { return WaitForQuitSignals() } + +// hackChainID replaces nibiru-localnet-0 with nibirulocalnet-9000-1 which matches the standard +func hackChainID(chainID string) string { + re := regexp.MustCompile(`-\d+$`) + lastNumber := re.FindString(chainID) + trimmedInput := strings.TrimSuffix(chainID, lastNumber) + if lastNumber == "-0" { + lastNumber = "-1" + } + trimmedInput = strings.ReplaceAll(trimmedInput, "-", "") + result := trimmedInput + "_9000" + lastNumber + + return result +} diff --git a/eth/chain_id.go b/eth/chain_id.go index 61b8041d1..d6d09dab4 100644 --- a/eth/chain_id.go +++ b/eth/chain_id.go @@ -2,15 +2,40 @@ package eth import ( + "fmt" "math/big" + "regexp" + "strings" "github.com/NibiruChain/nibiru/app/appconst" ) +var ( + // one of any lower case letter from "a"-"z" + regexChainID = `[a-z]{1,}` + // one of either "_" or "-" + regexEIP155Separator = `[_-]{1}` + // one of "_" + // regexEIP155Separator = `_{1}` + regexEIP155 = `[1-9][0-9]*` + regexEpochSeparator = `-{1}` + regexEpoch = `[1-9][0-9]*` + nibiruEvmChainId = regexp.MustCompile(fmt.Sprintf(`^(%s)%s(%s)%s(%s)$`, + regexChainID, + regexEIP155Separator, + regexEIP155, + regexEpochSeparator, + regexEpoch)) +) + // IsValidChainID returns false if the given chain identifier is incorrectly // formatted. func IsValidChainID(chainID string) bool { - return len(chainID) <= 48 + if len(chainID) > 48 { + return false + } + + return nibiruEvmChainId.MatchString(chainID) } // ParseEthChainID parses a string chain identifier's epoch to an @@ -27,5 +52,24 @@ func ParseEthChainID(chainID string) (*big.Int, error) { // Ethereum-compatible chain-id in *big.Int format. The function returns an error // if the chain-id has an invalid format func ParseEthChainIDStrict(chainID string) (*big.Int, error) { - return appconst.GetEthChainID(chainID), nil + chainID = strings.TrimSpace(chainID) + if len(chainID) > 48 { + return nil, ErrInvalidChainID.Wrapf( + `chain-id input "%s" cannot exceed 48 chars`, chainID) + } + + matches := nibiruEvmChainId.FindStringSubmatch(chainID) + if matches == nil || len(matches) != 4 || matches[1] == "" { + return nil, ErrInvalidChainID.Wrapf( + `chain-id input "%s", matches "%v"`, chainID, matches) + } + + // verify that the chain-id entered is a base 10 integer + chainIDInt, ok := new(big.Int).SetString(matches[2], 10) + if !ok { + return nil, ErrInvalidChainID.Wrapf( + `epoch "%s" must be base-10 integer format`, matches[2]) + } + + return chainIDInt, nil } diff --git a/eth/chain_id_test.go b/eth/chain_id_test.go index 39890acf6..2594c13c0 100644 --- a/eth/chain_id_test.go +++ b/eth/chain_id_test.go @@ -2,12 +2,11 @@ package eth import ( "math/big" + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - - "github.com/NibiruChain/nibiru/app/appconst" ) func TestParseChainID_Happy(t *testing.T) { @@ -17,18 +16,24 @@ func TestParseChainID_Happy(t *testing.T) { expInt *big.Int }{ { - chainID: "cataclysm-1", - expInt: big.NewInt(appconst.ETH_CHAIN_ID_MAINNET), + chainID: "nibiru_1-1", + name: "valid chain-id, single digit", + expInt: big.NewInt(1), + }, + { + chainID: "cataclysm_256-1", + name: "valid chain-id, multiple digits", + expInt: big.NewInt(256), }, { - chainID: "nibiru-localnet-0", - name: "valid nibiru-localnet-0", - expInt: big.NewInt(appconst.ETH_CHAIN_ID_LOCAL), + chainID: "cataclysm-4-20", + name: "valid chain-id, dashed, multiple digits", + expInt: big.NewInt(4), }, { - chainID: "otherchain", - name: "other chain, default id", - expInt: big.NewInt(appconst.ETH_CHAIN_ID_DEFAULT), + chainID: "chain-1-1", + name: "valid chain-id, double dash", + expInt: big.NewInt(1), }, } @@ -44,3 +49,82 @@ func TestParseChainID_Happy(t *testing.T) { require.True(t, IsValidChainID(tc.chainID)) } } + +func TestParseChainID_Sad(t *testing.T) { + testCases := []struct { + name string + chainID string + }{ + { + chainID: "chain_1_1", + name: "invalid chain-id, double underscore", + }, + { + chainID: "-", + name: "invalid chain-id, dash only", + }, + { + chainID: "-1", + name: "invalid chain-id, undefined identifier and EIP155", + }, + { + chainID: "_1-1", + name: "invalid chain-id, undefined identifier", + }, + { + chainID: "NIBIRU_1-1", + name: "invalid chain-id, uppercases", + }, + { + chainID: "Nibiru_1-1", + name: "invalid chain-id, mixed cases", + }, + { + chainID: "$&*#!_1-1", + name: "invalid chain-id, special chars", + }, + { + chainID: "nibiru_001-1", + name: "invalid eip155 chain-id, cannot start with 0", + }, + { + chainID: "nibiru_0x212-1", + name: "invalid eip155 chain-id, cannot invalid base", + }, + { + chainID: "nibiru_1-0x212", + name: "invalid eip155 chain-id, cannot invalid base", + }, + { + chainID: "nibiru_nibiru_9000-1", + name: "invalid eip155 chain-id, non-integer", + }, + { + chainID: "nibiru_-", + name: "invalid epoch, undefined", + }, + { + chainID: " ", + name: "blank chain ID", + }, + { + chainID: "", + name: "empty chain ID", + }, + { + chainID: "_-", + name: "empty content for chain id, eip155 and epoch numbers", + }, + { + chainID: "nibiru_" + strings.Repeat("1", 45) + "-1", + name: "long chain-id", + }, + } + + for _, tc := range testCases { + chainIDEpoch, err := ParseEthChainIDStrict(tc.chainID) + require.Error(t, err, tc.name) + require.Nil(t, chainIDEpoch) + require.False(t, IsValidChainID(tc.chainID), tc.name) + } +}