-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* parse compute unit price from tx details * fee metrics * wip: exporters * average calculation + overflow checking * use avg from common * update to pinned common
- Loading branch information
Showing
15 changed files
with
391 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package exporter | ||
|
||
import ( | ||
"context" | ||
|
||
commonMonitoring "github.com/smartcontractkit/chainlink-common/pkg/monitoring" | ||
"github.com/smartcontractkit/chainlink-common/pkg/utils/mathutil" | ||
|
||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/metrics" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/types" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/solana/fees" | ||
) | ||
|
||
func NewFeesFactory( | ||
log commonMonitoring.Logger, | ||
metrics metrics.Fees, | ||
) commonMonitoring.ExporterFactory { | ||
return &feesFactory{ | ||
log, | ||
metrics, | ||
} | ||
} | ||
|
||
type feesFactory struct { | ||
log commonMonitoring.Logger | ||
metrics metrics.Fees | ||
} | ||
|
||
func (p *feesFactory) NewExporter( | ||
params commonMonitoring.ExporterParams, | ||
) (commonMonitoring.Exporter, error) { | ||
return &feesExporter{ | ||
metrics.FeedInput{ | ||
AccountAddress: params.FeedConfig.GetContractAddress(), | ||
FeedID: params.FeedConfig.GetContractAddress(), | ||
ChainID: params.ChainConfig.GetChainID(), | ||
ContractStatus: params.FeedConfig.GetContractStatus(), | ||
ContractType: params.FeedConfig.GetContractType(), | ||
FeedName: params.FeedConfig.GetName(), | ||
FeedPath: params.FeedConfig.GetPath(), | ||
NetworkID: params.ChainConfig.GetNetworkID(), | ||
NetworkName: params.ChainConfig.GetNetworkName(), | ||
}, | ||
p.log, | ||
p.metrics, | ||
}, nil | ||
} | ||
|
||
type feesExporter struct { | ||
label metrics.FeedInput // static for each feed | ||
log commonMonitoring.Logger | ||
metrics metrics.Fees | ||
} | ||
|
||
func (f *feesExporter) Export(ctx context.Context, data interface{}) { | ||
details, err := types.MakeTxDetails(data) | ||
if err != nil { | ||
return // skip if input could not be parsed | ||
} | ||
|
||
// skip on no updates | ||
if len(details) == 0 { | ||
return | ||
} | ||
|
||
// calculate average of non empty TxDetails | ||
var feeArr []uint64 | ||
var computeUnitsArr []fees.ComputeUnitPrice | ||
for _, d := range details { | ||
if d.Empty() { | ||
continue | ||
} | ||
feeArr = append(feeArr, d.Fee) | ||
computeUnitsArr = append(computeUnitsArr, d.ComputeUnitPrice) | ||
} | ||
if len(feeArr) == 0 || len(computeUnitsArr) == 0 { | ||
f.log.Errorf("exporter could not find non-empty TxDetails") | ||
return | ||
} | ||
|
||
fee, err := mathutil.Avg(feeArr...) | ||
if err != nil { | ||
f.log.Errorf("fee average: %w", err) | ||
return | ||
} | ||
computeUnits, err := mathutil.Avg(computeUnitsArr...) | ||
if err != nil { | ||
f.log.Errorf("computeUnits average: %w", err) | ||
return | ||
} | ||
|
||
f.metrics.Set(fee, computeUnits, f.label) | ||
} | ||
|
||
func (f *feesExporter) Cleanup(_ context.Context) { | ||
f.metrics.Cleanup(f.label) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package exporter | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap/zapcore" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
commonMonitoring "github.com/smartcontractkit/chainlink-common/pkg/monitoring" | ||
"github.com/smartcontractkit/chainlink-common/pkg/utils" | ||
|
||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/metrics/mocks" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/testutils" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/types" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/solana/fees" | ||
) | ||
|
||
func TestFees(t *testing.T) { | ||
ctx := utils.Context(t) | ||
lgr, logs := logger.TestObserved(t, zapcore.ErrorLevel) | ||
m := mocks.NewFees(t) | ||
m.On("Set", mock.Anything, mock.Anything, mock.Anything).Once() | ||
m.On("Cleanup", mock.Anything).Once() | ||
|
||
factory := NewFeesFactory(lgr, m) | ||
|
||
chainConfig := testutils.GenerateChainConfig() | ||
feedConfig := testutils.GenerateFeedConfig() | ||
exporter, err := factory.NewExporter(commonMonitoring.ExporterParams{ChainConfig: chainConfig, FeedConfig: feedConfig, Nodes: []commonMonitoring.NodeConfig{}}) | ||
require.NoError(t, err) | ||
|
||
// happy path | ||
exporter.Export(ctx, []types.TxDetails{{Fee: 1, ComputeUnitPrice: 1}}) | ||
exporter.Cleanup(ctx) | ||
|
||
// not txdetails type - no calls to mock | ||
assert.NotPanics(t, func() { exporter.Export(ctx, 1) }) | ||
|
||
// zero txdetails - no calls to mock | ||
exporter.Export(ctx, []types.TxDetails{}) | ||
|
||
// empty txdetails | ||
exporter.Export(ctx, []types.TxDetails{{}}) | ||
assert.Equal(t, 1, logs.FilterMessage("exporter could not find non-empty TxDetails").Len()) | ||
|
||
// multiple TxDetails should return average | ||
// skip empty | ||
m.On("Set", uint64(1), fees.ComputeUnitPrice(10), mock.Anything).Once() | ||
exporter.Export(ctx, []types.TxDetails{{}, {Fee: 2}, {ComputeUnitPrice: 20}}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package metrics | ||
|
||
import ( | ||
commonMonitoring "github.com/smartcontractkit/chainlink-common/pkg/monitoring" | ||
|
||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/types" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/solana/fees" | ||
) | ||
|
||
//go:generate mockery --name Fees --output ./mocks/ | ||
|
||
type Fees interface { | ||
Set(txFee uint64, computeUnitPrice fees.ComputeUnitPrice, feedInput FeedInput) | ||
Cleanup(feedInput FeedInput) | ||
} | ||
|
||
var _ Fees = (*feeMetrics)(nil) | ||
|
||
type feeMetrics struct { | ||
txFee simpleGauge | ||
computeUnit simpleGauge | ||
} | ||
|
||
func NewFees(log commonMonitoring.Logger) *feeMetrics { | ||
return &feeMetrics{ | ||
txFee: newSimpleGauge(log, types.TxFeeMetric), | ||
computeUnit: newSimpleGauge(log, types.ComputeUnitPriceMetric), | ||
} | ||
} | ||
|
||
func (sh *feeMetrics) Set(txFee uint64, computeUnitPrice fees.ComputeUnitPrice, feedInput FeedInput) { | ||
sh.txFee.set(float64(txFee), feedInput.ToPromLabels()) | ||
sh.computeUnit.set(float64(computeUnitPrice), feedInput.ToPromLabels()) | ||
} | ||
|
||
func (sh *feeMetrics) Cleanup(feedInput FeedInput) { | ||
sh.txFee.delete(feedInput.ToPromLabels()) | ||
sh.computeUnit.delete(feedInput.ToPromLabels()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package metrics | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/prometheus/client_golang/prometheus/testutil" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
|
||
"github.com/smartcontractkit/chainlink-solana/pkg/monitoring/types" | ||
"github.com/smartcontractkit/chainlink-solana/pkg/solana/fees" | ||
) | ||
|
||
func TestFees(t *testing.T) { | ||
lgr := logger.Test(t) | ||
m := NewFees(lgr) | ||
|
||
// fetching gauges | ||
gFees, ok := gauges[types.TxFeeMetric] | ||
require.True(t, ok) | ||
gComputeUnits, ok := gauges[types.ComputeUnitPriceMetric] | ||
require.True(t, ok) | ||
|
||
v0 := 1 | ||
v1 := 10 | ||
l := FeedInput{NetworkID: t.Name()} | ||
|
||
// set gauge | ||
assert.NotPanics(t, func() { | ||
m.Set(uint64(v0), fees.ComputeUnitPrice(v1), l) | ||
}) | ||
num := testutil.ToFloat64(gFees.With(l.ToPromLabels())) | ||
assert.Equal(t, float64(v0), num) | ||
num = testutil.ToFloat64(gComputeUnits.With(l.ToPromLabels())) | ||
assert.Equal(t, float64(v1), num) | ||
|
||
// cleanup gauges | ||
assert.Equal(t, 1, testutil.CollectAndCount(gFees)) | ||
assert.Equal(t, 1, testutil.CollectAndCount(gComputeUnits)) | ||
assert.NotPanics(t, func() { m.Cleanup(l) }) | ||
assert.Equal(t, 0, testutil.CollectAndCount(gFees)) | ||
assert.Equal(t, 0, testutil.CollectAndCount(gComputeUnits)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.