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

LogPoller DSL Parser #959

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
uses: cachix/install-nix-action@3715ab1a11cac9e991980d7b4a28d80c7ebdd8f9 # nix:v2.24.6
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Print golangci-lint Version
run: nix develop -c golangci-lint --version
- name: golangci-lint
run: nix develop -c make lint-go-integration-tests
- name: Print lint report artifact
Expand All @@ -37,6 +39,8 @@ jobs:
uses: cachix/install-nix-action@3715ab1a11cac9e991980d7b4a28d80c7ebdd8f9 # nix:v2.24.6
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Print golangci-lint Version
run: nix develop -c golangci-lint --version
- name: golangci-lint
run: nix develop -c make lint-go-relay
- name: Print lint report artifact
Expand Down
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ run:
linters:
enable:
- exhaustive
- exportloopref
- copyloopvar
- revive
- goimports
- gosec
Expand Down
9 changes: 6 additions & 3 deletions integration-tests/smoke/ocr2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
)

func TestSolanaOCRV2Smoke(t *testing.T) {
for _, test := range []struct {
tests := []struct {
name string
env map[string]string
}{
Expand All @@ -29,13 +29,16 @@ func TestSolanaOCRV2Smoke(t *testing.T) {
"CL_MEDIAN_CMD": "chainlink-feeds",
"CL_SOLANA_CMD": "chainlink-solana",
}},
} {
}

for idx := range tests {
test := tests[idx]

config, err := tc.GetConfig("Smoke", tc.OCR2)
if err != nil {
t.Fatal(err)
}

test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
_, sg := startOCR2DataFeedsSmokeTest(t, test.name, test.env, config, "")
Expand Down
9 changes: 6 additions & 3 deletions integration-tests/soak/ocr2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
)

func TestSolanaOCRV2Soak(t *testing.T) {
for _, test := range []struct {
tests := []struct {
name string
env map[string]string
}{
Expand All @@ -29,13 +29,16 @@ func TestSolanaOCRV2Soak(t *testing.T) {
"CL_MEDIAN_CMD": "chainlink-feeds",
"CL_SOLANA_CMD": "chainlink-solana",
}},
} {
}

for idx := range tests {
test := tests[idx]

config, err := tc.GetConfig("Soak", tc.OCR2)
if err != nil {
t.Fatal(err)
}

test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

Expand Down
12 changes: 6 additions & 6 deletions integration-tests/solclient/deployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,12 +502,13 @@ func (c *ContractDeployer) DeployAnchorProgramsRemote(contractsDir string, env *
}
log.Debug().Interface("Binaries", contractBinaries).Msg("Program binaries")
g := errgroup.Group{}
for _, bin := range contractBinaries {
bin := bin

for idx := range contractBinaries {
g.Go(func() error {
return c.DeployProgramRemote(bin, env)
return c.DeployProgramRemote(contractBinaries[idx], env)
})
}

return g.Wait()
}

Expand All @@ -518,10 +519,9 @@ func (c *ContractDeployer) DeployAnchorProgramsRemoteDocker(baseDir, subDir stri
}
log.Info().Interface("Binaries", contractBinaries).Msg(fmt.Sprintf("Program binaries [%s]", filepath.Join("programs", subDir)))
g := errgroup.Group{}
for _, bin := range contractBinaries {
bin := bin
for idx := range contractBinaries {
g.Go(func() error {
return c.DeployProgramRemoteLocal(filepath.Join(subDir, bin), sol, programIDBuilder)
return c.DeployProgramRemoteLocal(filepath.Join(subDir, contractBinaries[idx]), sol, programIDBuilder)
})
}
return g.Wait()
Expand Down
9 changes: 5 additions & 4 deletions pkg/solana/config_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ func (c *ConfigTracker) LatestConfigDetails(ctx context.Context) (changedInBlock
func ConfigFromState(ctx context.Context, state State) (types.ContractConfig, error) {
pubKeys := []types.OnchainPublicKey{}
accounts := []types.Account{}

oracles, err := state.Oracles.Data()
if err != nil {
return types.ContractConfig{}, err
}
for _, o := range oracles {
o := o // https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable
pubKeys = append(pubKeys, o.Signer.Key[:])
accounts = append(accounts, types.Account(o.Transmitter.String()))

for idx := range oracles {
pubKeys = append(pubKeys, oracles[idx].Signer.Key[:])
accounts = append(accounts, types.Account(oracles[idx].Transmitter.String()))
}

onchainConfigStruct := median.OnchainConfig{
Expand Down
70 changes: 35 additions & 35 deletions pkg/solana/fees/block_history_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func TestBlockHistoryEstimator_InvalidBlockHistorySize(t *testing.T) {

func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
// Helper variables for tests
min := uint64(10)
max := uint64(100_000)
minPrice := uint64(10)
maxPrice := uint64(100_000)
defaultPrice := uint64(100)
depth := uint64(1) // 1 is LatestBlockEstimator
pollPeriod := 100 * time.Millisecond
Expand All @@ -63,21 +63,21 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
t.Run("Successful Estimation", func(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Assert the computed price matches the expected price
require.NoError(t, estimator.calculatePrice(ctx), "Failed to calculate price")
cfg.On("ComputeUnitPriceMin").Return(min)
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMin").Return(minPrice)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, uint64(lastBlockMedianPrice), estimator.BaseComputeUnitPrice())
})

t.Run("Min Gate: Price Should Be Floored at Min", func(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
tmpMin := uint64(lastBlockMedianPrice) + 100 // Set min higher than the median price
setupConfigMock(cfg, defaultPrice, tmpMin, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, tmpMin, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Call calculatePrice and ensure no error
Expand All @@ -91,14 +91,14 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
tmpMax := uint64(lastBlockMedianPrice) - 100 // Set max lower than the median price
setupConfigMock(cfg, defaultPrice, min, tmpMax, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Call calculatePrice and ensure no error
// Assert the compute unit price is capped at max
require.NoError(t, estimator.calculatePrice(ctx), "Failed to calculate price with price above max")
cfg.On("ComputeUnitPriceMax").Return(tmpMax)
cfg.On("ComputeUnitPriceMin").Return(min)
cfg.On("ComputeUnitPriceMin").Return(minPrice)
assert.Equal(t, tmpMax, estimator.BaseComputeUnitPrice(), "Price should be capped at max")
})

Expand All @@ -109,13 +109,13 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("GetLatestBlock", mock.Anything).Return(nil, fmt.Errorf("fail rpc call")) // Mock GetLatestBlock returning error
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Ensure the price remains unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when GetLatestBlock fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, uint64(100), estimator.BaseComputeUnitPrice(), "Price should not change when GetLatestBlock fails")
})

Expand All @@ -126,13 +126,13 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("GetLatestBlock", mock.Anything).Return(nil, nil) // Mock GetLatestBlock returning nil
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Ensure the price remains unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when parsing fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, uint64(100), estimator.BaseComputeUnitPrice(), "Price should not change when parsing fails")
})

Expand All @@ -143,13 +143,13 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("GetLatestBlock", mock.Anything).Return(&rpc.GetBlockResult{}, nil) // Mock GetLatestBlock returning empty block
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Ensure the price remains unchanged
require.EqualError(t, estimator.calculatePrice(ctx), errNoComputeUnitPriceCollected.Error(), "Expected error when no compute unit prices are collected")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, uint64(100), estimator.BaseComputeUnitPrice(), "Price should not change when median calculation fails")
})

Expand All @@ -160,21 +160,21 @@ func TestBlockHistoryEstimator_LatestBlock(t *testing.T) {
return nil, fmt.Errorf("fail client load")
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwFailLoader, cfg, logger.Test(t))

// Call calculatePrice and expect an error
// Ensure the price remains unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when getting client fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice(), "Price should remain at default when client fails")
})
}

func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
// helpers vars for tests
min := uint64(100)
max := uint64(100_000)
minPrice := uint64(100)
maxPrice := uint64(100_000)
depth := uint64(3)
defaultPrice := uint64(100)
pollPeriod := 3 * time.Second
Expand Down Expand Up @@ -220,20 +220,20 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
t.Run("Successful Estimation", func(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Calculated avg price should be equal to the one extracted manually from the blocks.
require.NoError(t, estimator.calculatePrice(ctx))
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, uint64(multipleBlocksAvg), estimator.BaseComputeUnitPrice())
})

t.Run("Min Gate: Price Should Be Floored at Min", func(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
tmpMin := uint64(multipleBlocksAvg) + 100 // Set min higher than the avg price
setupConfigMock(cfg, defaultPrice, tmpMin, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, tmpMin, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Compute unit price should be floored at min
Expand All @@ -246,13 +246,13 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
// Setup
cfg := cfgmock.NewConfig(t)
tmpMax := uint64(multipleBlocksAvg) - 100 // Set tmpMax lower than the avg price
setupConfigMock(cfg, defaultPrice, min, tmpMax, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Compute unit price should be capped at max
require.NoError(t, estimator.calculatePrice(ctx), "Failed to calculate price with price above max")
cfg.On("ComputeUnitPriceMax").Return(tmpMax)
cfg.On("ComputeUnitPriceMin").Return(min)
cfg.On("ComputeUnitPriceMin").Return(minPrice)
assert.Equal(t, tmpMax, estimator.BaseComputeUnitPrice(), "Price should be capped at max")
})

Expand All @@ -264,12 +264,12 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
return nil, fmt.Errorf("fail client load")
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
estimator := initializeEstimator(ctx, t, rwFailLoader, cfg, logger.Test(t))

// Price should remain unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when getting client fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice())
})

Expand All @@ -280,13 +280,13 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("SlotHeight", mock.Anything).Return(uint64(0), fmt.Errorf("failed to get current slot")) // Mock SlotHeight returning error
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Price should remain unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when getting current slot fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice())
})

Expand All @@ -297,13 +297,13 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("SlotHeight", mock.Anything).Return(depth-1, nil) // Mock SlotHeight returning less than desiredBlockCount
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Price should remain unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when current slot is less than desired block count")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice())
})

Expand All @@ -314,15 +314,15 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("SlotHeight", mock.Anything).Return(testSlots[len(testSlots)-1], nil)
rw.On("GetBlocksWithLimit", mock.Anything, mock.Anything, mock.Anything).
Return(nil, fmt.Errorf("failed to get blocks with limit")) // Mock GetBlocksWithLimit returning error
estimator := initializeEstimator(ctx, t, rwLoader, cfg, logger.Test(t))

// Price should remain unchanged
require.Error(t, estimator.calculatePrice(ctx), "Expected error when getting blocks with limit fails")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice())
})

Expand All @@ -333,7 +333,7 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {
return rw, nil
})
cfg := cfgmock.NewConfig(t)
setupConfigMock(cfg, defaultPrice, min, max, pollPeriod, depth)
setupConfigMock(cfg, defaultPrice, minPrice, pollPeriod, depth)
rw.On("SlotHeight", mock.Anything).Return(testSlots[len(testSlots)-1], nil)
emptyBlocks := rpc.BlocksResult{} // No blocks with compute unit prices
rw.On("GetBlocksWithLimit", mock.Anything, mock.Anything, mock.Anything).
Expand All @@ -342,15 +342,15 @@ func TestBlockHistoryEstimator_MultipleBlocks(t *testing.T) {

// Price should remain unchanged
require.EqualError(t, estimator.calculatePrice(ctx), errNoComputeUnitPriceCollected.Error(), "Expected error when no compute unit prices are collected")
cfg.On("ComputeUnitPriceMax").Return(max)
cfg.On("ComputeUnitPriceMax").Return(maxPrice)
assert.Equal(t, defaultPrice, estimator.BaseComputeUnitPrice())
})
}

// setupConfigMock configures the Config mock with necessary return values.
func setupConfigMock(cfg *cfgmock.Config, defaultPrice uint64, min, max uint64, pollPeriod time.Duration, depth uint64) {
func setupConfigMock(cfg *cfgmock.Config, defaultPrice uint64, minPrice uint64, pollPeriod time.Duration, depth uint64) {
cfg.On("ComputeUnitPriceDefault").Return(defaultPrice).Once()
cfg.On("ComputeUnitPriceMin").Return(min).Once()
cfg.On("ComputeUnitPriceMin").Return(minPrice).Once()
cfg.On("BlockHistoryPollPeriod").Return(pollPeriod).Once()
cfg.On("BlockHistorySize").Return(depth)
}
Expand Down
Loading
Loading