Skip to content

Commit

Permalink
Deployment test working
Browse files Browse the repository at this point in the history
  • Loading branch information
connorwstein committed Aug 14, 2024
1 parent c2cd153 commit dfb157e
Show file tree
Hide file tree
Showing 18 changed files with 4,945 additions and 283 deletions.
63 changes: 56 additions & 7 deletions integration-tests/deployment/ccip/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ package ccipdeployment
import (
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers"

"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config"

owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/gethwrappers"

"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink/integration-tests/deployment"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract"
Expand Down Expand Up @@ -114,10 +114,28 @@ type DeployCCIPContractConfig struct {
// Deployment produces an address book of everything it deployed.
func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (deployment.AddressBook, error) {
ab := deployment.NewMemoryAddressBook()
for sel, chain := range e.Chains {
if c.HomeChainSel == sel {
}
nodes, err := NodeInfo(e.NodeIDs, e.Offchain)
if err != nil {
e.Logger.Errorw("Failed to get node info", "err", err)
return ab, err
}
cap, err := c.CapabilityRegistry[c.HomeChainSel].GetHashedCapabilityId(
&bind.CallOpts{}, CapabilityLabelledName, CapabilityVersion)
if err != nil {
e.Logger.Errorw("Failed to get hashed capability id", "err", err)
return ab, err
}
// Signal to CR that our nodes support CCIP capability.
if err := AddNodes(
c.CapabilityRegistry[c.HomeChainSel],
e.Chains[c.HomeChainSel],
nodes.PeerIDs(c.HomeChainSel), // Doesn't actually matter which sel here
[][32]byte{cap},
); err != nil {
return ab, err
}

for sel, chain := range e.Chains {
// TODO: Still waiting for RMNRemote/RMNHome contracts etc.
mockARM, err := deployContract(e.Logger, chain, ab,
func(chain deployment.Chain) ContractDeploy[*mock_arm_contract.MockARMContract] {
Expand Down Expand Up @@ -334,7 +352,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (

offRamp, err := deployContract(e.Logger, chain, ab,
func(chain deployment.Chain) ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp] {
offRamp, tx, _, err2 := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp(
offRampAddr, tx, offRamp, err2 := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp(
chain.DeployerKey,
chain.Client,
evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{
Expand All @@ -352,7 +370,7 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (
[]evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{},
)
return ContractDeploy[*evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp]{
offRamp, nil, tx, EVM2EVMMultiOffRamp_1_6_0, err2,
offRampAddr, offRamp, tx, EVM2EVMMultiOffRamp_1_6_0, err2,
}
})
if err != nil {
Expand Down Expand Up @@ -380,6 +398,37 @@ func DeployCCIPContracts(e deployment.Environment, c DeployCCIPContractConfig) (
e.Logger.Errorw("Failed to confirm price registry authorized caller update", "err", err)
return ab, err
}

// Add chain config for each chain.
_, err = AddChainConfig(e.Logger,
e.Chains[c.HomeChainSel],
c.CCIPOnChainState.CCIPConfig[c.HomeChainSel],
chain.Selector,
nodes.PeerIDs(chain.Selector),
uint8(len(nodes)/3))
if err != nil {
return ab, err
}

// For each chain, we create a DON on the home chain.
if err := AddDON(e.Logger,
cap,
c.CapabilityRegistry[c.HomeChainSel],
c.CCIPConfig[c.HomeChainSel],
offRamp.Contract,
chain,
e.Chains[c.HomeChainSel],
uint8(len(nodes)/3),
nodes.BootstrapPeerIDs(chain.Selector)[0],
nodes.PeerIDs(chain.Selector),
nodes,
); err != nil {
e.Logger.Errorw("Failed to add DON", "err", err)
return ab, err
}
}

// Next steps: add initial configuration to cap registry and to offramps.

return ab, nil
}
53 changes: 39 additions & 14 deletions integration-tests/deployment/ccip/deploy_home_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@ import (
"bytes"
"context"
"errors"
"fmt"
"sort"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"
confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper"
"github.com/smartcontractkit/libocr/offchainreporting2plus/ocr3confighelper"

"github.com/smartcontractkit/chainlink/integration-tests/deployment"

"github.com/smartcontractkit/chainlink-ccip/chainconfig"
"github.com/smartcontractkit/chainlink-ccip/pluginconfig"
commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3"
"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/ccip_integration_tests/integrationhelpers"
"github.com/smartcontractkit/chainlink/integration-tests/deployment"
cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ocr3_config_encoder"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry"
"github.com/smartcontractkit/chainlink/v2/core/logger"
)

const (
Expand Down Expand Up @@ -156,6 +156,17 @@ func AddNodes(
return nil
}

func SetupConfigInfo(chainSelector uint64, readers [][32]byte, fChain uint8, cfg []byte) ccip_config.CCIPConfigTypesChainConfigInfo {
return ccip_config.CCIPConfigTypesChainConfigInfo{
ChainSelector: chainSelector,
ChainConfig: ccip_config.CCIPConfigTypesChainConfig{
Readers: readers,
FChain: fChain,
Config: cfg,
},
}
}

func AddChainConfig(
lggr logger.Logger,
h deployment.Chain,
Expand All @@ -176,7 +187,7 @@ func AddChainConfig(
if err != nil {
return ccip_config.CCIPConfigTypesChainConfigInfo{}, err
}
chainConfig := integrationhelpers.SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig)
chainConfig := SetupConfigInfo(chainSelector, p2pIDs, f, encodedExtraChainConfig)
inputConfig := []ccip_config.CCIPConfigTypesChainConfigInfo{
chainConfig,
}
Expand All @@ -192,22 +203,32 @@ func AddChainConfig(

func AddDON(
lggr logger.Logger,
capReg *capabilities_registry.CapabilitiesRegistry,
ccipCapabilityID [32]byte,
chainSelector uint64,
capReg *capabilities_registry.CapabilitiesRegistry,
ccipConfig *ccip_config.CCIPConfig,
dest deployment.Chain,
offRamp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp,
dest deployment.Chain,
home deployment.Chain,
f uint8,
bootstrapP2PID [32]byte,
p2pIDs [][32]byte,
oracles []confighelper2.OracleIdentityExtra,
nodes []Node,
) error {
sortP2PIDS(p2pIDs)
// Get OCR3 Config from helper
var schedule []int
for range oracles {
var oracles []confighelper2.OracleIdentityExtra
for _, node := range nodes {
schedule = append(schedule, 1)
cfg := node.selToOCRConfig[dest.Selector]
oracles = append(oracles, confighelper2.OracleIdentityExtra{
OracleIdentity: confighelper2.OracleIdentity{
OnchainPublicKey: cfg.OnchainPublicKey,
TransmitAccount: cfg.TransmitAccount,
OffchainPublicKey: cfg.OffchainPublicKey,
PeerID: cfg.PeerID.String(),
}, ConfigEncryptionPublicKey: cfg.ConfigEncryptionPublicKey,
})
}

tabi, err := ocr3_config_encoder.IOCR3ConfigEncoderMetaData.GetAbi()
Expand Down Expand Up @@ -281,7 +302,7 @@ func AddDON(

ocr3Configs = append(ocr3Configs, ocr3_config_encoder.CCIPConfigTypesOCR3Config{
PluginType: uint8(pluginType),
ChainSelector: chainSelector,
ChainSelector: dest.Selector,
F: configF,
OffchainConfigVersion: offchainConfigVersion,
OfframpAddress: offRamp.Address().Bytes(),
Expand Down Expand Up @@ -311,6 +332,9 @@ func AddDON(
Config: encodedConfigs,
},
}, false, false, f)
if err != nil {
return fmt.Errorf("%s", err.(rpc.DataError).ErrorData().(string))
}
if err := home.Confirm(tx.Hash()); err != nil {
return err
}
Expand Down Expand Up @@ -373,7 +397,7 @@ func AddDON(

tx, err = offRamp.SetOCR3Configs(dest.DeployerKey, offrampOCR3Configs)
if err != nil {
return err
return fmt.Errorf("%s", err.(rpc.DataError).ErrorData().(string))
}
if err := home.Confirm(tx.Hash()); err != nil {
return err
Expand All @@ -384,7 +408,8 @@ func AddDON(
Context: context.Background(),
}, uint8(pluginType))
if err != nil {
return err
//return err
return fmt.Errorf("%s", err.(rpc.DataError).ErrorData().(string))
}
// TODO: assertions
//require.Equalf(t, offrampOCR3Configs[pluginType].ConfigDigest, ocrConfig.ConfigInfo.ConfigDigest, "%s OCR3 config digest mismatch", pluginType.String())
Expand All @@ -394,7 +419,7 @@ func AddDON(
// // only commit will set signers, exec doesn't need them.
// require.Equalf(t, offrampOCR3Configs[pluginType].Signers, ocrConfig.Signers, "%s OCR3 config signers mismatch", pluginType.String())
//}
//require.Equalf(t, offrampOCR3Configs[pluginType].Transmitters, ocrConfig.Transmitters, "%s OCR3 config transmitters mismatch", pluginType.String())
//require.Equalf(t, offrampOCR3Configs[pluginType].TransmittersByEVMChainID, ocrConfig.TransmittersByEVMChainID, "%s OCR3 config transmitters mismatch", pluginType.String())
}

lggr.Infof("set ocr3 config on the offramp, signers: %+v, transmitters: %+v", signerAddresses, transmitterAddresses)
Expand Down
112 changes: 111 additions & 1 deletion integration-tests/deployment/ccip/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,125 @@ package ccipdeployment
import (
"context"
"fmt"
"strconv"

nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1"
"github.com/ethereum/go-ethereum/common"
chainsel "github.com/smartcontractkit/chain-selectors"
ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types"
"github.com/smartcontractkit/libocr/offchainreporting2plus/types"

"github.com/smartcontractkit/chainlink/integration-tests/deployment"
nodev1 "github.com/smartcontractkit/chainlink/integration-tests/deployment/jd/node/v1"
"github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey"

"github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/validate"
"github.com/smartcontractkit/chainlink/v2/core/services/relay"
)

type OCRConfig struct {
OffchainPublicKey ocrtypes.OffchainPublicKey
// For EVM-chains, this an *address*.
OnchainPublicKey ocrtypes.OnchainPublicKey
PeerID p2pkey.PeerID
TransmitAccount ocrtypes.Account
ConfigEncryptionPublicKey types.ConfigEncryptionPublicKey
IsBootstrap bool
MultiAddr string // TODO: type
}

type Nodes []Node

func (n Nodes) PeerIDs(chainSel uint64) [][32]byte {
var peerIDs [][32]byte
for _, node := range n {
cfg := node.selToOCRConfig[chainSel]
// NOTE: Assume same peerID for all chains.
// Might make sense to change proto as peerID is 1-1 with node?
peerIDs = append(peerIDs, cfg.PeerID)
}
return peerIDs
}

func (n Nodes) BootstrapPeerIDs(chainSel uint64) [][32]byte {
var peerIDs [][32]byte
for _, node := range n {
cfg := node.selToOCRConfig[chainSel]
if !cfg.IsBootstrap {
continue
}
peerIDs = append(peerIDs, cfg.PeerID)
}
return peerIDs
}

// OffchainPublicKey types.OffchainPublicKey
// // For EVM-chains, this an *address*.
// OnchainPublicKey types.OnchainPublicKey
// PeerID string
// TransmitAccount types.Account
type Node struct {
selToOCRConfig map[uint64]OCRConfig
}

func MustPeerIDFromString(s string) p2pkey.PeerID {
p := p2pkey.PeerID{}
if err := p.UnmarshalString(s); err != nil {
panic(err)
}
return p
}

// Gathers all the node info through JD required to be able to set
// OCR config for example.
func NodeInfo(nodeIDs []string, oc deployment.OffchainClient) (Nodes, error) {
var nodes []Node
for _, node := range nodeIDs {
// TODO: Filter should accept multiple nodes
nodeChainConfigs, err := oc.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{Filter: &nodev1.ListNodeChainConfigsRequest_Filter{
NodeId: node,
}})
if err != nil {
return nil, err
}
selToOCRConfig := make(map[uint64]OCRConfig)
for _, chainConfig := range nodeChainConfigs.ChainConfigs {
if chainConfig.Chain.Type == nodev1.ChainType_CHAIN_TYPE_SOLANA {
// Note supported for CCIP yet.
continue
}
evmChainID, err := strconv.Atoi(chainConfig.Chain.Id)
if err != nil {
return nil, err
}
sel, err := chainsel.SelectorFromChainId(uint64(evmChainID))
if err != nil {
return nil, err
}
b := common.Hex2Bytes(chainConfig.Ocr2Config.OcrKeyBundle.OffchainPublicKey)
var opk ocrtypes.OffchainPublicKey
copy(opk[:], b)

b = common.Hex2Bytes(chainConfig.Ocr2Config.OcrKeyBundle.ConfigPublicKey)
var cpk types.ConfigEncryptionPublicKey
copy(cpk[:], b)

selToOCRConfig[sel] = OCRConfig{
OffchainPublicKey: opk,
OnchainPublicKey: common.HexToAddress(chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress).Bytes(),
PeerID: MustPeerIDFromString(chainConfig.Ocr2Config.P2PKeyBundle.PeerId),
TransmitAccount: ocrtypes.Account(chainConfig.AccountAddress),
ConfigEncryptionPublicKey: cpk,
IsBootstrap: chainConfig.Ocr2Config.IsBootstrap,
MultiAddr: chainConfig.Ocr2Config.Multiaddr,
}
}
nodes = append(nodes, Node{
selToOCRConfig: selToOCRConfig,
})
}
return nodes, nil
}

// In our case, the only address needed is the cap registry which is actually an env var.
// and will pre-exist for our deployment. So the job specs only depend on the environment operators.
func NewCCIPJobSpecs(nodeIds []string, oc deployment.OffchainClient) (map[string][]string, error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,14 @@ func Test0001_InitialDeploy(t *testing.T) {
Contract: capReg,
},
})
state, err := ccipdeployment.GenerateOnchainState(e, ab)
require.NoError(t, err)
// Apply migration
output, err := Apply0001(e, ccipdeployment.DeployCCIPContractConfig{})
output, err := Apply0001(e, ccipdeployment.DeployCCIPContractConfig{
HomeChainSel: homeChainSel,
// Capreg/config already exist.
CCIPOnChainState: state,
})
require.NoError(t, err)

// Apply the jobs.
Expand Down
1 change: 1 addition & 0 deletions integration-tests/deployment/ccip/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func GenerateOnchainState(e deployment.Environment, ab deployment.AddressBook) (
McmsAddrs: make(map[uint64]common.Address),
Timelocks: make(map[uint64]*owner_wrappers.RBACTimelock),
CapabilityRegistry: make(map[uint64]*capabilities_registry.CapabilitiesRegistry),
CCIPConfig: make(map[uint64]*ccip_config.CCIPConfig),
}
// Get all the onchain state
addresses, err := ab.Addresses()
Expand Down
Loading

0 comments on commit dfb157e

Please sign in to comment.