Skip to content

Commit

Permalink
Extract common integration helper code
Browse files Browse the repository at this point in the history
  • Loading branch information
connorwstein committed Nov 18, 2024
1 parent cd981b8 commit dc9acfa
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 318 deletions.
114 changes: 98 additions & 16 deletions integration-tests/ccip-tests/testsetups/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@ package testsetups
import (
"fmt"
"math/big"
"net/http"
"net/http/httptest"
"os"
"strconv"
"testing"
"time"

chainsel "github.com/smartcontractkit/chain-selectors"

commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"
"github.com/smartcontractkit/chainlink-testing-framework/lib/blockchain"
ctfconfig "github.com/smartcontractkit/chainlink-testing-framework/lib/config"
ctftestenv "github.com/smartcontractkit/chainlink-testing-framework/lib/docker/test_env"
Expand All @@ -18,12 +23,16 @@ import (
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/ptr"
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext"
"github.com/smartcontractkit/chainlink-testing-framework/seth"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
commontypes "github.com/smartcontractkit/chainlink/deployment/common/types"

"github.com/smartcontractkit/chainlink/deployment"
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
"github.com/smartcontractkit/chainlink/deployment/environment/devenv"
clclient "github.com/smartcontractkit/chainlink/deployment/environment/nodeclient"
"github.com/smartcontractkit/chainlink/integration-tests/actions"
ccipactions "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/actions"
"github.com/smartcontractkit/chainlink/integration-tests/contracts"
"github.com/smartcontractkit/chainlink/integration-tests/docker/test_env"
"github.com/smartcontractkit/chainlink/integration-tests/testconfig"
Expand Down Expand Up @@ -75,6 +84,25 @@ func NewLocalDevEnvironmentWithDefaultPrice(
return NewLocalDevEnvironment(t, lggr, ccipdeployment.MockLinkPrice, ccipdeployment.MockWethPrice)
}

// mockAttestationResponse mocks the USDC attestation server, it returns random Attestation.
// We don't need to return exactly the same attestation, because our Mocked USDC contract doesn't rely on any specific
// value, but instead of that it just checks if the attestation is present. Therefore, it makes the test a bit simpler
// and doesn't require very detailed mocks. Please see tests in chainlink-ccip for detailed tests using real attestations
func mockAttestationResponse() *httptest.Server {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response := `{
"status": "complete",
"attestation": "0x9049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b"
}`

_, err := w.Write([]byte(response))
if err != nil {
panic(err)
}
}))
return server
}

func NewLocalDevEnvironment(
t *testing.T,
lggr logger.Logger,
Expand Down Expand Up @@ -125,6 +153,76 @@ func NewLocalDevEnvironment(
// fund the nodes
FundNodes(t, zeroLogLggr, testEnv, cfg, don.PluginNodes())

output, err := changeset.DeployPrerequisites(*e, changeset.DeployPrerequisiteConfig{
ChainSelectors: e.AllChainSelectors(),
})
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))
mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for _, chain := range e.AllChainSelectors() {
mcmsCfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: commonchangeset.SingleGroupMCMS(t),
Bypasser: commonchangeset.SingleGroupMCMS(t),
Proposer: commonchangeset.SingleGroupMCMS(t),
TimelockExecutors: e.AllDeployerKeys(),
TimelockMinDelay: big.NewInt(0),
}
}
output, err = commonchangeset.DeployMCMSWithTimelock(*e, mcmsCfg)
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))

state, err := ccipdeployment.LoadOnchainState(*e)
require.NoError(t, err)

var endpoint string
// When inmemory env then spin up in memory mock server
if testEnv == nil {
server := mockAttestationResponse()
defer server.Close()
endpoint = server.URL
} else {
err := ccipactions.SetMockServerWithUSDCAttestation(e.MockAdapter, nil)
require.NoError(t, err)
endpoint = e.MockAdapter.InternalEndpoint
}

tokenConfig := ccipdeployment.NewTestTokenConfig(state.Chains[feedSel].USDFeeds)
// Apply migration
output, err = changeset.InitialDeploy(*e, ccipdeployment.DeployCCIPContractConfig{
HomeChainSel: homeChainSel,
FeedChainSel: feedSel,
ChainsToDeploy: e.AllChainSelectors(),
TokenConfig: tokenConfig,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
USDCConfig: ccipdeployment.USDCConfig{
Enabled: true,
USDCAttestationConfig: ccipdeployment.USDCAttestationConfig{
API: endpoint,
APITimeout: commonconfig.MustNewDuration(time.Second),
APIInterval: commonconfig.MustNewDuration(500 * time.Millisecond),
},
},
})
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))

// Ensure capreg logs are up to date.
ccipdeployment.ReplayLogs(t, e.Offchain, replayBlocks)

// Apply the jobs.
for nodeID, jobs := range output.JobSpecs {
for _, job := range jobs {
// Note these auto-accept
_, err := e.Offchain.ProposeJob(ctx,
&jobv1.ProposeJobRequest{
NodeId: nodeID,
Spec: job,
})
require.NoError(t, err)
}
}

return ccipdeployment.DeployedEnv{
Env: *e,
HomeChainSel: homeChainSel,
Expand All @@ -139,22 +237,6 @@ func NewLocalDevEnvironmentWithRMN(
numRmnNodes int,
) (ccipdeployment.DeployedEnv, devenv.RMNCluster) {
tenv, dockerenv, _ := NewLocalDevEnvironmentWithDefaultPrice(t, lggr)
state, err := ccipdeployment.LoadOnchainState(tenv.Env)
require.NoError(t, err)

// Deploy CCIP contracts.
newAddresses := deployment.NewMemoryAddressBook()
err = ccipdeployment.DeployCCIPContracts(tenv.Env, newAddresses, ccipdeployment.DeployCCIPContractConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccipdeployment.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
MCMSConfig: ccipdeployment.NewTestMCMSConfig(t, tenv.Env),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
require.NoError(t, tenv.Env.ExistingAddresses.Merge(newAddresses))

l := logging.GetTestLogger(t)
config := GenerateTestRMNConfig(t, numRmnNodes, tenv, MustNetworksToRPCMap(dockerenv.EVMNetworks))
rmnCluster, err := devenv.NewRMNCluster(
Expand Down
54 changes: 0 additions & 54 deletions integration-tests/smoke/ccip_messaging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ import (
"github.com/smartcontractkit/chainlink-common/pkg/hashutil"
"github.com/smartcontractkit/chainlink-common/pkg/merklemulti"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"

"github.com/smartcontractkit/chainlink/deployment"
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
commontypes "github.com/smartcontractkit/chainlink/deployment/common/types"
"github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
Expand Down Expand Up @@ -68,55 +63,6 @@ func Test_CCIPMessaging(t *testing.T) {
", source chain selector:", sourceChain,
", dest chain selector:", destChain,
)
output, err := changeset.DeployPrerequisites(e.Env, changeset.DeployPrerequisiteConfig{
ChainSelectors: e.Env.AllChainSelectors(),
})
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(output.AddressBook))

cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for _, chain := range allChainSelectors {
cfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: commonchangeset.SingleGroupMCMS(t),
Bypasser: commonchangeset.SingleGroupMCMS(t),
Proposer: commonchangeset.SingleGroupMCMS(t),
TimelockExecutors: e.Env.AllDeployerKeys(),
TimelockMinDelay: big.NewInt(0),
}
}
output, err = commonchangeset.DeployMCMSWithTimelock(e.Env, cfg)
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(output.AddressBook))
tokenConfig := ccdeploy.NewTestTokenConfig(state.Chains[e.FeedChainSel].USDFeeds)
output, err = changeset.InitialDeploy(e.Env, ccdeploy.DeployCCIPContractConfig{
HomeChainSel: e.HomeChainSel,
FeedChainSel: e.FeedChainSel,
ChainsToDeploy: allChainSelectors,
TokenConfig: tokenConfig,
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
require.NoError(t, e.Env.ExistingAddresses.Merge(output.AddressBook))
// Get new state after migration.
state, err = ccdeploy.LoadOnchainState(e.Env)
require.NoError(t, err)

// Ensure capreg logs are up to date.
ccdeploy.ReplayLogs(t, e.Env.Offchain, e.ReplayBlocks)

// Apply the jobs.
for nodeID, jobs := range output.JobSpecs {
for _, job := range jobs {
// Note these auto-accept
_, err := e.Env.Offchain.ProposeJob(ctx,
&jobv1.ProposeJobRequest{
NodeId: nodeID,
Spec: job,
})
require.NoError(t, err)
}
}

// connect a single lane, source to dest
require.NoError(t, ccdeploy.AddLaneWithDefaultPrices(e.Env, state, sourceChain, destChain))

Expand Down
110 changes: 1 addition & 109 deletions integration-tests/smoke/ccip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"

jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job"
"github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext"
commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset"
commontypes "github.com/smartcontractkit/chainlink/deployment/common/types"

"github.com/smartcontractkit/chainlink/deployment"
ccdeploy "github.com/smartcontractkit/chainlink/deployment/ccip"
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
"github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/testsetups"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"
"github.com/smartcontractkit/chainlink/v2/core/logger"
Expand All @@ -23,63 +17,11 @@ import (
func TestInitialDeployOnLocal(t *testing.T) {
t.Parallel()
lggr := logger.TestLogger(t)
ctx := ccdeploy.Context(t)
tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr)
e := tenv.Env

state, err := ccdeploy.LoadOnchainState(tenv.Env)
require.NoError(t, err)

feeds := state.Chains[tenv.FeedChainSel].USDFeeds
output, err := changeset.DeployPrerequisites(tenv.Env, changeset.DeployPrerequisiteConfig{
ChainSelectors: tenv.Env.AllChainSelectors(),
})
require.NoError(t, err)
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))

cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for _, chain := range e.AllChainSelectors() {
cfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: commonchangeset.SingleGroupMCMS(t),
Bypasser: commonchangeset.SingleGroupMCMS(t),
Proposer: commonchangeset.SingleGroupMCMS(t),
TimelockExecutors: e.AllDeployerKeys(),
TimelockMinDelay: big.NewInt(0),
}
}
output, err = commonchangeset.DeployMCMSWithTimelock(e, cfg)
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))

output, err = changeset.InitialDeploy(tenv.Env, ccdeploy.DeployCCIPContractConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: tenv.Env.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(feeds),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
require.NoError(t, tenv.Env.ExistingAddresses.Merge(output.AddressBook))
// Get new state after migration.
state, err = ccdeploy.LoadOnchainState(e)
state, err := ccdeploy.LoadOnchainState(e)
require.NoError(t, err)

// Ensure capreg logs are up to date.
ccdeploy.ReplayLogs(t, e.Offchain, tenv.ReplayBlocks)

// Apply the jobs.
for nodeID, jobs := range output.JobSpecs {
for _, job := range jobs {
// Note these auto-accept
_, err := e.Offchain.ProposeJob(ctx,
&jobv1.ProposeJobRequest{
NodeId: nodeID,
Spec: job,
})
require.NoError(t, err)
}
}

// Add all lanes
require.NoError(t, ccdeploy.AddLanesForAll(e, state))
// Need to keep track of the block number for each chain so that event subscription can be done from that block.
Expand Down Expand Up @@ -127,45 +69,11 @@ func TestInitialDeployOnLocal(t *testing.T) {
func TestTokenTransfer(t *testing.T) {
t.Parallel()
lggr := logger.TestLogger(t)
ctx := ccdeploy.Context(t)
tenv, _, _ := testsetups.NewLocalDevEnvironmentWithDefaultPrice(t, lggr)

e := tenv.Env
state, err := ccdeploy.LoadOnchainState(e)
require.NoError(t, err)

output, err := changeset.DeployPrerequisites(e, changeset.DeployPrerequisiteConfig{
ChainSelectors: e.AllChainSelectors(),
})
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))

cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig)
for _, chain := range e.AllChainSelectors() {
cfg[chain] = commontypes.MCMSWithTimelockConfig{
Canceller: commonchangeset.SingleGroupMCMS(t),
Bypasser: commonchangeset.SingleGroupMCMS(t),
Proposer: commonchangeset.SingleGroupMCMS(t),
TimelockExecutors: e.AllDeployerKeys(),
TimelockMinDelay: big.NewInt(0),
}
}
output, err = commonchangeset.DeployMCMSWithTimelock(e, cfg)
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))
output, err = changeset.InitialDeploy(e, ccdeploy.DeployCCIPContractConfig{
HomeChainSel: tenv.HomeChainSel,
FeedChainSel: tenv.FeedChainSel,
ChainsToDeploy: e.AllChainSelectors(),
TokenConfig: ccdeploy.NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds),
OCRSecrets: deployment.XXXGenerateTestOCRSecrets(),
})
require.NoError(t, err)
require.NoError(t, e.ExistingAddresses.Merge(output.AddressBook))
// Get new state after migration and mock USDC token deployment.
state, err = ccdeploy.LoadOnchainState(e)
require.NoError(t, err)

srcToken, _, dstToken, _, err := ccdeploy.DeployTransferableToken(
lggr,
tenv.Env.Chains,
Expand All @@ -177,22 +85,6 @@ func TestTokenTransfer(t *testing.T) {
)
require.NoError(t, err)

// Ensure capreg logs are up to date.
ccdeploy.ReplayLogs(t, e.Offchain, tenv.ReplayBlocks)

// Apply the jobs.
for nodeID, jobs := range output.JobSpecs {
for _, job := range jobs {
// Note these auto-accept
_, err := e.Offchain.ProposeJob(ctx,
&jobv1.ProposeJobRequest{
NodeId: nodeID,
Spec: job,
})
require.NoError(t, err)
}
}

// Add all lanes
require.NoError(t, ccdeploy.AddLanesForAll(e, state))
// Need to keep track of the block number for each chain so that event subscription can be done from that block.
Expand Down
Loading

0 comments on commit dc9acfa

Please sign in to comment.