Skip to content

Commit f4bd7da

Browse files
author
Alok
committed
fix: temp
1 parent 2eb1f54 commit f4bd7da

File tree

5 files changed

+171
-89
lines changed

5 files changed

+171
-89
lines changed

tools/preconf-rpc/blocktracker/blocktracker.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package blocktracker
22

33
import (
44
"context"
5+
"errors"
56
"log/slog"
67
"math/big"
78
"sync"
@@ -64,8 +65,8 @@ func (b *blockTracker) Start(ctx context.Context) <-chan struct{} {
6465
}
6566
_ = b.blocks.Add(blockNo, block)
6667
b.latestBlockNo.Store(block.NumberU64())
67-
b.log.Debug("New block detected", "number", block.NumberU64(), "hash", block.Hash().Hex())
6868
b.triggerCheck()
69+
b.log.Debug("New block detected", "number", block.NumberU64(), "hash", block.Hash().Hex())
6970
}
7071
}
7172
}
@@ -83,6 +84,15 @@ func (b *blockTracker) LatestBlockNumber() uint64 {
8384
return b.latestBlockNo.Load()
8485
}
8586

87+
func (b *blockTracker) NextBlockNumber() (uint64, time.Duration, error) {
88+
block, found := b.blocks.Get(b.latestBlockNo.Load())
89+
if !found {
90+
return 0, 0, errors.New("latest block not found in cache")
91+
}
92+
blockTime := time.Unix(int64(block.Time()), 0)
93+
return b.latestBlockNo.Load() + 1, time.Until(blockTime.Add(12 * time.Second)), nil
94+
}
95+
8696
func (b *blockTracker) CheckTxnInclusion(
8797
ctx context.Context,
8898
txHash common.Hash,

tools/preconf-rpc/blocktracker/blocktracker_test.go

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ package blocktracker_test
33
import (
44
"context"
55
"hash"
6-
"log/slog"
76
"math/big"
7+
"os"
88
"testing"
9+
"time"
910

1011
"github.com/ethereum/go-ethereum/common"
1112
"github.com/ethereum/go-ethereum/core/types"
1213
"github.com/primev/mev-commit/tools/preconf-rpc/blocktracker"
14+
"github.com/primev/mev-commit/x/util"
1315
"golang.org/x/crypto/sha3"
1416
)
1517

@@ -74,7 +76,7 @@ func TestBlockTracker(t *testing.T) {
7476
blk1 := types.NewBlock(
7577
&types.Header{
7678
Number: big.NewInt(100),
77-
Time: 1622547800,
79+
Time: uint64(time.Now().Unix()),
7880
},
7981
&types.Body{Transactions: []*types.Transaction{tx1, tx2}},
8082
nil, // No receipts
@@ -84,7 +86,7 @@ func TestBlockTracker(t *testing.T) {
8486
blk2 := types.NewBlock(
8587
&types.Header{
8688
Number: big.NewInt(101),
87-
Time: 1622547900,
89+
Time: uint64(time.Now().Add(12 * time.Second).Unix()),
8890
},
8991
&types.Body{Transactions: []*types.Transaction{tx3}},
9092
nil, // No receipts
@@ -99,7 +101,7 @@ func TestBlockTracker(t *testing.T) {
99101
},
100102
}
101103

102-
tracker, err := blocktracker.NewBlockTracker(client, slog.Default())
104+
tracker, err := blocktracker.NewBlockTracker(client, util.NewTestLogger(os.Stdout))
103105
if err != nil {
104106
t.Fatalf("Failed to create block tracker: %v", err)
105107
}
@@ -112,6 +114,26 @@ func TestBlockTracker(t *testing.T) {
112114

113115
client.blockNumber <- 100
114116

117+
start := time.Now()
118+
for {
119+
bidBlockNo, duration, err := tracker.NextBlockNumber()
120+
if err == nil {
121+
if bidBlockNo != 101 {
122+
t.Fatalf("Expected next block number to be 101, got %d", bidBlockNo)
123+
}
124+
if duration <= 0 {
125+
t.Fatalf("Expected positive duration, got %v", duration)
126+
}
127+
break
128+
} else {
129+
t.Logf("Waiting for next block number: %v", err)
130+
}
131+
if time.Since(start) > 5*time.Second {
132+
t.Fatalf("Timeout waiting for next block number")
133+
}
134+
time.Sleep(100 * time.Millisecond)
135+
}
136+
115137
included, err := tracker.CheckTxnInclusion(ctx, tx1.Hash(), 100)
116138
if err != nil {
117139
t.Fatalf("Error checking transaction inclusion: %v", err)
@@ -128,6 +150,22 @@ func TestBlockTracker(t *testing.T) {
128150

129151
client.blockNumber <- 101
130152

153+
start = time.Now()
154+
for {
155+
bidBlockNo, duration, err := tracker.NextBlockNumber()
156+
if err == nil {
157+
if bidBlockNo == 102 && duration > 0 {
158+
break
159+
}
160+
} else {
161+
t.Logf("Waiting for next block number: %v", err)
162+
}
163+
if time.Since(start) > 5*time.Second {
164+
t.Fatalf("Timeout waiting for next block number")
165+
}
166+
time.Sleep(100 * time.Millisecond)
167+
}
168+
131169
included, err = tracker.CheckTxnInclusion(ctx, tx4.Hash(), 101)
132170
if err != nil {
133171
t.Fatalf("Error checking transaction inclusion: %v", err)

tools/preconf-rpc/pricer/pricer.go

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,27 @@ type blockPrices struct {
2929
}
3030

3131
type BidPricer struct {
32-
apiKey string
33-
log *slog.Logger
34-
mu sync.RWMutex // Protects currentEstimates
35-
currentEstimates map[int64]float64
32+
apiKey string
33+
log *slog.Logger
34+
mu sync.RWMutex // Protects currentEstimates
35+
currentEstimates map[int64]float64
36+
currentBlockNumber int64
3637
}
3738

38-
func NewPricer(apiKey string, logger *slog.Logger) *BidPricer {
39-
return &BidPricer{
40-
apiKey: apiKey,
41-
log: logger,
39+
func NewPricer(apiKey string, logger *slog.Logger) (*BidPricer, error) {
40+
bp := &BidPricer{
41+
apiKey: apiKey,
42+
log: logger,
43+
currentEstimates: make(map[int64]float64),
4244
}
45+
46+
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
47+
defer cancel()
48+
49+
if err := bp.syncEstimate(ctx); err != nil {
50+
return nil, err
51+
}
52+
return bp, nil
4353
}
4454

4555
func (b *BidPricer) Start(ctx context.Context) <-chan struct{} {
@@ -54,7 +64,7 @@ func (b *BidPricer) Start(ctx context.Context) <-chan struct{} {
5464
case <-ctx.Done():
5565
return
5666
case <-ticker.C:
57-
if _, err := b.syncEstimate(ctx); err != nil {
67+
if err := b.syncEstimate(ctx); err != nil {
5868
b.log.Error("Failed to estimate price", "error", err)
5969
}
6070
}
@@ -68,20 +78,20 @@ func (b *BidPricer) EstimatePrice(ctx context.Context) map[int64]float64 {
6878
defer b.mu.RUnlock()
6979

7080
estimates := make(map[int64]float64)
71-
for blockNumber, price := range b.currentEstimates {
72-
estimates[blockNumber] = price
81+
for confidence, price := range b.currentEstimates {
82+
estimates[confidence] = price
7383
}
7484
return estimates
7585
}
7686

77-
func (b *BidPricer) SyncEstimate(ctx context.Context) error {
87+
func (b *BidPricer) syncEstimate(ctx context.Context) error {
7888
client := &http.Client{
7989
Timeout: 10 * time.Second,
8090
}
8191

8292
req, err := http.NewRequestWithContext(ctx, "GET", apiURL, nil)
8393
if err != nil {
84-
return nil, err
94+
return err
8595
}
8696

8797
if b.apiKey != "" {
@@ -90,30 +100,51 @@ func (b *BidPricer) SyncEstimate(ctx context.Context) error {
90100

91101
resp, err := client.Do(req)
92102
if err != nil {
93-
return nil, err
103+
return err
94104
}
95105

96106
defer func() {
97107
_ = resp.Body.Close()
98108
}()
99109

100110
if resp.StatusCode != http.StatusOK {
101-
return nil, errors.New("failed to fetch price estimate: " + resp.Status)
111+
return errors.New("failed to fetch price estimate: " + resp.Status)
102112
}
103113

104114
respBuf, err := io.ReadAll(io.LimitReader(resp.Body, 1024*1024))
105115
if err != nil {
106-
return nil, err
116+
return err
107117
}
108118

109119
bp := new(blockPrices)
110120
if err := json.Unmarshal(respBuf, bp); err != nil {
111-
return nil, err
121+
return err
112122
}
113123

114124
if len(bp.Prices) == 0 {
115-
return nil, errors.New("no block prices available")
125+
return errors.New("no block prices available")
116126
}
117127

118-
return bp, nil
128+
if b.currentBlockNumber < bp.CurrentBlockNumber+1 {
129+
for _, price := range bp.Prices {
130+
if price.BlockNumber == bp.CurrentBlockNumber+1 {
131+
b.mu.Lock()
132+
for _, estimatedPrice := range price.EstimatedPrices {
133+
switch estimatedPrice.Confidence {
134+
case 90:
135+
b.currentEstimates[int64(estimatedPrice.Confidence)] = estimatedPrice.PriorityFeePerGasGwei
136+
case 95:
137+
b.currentEstimates[int64(estimatedPrice.Confidence)] = estimatedPrice.PriorityFeePerGasGwei
138+
case 99:
139+
b.currentEstimates[int64(estimatedPrice.Confidence)] = estimatedPrice.PriorityFeePerGasGwei
140+
}
141+
}
142+
b.currentBlockNumber = price.BlockNumber
143+
b.mu.Unlock()
144+
b.log.Debug("Updated current estimates", "blockNumber", price.BlockNumber, "estimates", b.currentEstimates)
145+
}
146+
}
147+
}
148+
149+
return nil
119150
}

tools/preconf-rpc/pricer/pricer_test.go

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,36 @@ package pricer_test
22

33
import (
44
"context"
5+
"io"
56
"testing"
67

78
"github.com/primev/mev-commit/tools/preconf-rpc/pricer"
9+
"github.com/primev/mev-commit/x/util"
810
)
911

1012
func TestEstimatePrice(t *testing.T) {
1113
t.Parallel()
1214

13-
bp := pricer.NewPricer("")
14-
15-
ctx := context.Background()
16-
17-
prices, err := bp.EstimatePrice(ctx)
15+
logger := util.NewTestLogger(io.Discard)
16+
bp, err := pricer.NewPricer("", logger)
1817
if err != nil {
19-
t.Fatalf("failed to estimate price: %v", err)
20-
}
21-
22-
if prices.CurrentBlockNumber == 0 {
23-
t.Error("expected non-zero current block number")
18+
t.Fatalf("failed to create pricer: %v", err)
2419
}
2520

26-
if len(prices.Prices) == 0 {
27-
t.Error("expected at least one block price")
28-
}
21+
ctx := context.Background()
2922

30-
price := prices.Prices[0]
23+
prices := bp.EstimatePrice(ctx)
3124

32-
if price.BlockNumber == 0 {
33-
t.Error("expected non-zero block number in price")
25+
if len(prices) != 3 {
26+
t.Fatalf("expected 3 confidence levels, got %d", len(prices))
3427
}
3528

36-
if len(price.EstimatedPrices) == 0 {
37-
t.Error("expected at least one estimated price")
38-
}
39-
40-
for _, estPrice := range price.EstimatedPrices {
41-
if estPrice.PriorityFeePerGasGwei <= 0 {
42-
t.Errorf("expected positive priority fee per gas, got %f", estPrice.PriorityFeePerGasGwei)
29+
for confidence, price := range prices {
30+
if confidence <= 0 {
31+
t.Errorf("expected positive confidence level, got %d", confidence)
32+
}
33+
if price <= 0 {
34+
t.Errorf("expected positive price, got %f", price)
4335
}
4436
}
4537

0 commit comments

Comments
 (0)