Skip to content

Commit

Permalink
remaining unit + integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aalu1418 committed May 17, 2024
1 parent 84d6789 commit 39b14f7
Show file tree
Hide file tree
Showing 4 changed files with 650 additions and 603 deletions.
27 changes: 15 additions & 12 deletions pkg/solana/fees/block_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ func (bhe *blockHistoryEstimator) run() {
case <-bhe.chStop:
return
case <-tick:
if err := bhe.getPrice(); err != nil {
bhe.lgr.Errorw("BlockHistoryEstimator failed to fetch price: %w", err)
if err := bhe.calculatePrice(); err != nil {
bhe.lgr.Error(fmt.Errorf("BlockHistoryEstimator failed to fetch price: %w", err))
}
}

Expand All @@ -82,23 +82,27 @@ func (bhe *blockHistoryEstimator) Close() error {
}

func (bhe *blockHistoryEstimator) BaseComputeUnitPrice() uint64 {
bhe.lock.RLock()
defer bhe.lock.RUnlock()

if bhe.price >= bhe.cfg.ComputeUnitPriceMin() && bhe.price <= bhe.cfg.ComputeUnitPriceMax() {
return bhe.price
price := bhe.readRawPrice()
if price >= bhe.cfg.ComputeUnitPriceMin() && price <= bhe.cfg.ComputeUnitPriceMax() {
return price
}

if bhe.price < bhe.cfg.ComputeUnitPriceMin() {
bhe.lgr.Warnw("BlockHistoryEstimator: estimation below minimum consider lowering ComputeUnitPriceMin", "min", bhe.cfg.ComputeUnitPriceMin(), "calculated", bhe.price)
if price < bhe.cfg.ComputeUnitPriceMin() {
bhe.lgr.Warnw("BlockHistoryEstimator: estimation below minimum consider lowering ComputeUnitPriceMin", "min", bhe.cfg.ComputeUnitPriceMin(), "calculated", price)
return bhe.cfg.ComputeUnitPriceMin()
}

bhe.lgr.Warnw("BlockHistoryEstimator: estimation above maximum consider increasing ComputeUnitPriceMax", "min", bhe.cfg.ComputeUnitPriceMax(), "calculated", bhe.price)
bhe.lgr.Warnw("BlockHistoryEstimator: estimation above maximum consider increasing ComputeUnitPriceMax", "min", bhe.cfg.ComputeUnitPriceMax(), "calculated", price)
return bhe.cfg.ComputeUnitPriceMax()
}

func (bhe *blockHistoryEstimator) getPrice() error {
func (bhe *blockHistoryEstimator) readRawPrice() uint64 {
bhe.lock.RLock()
defer bhe.lock.RUnlock()
return bhe.price
}

func (bhe *blockHistoryEstimator) calculatePrice() error {
// fetch client
c, err := bhe.client.Get()
if err != nil {
Expand Down Expand Up @@ -132,7 +136,6 @@ func (bhe *blockHistoryEstimator) getPrice() error {
"blockhash", block.Blockhash,
"slot", block.ParentSlot+1,
"count", len(feeData.Prices),
"values", feeData.Prices,
)
return nil
}
40 changes: 33 additions & 7 deletions pkg/solana/fees/block_history_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package fees

import (
"encoding/json"
"fmt"
"io/ioutil"
"testing"
"time"

"github.com/gagliardetto/solana-go/rpc"
"github.com/stretchr/testify/assert"
Expand All @@ -20,6 +22,7 @@ import (
)

func TestBlockHistoryEstimator(t *testing.T) {
feePolling = 100 * time.Millisecond // TODO: make this part of cfg mock
min := uint64(10)
max := uint64(1000)

Expand All @@ -44,26 +47,49 @@ func TestBlockHistoryEstimator(t *testing.T) {
estimator, err := NewBlockHistoryEstimator(rwLoader, cfg, lgr)
require.NoError(t, err)

// TODO: test multiple client runs when configurable
rw.On("GetLatestBlock").Return(blockRes, nil).Once()
require.NoError(t, estimator.Start(ctx))
tests.AssertLogEventually(t, logs, "BlockHistoryEstimator: updated")
require.NoError(t, estimator.Close())
assert.Equal(t, uint64(55000), estimator.price)
assert.Equal(t, uint64(55000), estimator.readRawPrice())

// min/max gates
assert.Equal(t, max, estimator.BaseComputeUnitPrice())
estimator.price = 0
assert.Equal(t, min, estimator.BaseComputeUnitPrice())
estimator.price = 100
assert.Equal(t, estimator.price, estimator.BaseComputeUnitPrice())

// failed to get client
validPrice := uint64(100)
estimator.price = validPrice
assert.Equal(t, estimator.readRawPrice(), estimator.BaseComputeUnitPrice())

// failed to get latest block
rw.On("GetLatestBlock").Return(nil, fmt.Errorf("fail rpc call")).Once()
tests.AssertLogEventually(t, logs, "failed to get block")
assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails")

// failed to parse block
rw.On("GetLatestBlock").Return(nil, nil).Once()
tests.AssertLogEventually(t, logs, "failed to parse block")
assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails")

// failed to calculate median
rw.On("GetLatestBlock").Return(&rpc.GetBlockResult{}, nil).Once()
tests.AssertLogEventually(t, logs, "failed to find median")
assert.Equal(t, validPrice, estimator.BaseComputeUnitPrice(), "price should not change when getPrice fails")

// back to happy path
rw.On("GetLatestBlock").Return(blockRes, nil).Once()
tests.AssertEventually(t, func() bool {
return logs.FilterMessageSnippet("BlockHistoryEstimator: updated").Len() == 2
})
assert.Equal(t, uint64(55000), estimator.readRawPrice())
require.NoError(t, estimator.Close())

// failed to get client
rwFail := utils.NewLazyLoad(func() (client.ReaderWriter, error) {
return nil, fmt.Errorf("fail client load")
})
estimator, err = NewBlockHistoryEstimator(rwFail, cfg, lgr)
require.NoError(t, err)
require.NoError(t, estimator.Start(ctx))
tests.AssertLogEventually(t, logs, "failed to get client")
require.NoError(t, estimator.Close())
}
Loading

0 comments on commit 39b14f7

Please sign in to comment.