Skip to content

Commit

Permalink
build
Browse files Browse the repository at this point in the history
  • Loading branch information
0xAustinWang committed Dec 17, 2024
1 parent 1d87264 commit 4f21404
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 108 deletions.
1 change: 0 additions & 1 deletion deployment/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ type OnchainClient interface {
bind.DeployBackend
BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
}

// OffchainClient interacts with the job-distributor
Expand Down
4 changes: 0 additions & 4 deletions deployment/environment/memory/sim.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@ func (b *Backend) NonceAt(ctx context.Context, account common.Address, blockNumb
return b.Sim.Client().NonceAt(ctx, account, blockNumber)
}

func (b *Backend) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
return b.Sim.Client().BlockByNumber(ctx, number)
}

func NewBackend(sim *simulated.Backend) *Backend {
if sim == nil {
panic("simulated backend is nil")
Expand Down
57 changes: 20 additions & 37 deletions integration-tests/load/ccip/ccip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package ccip
import (
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-common/pkg/utils/tests"
"github.com/smartcontractkit/chainlink-testing-framework/lib/logging"
"github.com/smartcontractkit/chainlink-testing-framework/wasp"
"github.com/smartcontractkit/chainlink/deployment"
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
ccipchangeset "github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig"
"github.com/stretchr/testify/require"
"math/big"
Expand All @@ -21,9 +20,7 @@ var (
"branch": "ccip_load_crib",
"commit": "ccip_load_crib",
}
wg sync.WaitGroup
abPath = "/Users/austin.wang/ccip-core/repos/chainlink/integration-tests/load/ccip/testfiles/ccip-v2-scripts-address-book.json"
nodeIdsPath = "/Users/austin.wang/ccip-core/repos/chainlink/integration-tests/load/ccip/testfiles/ccip-v2-scripts-node-details.json"
wg sync.WaitGroup
)

// step 1: setup
Expand All @@ -36,40 +33,32 @@ var (
// Stop the chains, cleanup the environment
func TestCCIPLoad_RPS(t *testing.T) {
ctx := tests.Context(t)
l := logging.GetTestLogger(t)
lggr := logger.Test(t)

config, err := tc.GetConfig([]string{"Load"}, tc.CCIP)
if err != nil {
t.Fatal(err)
}
l.Info().Interface("loadedTestConfig", config).Msg("Loaded Test Config")

l.Info().Msg("Starting ccip load test")
l.Info().
Int("Number of Nodes", *(config.CCIP.Load.NoOfNodes)).
Interface("config", config.CCIP.Load).
Msg("Test Config")
require.NoError(t, err)
lggr.Infof("loaded test config: %+v", config)

var env = generateEnvironment()
lggr.Info("starting ccip load test")
lggr.Infof("Number of nodes: %d", *(config.CCIP.Load.NoOfNodes))
lggr.Infof("config: %+v", config.CCIP.Load)
lggr.Info("Test Config")

var env = deployment.Environment{}
// output, err := actions.SetupCCIPHomeChain(l, sethClient, config.CCIP, workerNodes)
// require.NoError(t, err)
// env, err = crib.DeployPrerequisites(output, config.CCIP)
// merge addressbooks
// env, err := crib.DeployCCIPContracts(output, config.CCIP)
env, err := CreateEnvironmentFromCribOutput(t, lggr)
require.NoError(t, err)
require.NotNil(t, env)

// Need to keep track of the block number for each chain so that event subscription can be done from that block.
startBlocks := make(map[uint64]*uint64)
state, err := ccipdeployment.LoadOnchainState(env)
state, err := ccipchangeset.LoadOnchainState(*env)
require.NoError(t, err)

cfgl := config.Logging.Loki

// Parse all events from the simulated chains, send to Loki
loki, err := wasp.NewLokiClient(wasp.NewLokiConfig(cfgl.Endpoint, cfgl.TenantId, cfgl.BasicAuth, cfgl.BearerToken))
if err != nil {
l.Error().Err(err).Msg("Failed to create Loki client")
env.Logger.Error("failed to create loki client")
return
}
defer loki.StopNow()
Expand All @@ -92,7 +81,7 @@ func TestCCIPLoad_RPS(t *testing.T) {
// this schedule is per generator
// in this example, it would be 1 request per 10seconds per generator (dest chain)
// so if there are 3 generators, it would be 3 requests per 10 seconds over the network
Gun: NewDestinationGun(l, selector, env, state.Chains[selector].Receiver.Address(), loki),
Gun: NewDestinationGun(env.Logger, selector, env, state.Chains[selector].Receiver.Address(), loki),
Labels: CommonTestLabels,
LokiConfig: wasp.NewLokiConfig(cfgl.Endpoint, cfgl.TenantId, cfgl.BasicAuth, cfgl.BearerToken),
// use the same loki client using `NewLokiClient` with the same config for sending events
Expand Down Expand Up @@ -122,9 +111,9 @@ func TestCCIPLoad_RPS(t *testing.T) {
fmt.Printf("CommitReportAccepted event: %+v\n", event)

blockNum := commitIterator.Event.Raw.BlockNumber
block, err := env.Chains[chainSelector].Client.BlockByNumber(ctx, big.NewInt(int64(blockNum)))
header, err := env.Chains[chainSelector].Client.HeaderByNumber(ctx, big.NewInt(int64(blockNum)))
require.NoError(t, err)
timestamp := time.Unix(int64(block.Time()), 0)
timestamp := time.Unix(int64(header.Time()), 0)

for _, root := range event.MerkleRoots {
lokiLabels = setLokiLabels(root.SourceChainSelector, chainSelector)
Expand All @@ -148,9 +137,9 @@ func TestCCIPLoad_RPS(t *testing.T) {
fmt.Printf("ExecutionStateChanged event: %+v\n", event)

blockNum := execIterator.Event.Raw.BlockNumber
block, err := env.Chains[chainSelector].Client.BlockByNumber(ctx, big.NewInt(int64(blockNum)))
header, err := env.Chains[chainSelector].Client.HeaderByNumber(ctx, big.NewInt(int64(blockNum)))
require.NoError(t, err)
timestamp := time.Unix(int64(block.Time()), 0)
timestamp := time.Unix(int64(header.Time), 0)

// todo: push loki calls to channel?
lokiLabels = setLokiLabels(execIterator.Event.SourceChainSelector, chainSelector)
Expand All @@ -172,9 +161,3 @@ func TestCCIPLoad_RPS(t *testing.T) {
// crib.StopChains(env)
// crib.StopNodes(env)
}

func generateEnvironment() {
ab := readAddressBook(abPath)
nIds := readNodeIds(nodeIdsPath)

}
25 changes: 11 additions & 14 deletions integration-tests/load/ccip/destination_gun.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import (
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/rs/zerolog"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-testing-framework/wasp"
"github.com/smartcontractkit/chainlink/deployment"
ccipdeployment "github.com/smartcontractkit/chainlink/deployment/ccip"
ccipchangeset "github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"

"sync/atomic"
"time"
)
Expand All @@ -21,7 +22,7 @@ type ChainSelectorPair struct {
}

type DestinationGun struct {
l zerolog.Logger
l logger.Logger
env deployment.Environment
seqNums map[ChainSelectorPair]*atomic.Uint64
roundNum *atomic.Int32
Expand All @@ -30,7 +31,7 @@ type DestinationGun struct {
loki *wasp.LokiClient
}

func NewDestinationGun(l zerolog.Logger, chainSelector uint64, env deployment.Environment, receiver common.Address, loki *wasp.LokiClient) *DestinationGun {
func NewDestinationGun(l logger.Logger, chainSelector uint64, env deployment.Environment, receiver common.Address, loki *wasp.LokiClient) *DestinationGun {
seqNums := make(map[ChainSelectorPair]*atomic.Uint64)
for _, cs := range env.AllChainSelectorsExcluding([]uint64{chainSelector}) {

Expand Down Expand Up @@ -60,7 +61,7 @@ func (m *DestinationGun) Call(_ *wasp.Generator) *wasp.Response {

waspGroup := fmt.Sprintf("%d-%s", m.chainSelector, "messageOnly")

state, err := ccipdeployment.LoadOnchainState(m.env)
state, err := ccipchangeset.LoadOnchainState(m.env)
if err != nil {
return &wasp.Response{Error: err.Error(), Group: waspGroup, Failed: true}
}
Expand All @@ -75,12 +76,7 @@ func (m *DestinationGun) Call(_ *wasp.Generator) *wasp.Response {
dst: m.chainSelector,
}
m.seqNums[csPair].Add(1)
m.l.Info().
Int32("RoundNum", requestedRound).
Uint64("Destination ChainSelector", m.chainSelector).
Uint64("Source ChainSelector", src).
Uint64("SequenceNumber", m.seqNums[csPair].Load()).
Msg("starting transmit")
m.l.Infow("Starting transmit with ", "RoundNum", requestedRound, "Destination ChainSelector", m.chainSelector, "Source ChainSelector", src, "SequenceNumber", m.seqNums[csPair].Load())

r := state.Chains[src].Router

Expand Down Expand Up @@ -116,10 +112,10 @@ func (m *DestinationGun) Call(_ *wasp.Generator) *wasp.Response {
return &wasp.Response{Failed: false, Group: waspGroup}
}

// GetCycledClient will return a valid client from a random source chain
// MustSourceChain will return a chain selector to send a message from
func (m *DestinationGun) MustSourceChain() (uint64, error) {

// TODO: check if this chain has sent a message recently, if so, switch to the next chain
// TODO: make this smarter by checking if this chain has sent a message recently, if so, switch to the next chain
otherCS := m.env.AllChainSelectorsExcluding([]uint64{m.chainSelector})
if len(otherCS) == 0 {
return 0, fmt.Errorf("no other chains to send from")
Expand All @@ -133,7 +129,8 @@ func (m *DestinationGun) MustSourceChain() (uint64, error) {
func (m *DestinationGun) GetMessage() (router.ClientEVM2AnyMessage, error) {
rcv, err := utils.ABIEncode(`[{"type":"address"}]`, m.receiver)
if err != nil {
m.l.Error().Err(err).Msg("Error encoding receiver address")
m.l.Error("Error encoding receiver address")
return router.ClientEVM2AnyMessage{}, err
}

return router.ClientEVM2AnyMessage{
Expand Down
84 changes: 32 additions & 52 deletions integration-tests/load/ccip/helpers.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
package ccip

import (
"context"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/rs/zerolog"
"github.com/smartcontractkit/chainlink-common/pkg/logger"
"github.com/smartcontractkit/chainlink-testing-framework/wasp"
"github.com/smartcontractkit/chainlink/deployment"
"github.com/smartcontractkit/chainlink/deployment/environment/devenv"
"github.com/stretchr/testify/require"
"io"
"os"
"testing"
"time"
)

const (
transmitted = iota
committed
executed
LokiLoadLabel = "ccip_load_test"
ErrLokiClient = "failed to create Loki client for monitoring"
ErrLokiPush = "failed to push metrics to Loki"
LokiLoadLabel = "ccip_load_test"
ErrLokiClient = "failed to create Loki client for monitoring"
ErrLokiPush = "failed to push metrics to Loki"
abPath = "/Users/austin.wang/ccip-core/repos/chainlink/integration-tests/load/ccip/testfiles/ccip-v2-scripts-address-book.json"
nodeIdsPath = "/Users/austin.wang/ccip-core/repos/chainlink/integration-tests/load/ccip/testfiles/ccip-v2-scripts-node-details.json"
chainConfigPath = "/Users/austin.wang/ccip-core/repos/chainlink/integration-tests/load/ccip/testfiles/ccip-v2-scripts-chains-details.json"
)

// todo: Have a different struct for commit/exec?
Expand All @@ -30,36 +35,23 @@ type LokiMetric struct {
SequenceNumber uint64 `json:"sequence_number"`
}

func GetAddressFromTypeAndVersion(ab deployment.AddressBook, cs uint64, tv string) (common.Address, error) {
allAddr, err := ab.AddressesForChain(cs)
if err != nil {
return common.Address{}, err
}
for addr, tv := range allAddr {
if tv.Type == tv.Type && tv.Version == tv.Version {
return common.HexToAddress(addr), nil
}
}

return common.Address{}, fmt.Errorf("address not found for chain selector %d and typeAndVersion %s", cs, tv)
}

func SendMetricsToLoki(l zerolog.Logger, lc *wasp.LokiClient, updatedLabels map[string]string, metrics *LokiMetric) {
func SendMetricsToLoki(l logger.Logger, lc *wasp.LokiClient, updatedLabels map[string]string, metrics *LokiMetric) {
if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), metrics); err != nil {
l.Error().Err(err).Msg(ErrLokiPush)
l.Error(ErrLokiPush)
}
}

func setLokiLabels(src, dst uint64) map[string]string {
return map[string]string{
"sourceSelector": fmt.Sprintf("%d", src),
"sourceEvmChainId": fmt.Sprintf("%d", src),
"destEvmChainId": fmt.Sprintf("%d", src),
"destinationSelector": fmt.Sprintf("%d", dst),
"testType": LokiLoadLabel,
}
}

func readFile(inputDir string, fileName string) []byte {
file, err := os.Open(fmt.Sprintf("%s/%s", inputDir, fileName))
func readFile(filePath string) []byte {
file, err := os.Open(filePath)
if err != nil {
fmt.Println("Error opening file:", err)
panic(err)
Expand All @@ -75,42 +67,28 @@ func readFile(inputDir string, fileName string) []byte {
return byteValue
}

func ReadAddressBook(inputDir string) *deployment.AddressBookMap {
byteValue := readFile(inputDir, AddressBookFileName)

var result map[uint64]map[string]deployment.TypeAndVersion
func readFromFile[T []string | *deployment.AddressBookMap | []devenv.ChainConfig](t *testing.T, inputDir string) T {
byteValue := readFile(inputDir)

var result T
// Unmarshal the JSON into the map
err := json.Unmarshal(byteValue, &result)
if err != nil {
fmt.Println("Error unmarshalling JSON:", err)
panic(err)
}
require.NoError(t, err)

// Print the deserialized map
fmt.Println(result)
return deployment.NewMemoryAddressBookFromMap(result)
return result
}

func ReadNodesDetails(inputDir string) NodesDetails {
byteValue := readFile(inputDir, NodesDetailsFileName)
func CreateEnvironmentFromCribOutput(t *testing.T, lggr logger.Logger) (*deployment.Environment, error) {
ab := readFromFile[*deployment.AddressBookMap](t, abPath)
nodeIds := readFromFile[[]string](t, nodeIdsPath)
chainDetails := readFromFile[[]devenv.ChainConfig](t, chainConfigPath)

var result NodesDetails

// Unmarshal the JSON into the map
err := json.Unmarshal(byteValue, &result)
if err != nil {
fmt.Println("Error unmarshalling JSON:", err)
panic(err)
}

// Print the deserialized map
fmt.Println(result)
return result
}
// todo: make sure to call chainDetails.SetDeployerKey() for each chain
// where private keys should be stored in env vars or .toml

func NewDeployEnvironmentFromCribOutput(lggr logger.Logger, ab deployment.AddressBook, nodeIDs []string) (*deployment.Environment, error) {
chains, err := devenv.NewChains(lggr, output.Chains)
chains, err := devenv.NewChains(lggr, chainDetails)
if err != nil {
return nil, err
}
Expand All @@ -119,7 +97,9 @@ func NewDeployEnvironmentFromCribOutput(lggr logger.Logger, ab deployment.Addres
lggr,
ab,
chains,
nodeIDs,
nil, // todo: populate the offchain client using output.DON
nodeIds,
nil,
func() context.Context { return context.Background() },
deployment.XXXGenerateTestOCRSecrets(),
), nil
}

0 comments on commit 4f21404

Please sign in to comment.