Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BCF-2901 Fix potential JAID collisions in multi chain env #11821

Merged
merged 5 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/cmd/cosmos_node_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func TestShell_IndexCosmosNodes(t *testing.T) {
nodes := *r.Renders[0].(*cmd.CosmosNodePresenters)
require.Len(t, nodes, 1)
n := nodes[0]
assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID, *node.Name), n.ID)
assert.Equal(t, chainID, n.ChainID)
assert.Equal(t, *node.Name, n.ID)
assert.Equal(t, *node.Name, n.Name)
wantConfig, err := toml.Marshal(node)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions core/cmd/evm_node_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ func TestShell_IndexEVMNodes(t *testing.T) {
n1 := nodes[0]
n2 := nodes[1]
assert.Equal(t, chainID.String(), n1.ChainID)
assert.Equal(t, *node1.Name, n1.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID.String(), *node1.Name), n1.ID)
assert.Equal(t, *node1.Name, n1.Name)
wantConfig, err := toml.Marshal(node1)
require.NoError(t, err)
assert.Equal(t, string(wantConfig), n1.Config)
assert.Equal(t, chainID.String(), n2.ChainID)
assert.Equal(t, *node2.Name, n2.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(chainID.String(), *node2.Name), n2.ID)
assert.Equal(t, *node2.Name, n2.Name)
wantConfig2, err := toml.Marshal(node2)
require.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion core/cmd/ocr2_keys_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestOCR2KeyBundlePresenter_RenderTable(t *testing.T) {
pubKeyConfig := key.ConfigEncryptionPublicKey()
pubKey := key.OffchainPublicKey()
p := cmd.OCR2KeyBundlePresenter{
JAID: cmd.JAID{ID: bundleID},
JAID: cmd.NewJAID(bundleID),
OCR2KeysBundleResource: presenters.OCR2KeysBundleResource{
JAID: presenters.NewJAID(key.ID()),
ChainType: "evm",
Expand Down
4 changes: 2 additions & 2 deletions core/cmd/solana_node_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ func TestShell_IndexSolanaNodes(t *testing.T) {
n1 := nodes[0]
n2 := nodes[1]
assert.Equal(t, id, n1.ChainID)
assert.Equal(t, *node1.Name, n1.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node1.Name), n1.ID)
assert.Equal(t, *node1.Name, n1.Name)
wantConfig, err := toml.Marshal(node1)
require.NoError(t, err)
assert.Equal(t, string(wantConfig), n1.Config)
assert.Equal(t, id, n2.ChainID)
assert.Equal(t, *node2.Name, n2.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node2.Name), n2.ID)
assert.Equal(t, *node2.Name, n2.Name)
wantConfig2, err := toml.Marshal(node2)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions core/cmd/starknet_node_commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ func TestShell_IndexStarkNetNodes(t *testing.T) {
n1 := nodes[0]
n2 := nodes[1]
assert.Equal(t, id, n1.ChainID)
assert.Equal(t, *node1.Name, n1.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node1.Name), n1.ID)
assert.Equal(t, *node1.Name, n1.Name)
wantConfig, err := toml.Marshal(node1)
require.NoError(t, err)
assert.Equal(t, string(wantConfig), n1.Config)
assert.Equal(t, id, n2.ChainID)
assert.Equal(t, *node2.Name, n2.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(id, *node2.Name), n2.ID)
assert.Equal(t, *node2.Name, n2.Name)
wantConfig2, err := toml.Marshal(node2)
require.NoError(t, err)
Expand Down
4 changes: 4 additions & 0 deletions core/internal/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ func MustRandomBytes(t *testing.T, l int) (b []byte) {
return b
}

func FormatWithPrefixedChainID(chainID, id string) string {
ilija42 marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Sprintf("%s/%s", chainID, id)
}

type JobPipelineV2TestHelper struct {
Prm pipeline.ORM
Jrm job.ORM
Expand Down
2 changes: 1 addition & 1 deletion core/web/eth_keys_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ func (ekc *ETHKeysController) Chain(c *gin.Context) {
jsonAPIError(c, http.StatusBadRequest, errors.Errorf("invalid address: %s, must be hex address", keyID))
return
}
address := common.HexToAddress((keyID))
address := common.HexToAddress(keyID)

cid := c.Query("evmChainID")
chain, ok := ekc.getChain(c, cid)
Expand Down
15 changes: 10 additions & 5 deletions core/web/eth_keys_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ func TestETHKeysController_ChainSuccess_UpdateNonce(t *testing.T) {
err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey)
assert.NoError(t, err)

assert.Equal(t, key.ID(), updatedKey.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID)
assert.Equal(t, key.Address.String(), updatedKey.Address)
assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String())
assert.Equal(t, false, updatedKey.Disabled)
}
Expand Down Expand Up @@ -328,7 +329,8 @@ func TestETHKeysController_ChainSuccess_Disable(t *testing.T) {
err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey)
assert.NoError(t, err)

assert.Equal(t, key.ID(), updatedKey.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(updatedKey.EVMChainID.String(), key.Address.String()), updatedKey.ID)
assert.Equal(t, key.Address.String(), updatedKey.Address)
assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String())
assert.Equal(t, true, updatedKey.Disabled)
}
Expand Down Expand Up @@ -371,7 +373,8 @@ func TestETHKeysController_ChainSuccess_Enable(t *testing.T) {
err := cltest.ParseJSONAPIResponse(t, resp, &updatedKey)
assert.NoError(t, err)

assert.Equal(t, key.ID(), updatedKey.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID)
assert.Equal(t, key.Address.String(), updatedKey.Address)
assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String())
assert.Equal(t, false, updatedKey.Disabled)
}
Expand Down Expand Up @@ -436,7 +439,8 @@ func TestETHKeysController_ChainSuccess_ResetWithAbandon(t *testing.T) {
err = cltest.ParseJSONAPIResponse(t, resp, &updatedKey)
assert.NoError(t, err)

assert.Equal(t, key.ID(), updatedKey.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key.Address.String()), updatedKey.ID)
assert.Equal(t, key.Address.String(), updatedKey.Address)
assert.Equal(t, cltest.FixtureChainID.String(), updatedKey.EVMChainID.String())
assert.Equal(t, false, updatedKey.Disabled)

Expand Down Expand Up @@ -663,7 +667,8 @@ func TestETHKeysController_DeleteSuccess(t *testing.T) {
err := cltest.ParseJSONAPIResponse(t, resp, &deletedKey)
assert.NoError(t, err)

assert.Equal(t, key0.ID(), deletedKey.ID)
assert.Equal(t, cltest.FormatWithPrefixedChainID(cltest.FixtureChainID.String(), key0.Address.String()), deletedKey.ID)
assert.Equal(t, key0.Address.String(), deletedKey.Address)
assert.Equal(t, cltest.FixtureChainID.String(), deletedKey.EVMChainID.String())
assert.Equal(t, false, deletedKey.Disabled)

Expand Down
69 changes: 69 additions & 0 deletions core/web/presenters/chain_msg_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package presenters

import (
"fmt"
"testing"

"github.com/manyminds/api2go/jsonapi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/cosmostest"
"github.com/smartcontractkit/chainlink/v2/core/internal/testutils/solanatest"
)

func TestSolanaMessageResource(t *testing.T) {
id := "1"
chainID := solanatest.RandomChainID()
r := NewSolanaMsgResource(id, chainID)
assert.Equal(t, chainID, r.ChainID)

b, err := jsonapi.Marshal(r)
require.NoError(t, err)

expected := fmt.Sprintf(`
{
"data":{
"type":"solana_messages",
"id":"%s/%s",
"attributes":{
"ChainID":"%s",
"from":"",
"to":"",
"amount":0
}
}
}
`, chainID, id, chainID)

assert.JSONEq(t, expected, string(b))
}

func TestCosmosMessageResource(t *testing.T) {
id := "1"
chainID := cosmostest.RandomChainID()
contractID := "cosmos1p3ucd3ptpw902fluyjzkq3fflq4btddac9sa3s"
r := NewCosmosMsgResource(id, chainID, contractID)
assert.Equal(t, chainID, r.ChainID)
assert.Equal(t, contractID, r.ContractID)

b, err := jsonapi.Marshal(r)
require.NoError(t, err)

expected := fmt.Sprintf(`
{
"data":{
"type":"cosmos_messages",
"id":"%s/%s",
"attributes":{
"ChainID":"%s",
"ContractID":"%s",
"State":"",
"TxHash":null
}
}
}
`, chainID, id, chainID, contractID)

assert.JSONEq(t, expected, string(b))
}
2 changes: 1 addition & 1 deletion core/web/presenters/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (r CosmosNodeResource) GetName() string {
// NewCosmosNodeResource returns a new CosmosNodeResource for node.
func NewCosmosNodeResource(node types.NodeStatus) CosmosNodeResource {
return CosmosNodeResource{NodeResource{
JAID: NewJAID(node.Name),
JAID: NewPrefixedJAID(node.Name, node.ChainID),
ChainID: node.ChainID,
Name: node.Name,
State: node.State,
Expand Down
2 changes: 1 addition & 1 deletion core/web/presenters/cosmos_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (CosmosMsgResource) GetName() string {
// NewCosmosMsgResource returns a new partial CosmosMsgResource.
func NewCosmosMsgResource(id string, chainID string, contractID string) CosmosMsgResource {
return CosmosMsgResource{
JAID: NewJAID(id),
JAID: NewPrefixedJAID(id, chainID),
ChainID: chainID,
ContractID: contractID,
}
Expand Down
2 changes: 1 addition & 1 deletion core/web/presenters/eth_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type NewETHKeyOption func(*ETHKeyResource)
// Use the functional options to inject the ETH and LINK balances
func NewETHKeyResource(k ethkey.KeyV2, state ethkey.State, opts ...NewETHKeyOption) *ETHKeyResource {
r := &ETHKeyResource{
JAID: NewJAID(k.Address.Hex()),
JAID: NewPrefixedJAID(k.Address.Hex(), state.EVMChainID.String()),
EVMChainID: state.EVMChainID,
Address: k.Address.Hex(),
EthBalance: nil,
Expand Down
4 changes: 2 additions & 2 deletions core/web/presenters/eth_key_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestETHKeyResource(t *testing.T) {
{
"data":{
"type":"eTHKeys",
"id":"%s",
"id":"42/%s",
"attributes":{
"address":"%s",
"evmChainID":"42",
Expand Down Expand Up @@ -84,7 +84,7 @@ func TestETHKeyResource(t *testing.T) {
{
"data": {
"type":"eTHKeys",
"id":"%s",
"id":"42/%s",
"attributes":{
"address":"%s",
"evmChainID":"42",
Expand Down
1 change: 1 addition & 0 deletions core/web/presenters/eth_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func NewEthTxResourceFromAttempt(txa txmgr.TxAttempt) EthTxResource {

if txa.Tx.ChainID != nil {
r.EVMChainID = *big.New(txa.Tx.ChainID)
r.JAID = NewPrefixedJAID(r.JAID.ID, txa.Tx.ChainID.String())
}

if tx.Sequence != nil {
Expand Down
8 changes: 5 additions & 3 deletions core/web/presenters/eth_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import (
func TestEthTxResource(t *testing.T) {
t.Parallel()

chainID := big.NewInt(54321)
tx := txmgr.Tx{
ID: 1,
EncodedPayload: []byte(`{"data": "is wilding out"}`),
FromAddress: common.HexToAddress("0x1"),
ToAddress: common.HexToAddress("0x2"),
FeeLimit: uint32(5000),
ChainID: chainID,
State: txmgrcommon.TxConfirmed,
Value: big.Int(assets.NewEthValue(1)),
}
Expand All @@ -52,7 +54,7 @@ func TestEthTxResource(t *testing.T) {
"sentAt": "",
"to": "0x0000000000000000000000000000000000000002",
"value": "0.000000000000000001",
"evmChainID": "0"
"evmChainID": "54321"
}
}
}
Expand Down Expand Up @@ -85,7 +87,7 @@ func TestEthTxResource(t *testing.T) {
{
"data": {
"type": "evm_transactions",
"id": "0x0000000000000000000000000000000000000000000000000000000000010203",
"id": "54321/0x0000000000000000000000000000000000000000000000000000000000010203",
"attributes": {
"state": "confirmed",
"data": "0x7b2264617461223a202269732077696c64696e67206f7574227d",
Expand All @@ -98,7 +100,7 @@ func TestEthTxResource(t *testing.T) {
"sentAt": "300",
"to": "0x0000000000000000000000000000000000000002",
"value": "0.000000000000000001",
"evmChainID": "0"
"evmChainID": "54321"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/web/presenters/evm_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (r EVMNodeResource) GetName() string {
// NewEVMNodeResource returns a new EVMNodeResource for node.
func NewEVMNodeResource(node types.NodeStatus) EVMNodeResource {
return EVMNodeResource{NodeResource{
JAID: NewJAID(node.Name),
JAID: NewPrefixedJAID(node.Name, node.ChainID),
ChainID: node.ChainID,
Name: node.Name,
State: node.State,
Expand Down
64 changes: 64 additions & 0 deletions core/web/presenters/evm_forwarder_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package presenters

import (
"fmt"
"strings"
"testing"
"time"

"github.com/manyminds/api2go/jsonapi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big"
)

func TestEVMForwarderResource(t *testing.T) {
var (
ID = int64(1)
address = utils.RandomAddress()
chainID = *big.NewI(4)
createdAt = time.Now()
updatedAt = time.Now().Add(time.Second)
)
fwd := forwarders.Forwarder{
ID: ID,
Address: address,
EVMChainID: chainID,
CreatedAt: createdAt,
UpdatedAt: updatedAt,
}

r := NewEVMForwarderResource(fwd)
assert.Equal(t, fmt.Sprint(ID), r.ID)
assert.Equal(t, address, r.Address)
assert.Equal(t, chainID, r.EVMChainID)
assert.Equal(t, createdAt, r.CreatedAt)
assert.Equal(t, updatedAt, r.UpdatedAt)

b, err := jsonapi.Marshal(r)
require.NoError(t, err)

createdAtMarshalled, err := createdAt.MarshalText()
require.NoError(t, err)
updatedAtMarshalled, err := updatedAt.MarshalText()
require.NoError(t, err)

expected := fmt.Sprintf(`
{
"data":{
"type":"evm_forwarder",
"id":"%d",
"attributes":{
"address":"%s",
"evmChainId":"%s",
"createdAt":"%s",
"updatedAt":"%s"
}
}
}
`, ID, strings.ToLower(address.String()), chainID.String(), string(createdAtMarshalled), string(updatedAtMarshalled))
assert.JSONEq(t, expected, string(b))
}
6 changes: 6 additions & 0 deletions core/web/presenters/jsonapi.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package presenters

import (
"fmt"
"strconv"
)

Expand All @@ -14,6 +15,11 @@ func NewJAID(id string) JAID {
return JAID{id}
}

// NewPrefixedJAID prefixes JAID with chain id in %s/%s format.
func NewPrefixedJAID(id string, chainID string) JAID {
return JAID{ID: fmt.Sprintf("%s/%s", chainID, id)}
ilija42 marked this conversation as resolved.
Show resolved Hide resolved
}

// NewJAIDInt32 converts an int32 into a JAID
func NewJAIDInt32(id int32) JAID {
return JAID{strconv.Itoa(int(id))}
Expand Down
Loading
Loading