Skip to content

Commit

Permalink
fix(manager): only reset custom gas price (#1595)
Browse files Browse the repository at this point in the history
## Overview

This PR fixes custom gas price reset after a successful submission.

## Checklist

- [x] New and updated code has appropriate documentation
- [x] New and updated code has new and/or updated testing
- [x] Required CI checks are passing
- [x] Visual proof for any user facing features like CLI or
documentation updates
- [x] Linked issues closed with keywords


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **Bug Fixes**
- Modified the logic for adjusting `gasPrice` to prevent division
operation when not required.
- **Refactor**
- Refactored test cases for submitting blocks to a mock DA to cover
different scenarios.
- **Validation**
- Added a validation check for `DAGasMultiplier` in `nodeConfig` to meet
specific criteria.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
tuxcanfly committed Mar 19, 2024
1 parent b3ad562 commit 553e399
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 50 deletions.
12 changes: 7 additions & 5 deletions block/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -901,7 +901,7 @@ func (m *Manager) submitBlocksToDA(ctx context.Context) error {
res := m.dalc.SubmitBlocks(ctx, blocksToSubmit, maxBlobSize, gasPrice)
switch res.Code {
case da.StatusSuccess:
m.logger.Info("successfully submitted Rollkit blocks to DA layer", "daHeight", res.DAHeight, "count", res.SubmittedCount)
m.logger.Info("successfully submitted Rollkit blocks to DA layer", "gasPrice", gasPrice, "daHeight", res.DAHeight, "count", res.SubmittedCount)
if res.SubmittedCount == uint64(len(blocksToSubmit)) {
submittedAllBlocks = true
}
Expand All @@ -920,15 +920,17 @@ func (m *Manager) submitBlocksToDA(ctx context.Context) error {
// scale back gasPrice gradually
backoff = initialBackoff
maxBlobSize = initialMaxBlobSize
gasPrice = gasPrice / m.dalc.GasMultiplier
if gasPrice < initialGasPrice {
gasPrice = initialGasPrice
if m.dalc.GasMultiplier > 0 && gasPrice != -1 {
gasPrice = gasPrice / m.dalc.GasMultiplier
if gasPrice < initialGasPrice {
gasPrice = initialGasPrice
}
}
m.logger.Debug("resetting DA layer submission options", "backoff", backoff, "gasPrice", gasPrice, "maxBlobSize", maxBlobSize)
case da.StatusNotIncludedInBlock, da.StatusAlreadyInMempool:
m.logger.Error("DA layer submission failed", "error", res.Message, "attempt", attempt)
backoff = m.conf.DABlockTime * time.Duration(m.conf.DAMempoolTTL)
if m.dalc.GasMultiplier != -1 && gasPrice != -1 {
if m.dalc.GasMultiplier > 0 && gasPrice != -1 {
gasPrice = gasPrice * m.dalc.GasMultiplier
}
m.logger.Info("retrying DA layer submission with", "backoff", backoff, "gasPrice", gasPrice, "maxBlobSize", maxBlobSize)
Expand Down
110 changes: 67 additions & 43 deletions block/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (

// Returns a minimalistic block manager
func getManager(t *testing.T, backend goDA.DA) *Manager {
logger := test.NewFileLoggerCustom(t, test.TempLogFileName(t, t.Name()))
logger := test.NewLogger(t)
return &Manager{
dalc: da.NewDAClient(backend, -1, -1, nil, logger),
blockCache: NewBlockCache(),
Expand Down Expand Up @@ -138,49 +138,73 @@ func TestIsDAIncluded(t *testing.T) {
func TestSubmitBlocksToMockDA(t *testing.T) {
ctx := context.Background()

mockDA := &mock.MockDA{}
m := getManager(t, mockDA)
m.conf.DABlockTime = time.Millisecond
m.conf.DAMempoolTTL = 1
m.dalc.GasPrice = 1.0
m.dalc.GasMultiplier = 1.2
kvStore, err := store.NewDefaultInMemoryKVStore()
require.NoError(t, err)
m.store = store.New(kvStore)

t.Run("handle_tx_already_in_mempool", func(t *testing.T) {
var blobs [][]byte
block := types.GetRandomBlock(1, 5)
blob, err := block.MarshalBinary()
require.NoError(t, err)

err = m.store.SaveBlock(ctx, block, &types.Commit{})
require.NoError(t, err)
m.store.SetHeight(ctx, 1)

blobs = append(blobs, blob)
// Set up the mock to
// * throw timeout waiting for tx to be included exactly once
// * wait for tx to drop from mempool exactly DABlockTime * DAMempoolTTL seconds
// * retry with a higher gas price
// * successfully submit
mockDA.On("MaxBlobSize").Return(uint64(12345), nil)
mockDA.
On("Submit", blobs, 1.0, []byte(nil)).
Return([][]byte{}, da.ErrTxTimedout).Once()
mockDA.
On("Submit", blobs, 1.0*1.2, []byte(nil)).
Return([][]byte{}, da.ErrTxAlreadyInMempool).Times(int(m.conf.DAMempoolTTL))
mockDA.
On("Submit", blobs, 1.0*1.2*1.2, []byte(nil)).
Return([][]byte{bytes.Repeat([]byte{0x00}, 8)}, nil)
testCases := []struct {
name string
gasPrice float64
gasMultiplier float64
expectedGasPrices []float64
isErrExpected bool
}{
{"defaults", -1, -1, []float64{
-1, -1, -1,
}, false},
{"fixed_gas_price", 1.0, -1, []float64{
1.0, 1.0, 1.0,
}, false},
{"default_gas_price_with_multiplier", -1, 1.2, []float64{
-1, -1, -1,
}, false},
{"fixed_gas_price_with_multiplier", 1.0, 1.2, []float64{
1.0, 1.2, 1.2 * 1.2,
}, false},
}

m.pendingBlocks, err = NewPendingBlocks(m.store, m.logger)
require.NoError(t, err)
err = m.submitBlocksToDA(ctx)
require.NoError(t, err)
mockDA.AssertExpectations(t)
})
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
mockDA := &mock.MockDA{}
m := getManager(t, mockDA)
m.conf.DABlockTime = time.Millisecond
m.conf.DAMempoolTTL = 1
kvStore, err := store.NewDefaultInMemoryKVStore()
require.NoError(t, err)
m.store = store.New(kvStore)

var blobs [][]byte
block := types.GetRandomBlock(1, 5)
blob, err := block.MarshalBinary()
require.NoError(t, err)

err = m.store.SaveBlock(ctx, block, &types.Commit{})
require.NoError(t, err)
m.store.SetHeight(ctx, 1)

m.dalc.GasPrice = tc.gasPrice
m.dalc.GasMultiplier = tc.gasMultiplier

blobs = append(blobs, blob)
// Set up the mock to
// * throw timeout waiting for tx to be included exactly twice
// * wait for tx to drop from mempool exactly DABlockTime * DAMempoolTTL seconds
// * retry with a higher gas price
// * successfully submit
mockDA.On("MaxBlobSize").Return(uint64(12345), nil)
mockDA.
On("Submit", blobs, tc.expectedGasPrices[0], []byte(nil)).
Return([][]byte{}, da.ErrTxTimedout).Once()
mockDA.
On("Submit", blobs, tc.expectedGasPrices[1], []byte(nil)).
Return([][]byte{}, da.ErrTxTimedout).Once()
mockDA.
On("Submit", blobs, tc.expectedGasPrices[2], []byte(nil)).
Return([][]byte{bytes.Repeat([]byte{0x00}, 8)}, nil)

m.pendingBlocks, err = NewPendingBlocks(m.store, m.logger)
require.NoError(t, err)
err = m.submitBlocksToDA(ctx)
require.NoError(t, err)
mockDA.AssertExpectations(t)
})
}
}

func TestSubmitBlocksToDA(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/rollkit/docs/rollkit_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ rollkit start [flags]
--rollkit.da_address string DA address (host:port) (default "http://localhost:26658")
--rollkit.da_auth_token string DA auth token
--rollkit.da_block_time duration DA chain block time (for syncing) (default 15s)
--rollkit.da_gas_multiplier float DA gas price multiplier for retrying blob transactions (default -1)
--rollkit.da_gas_multiplier float DA gas price multiplier for retrying blob transactions
--rollkit.da_gas_price float DA gas price for blob transactions (default -1)
--rollkit.da_namespace string DA namespace to submit blob transactions
--rollkit.da_start_height uint starting DA block height (for syncing)
Expand Down
2 changes: 1 addition & 1 deletion config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var DefaultNodeConfig = NodeConfig{
},
DAAddress: "http://localhost:26658",
DAGasPrice: -1,
DAGasMultiplier: -1,
DAGasMultiplier: 0,
Light: false,
HeaderConfig: HeaderConfig{
TrustedHash: "",
Expand Down
4 changes: 4 additions & 0 deletions node/full.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,10 @@ func initDALC(nodeConfig config.NodeConfig, dalcKV ds.TxnDatastore, logger log.L
return nil, fmt.Errorf("error decoding namespace: %w", err)
}

if nodeConfig.DAGasMultiplier < 0 {
return nil, fmt.Errorf("gas multiplier must be greater than or equal to zero")
}

client, err := proxyda.NewClient(nodeConfig.DAAddress, nodeConfig.DAAuthToken)
if err != nil {
return nil, fmt.Errorf("error while establishing connection to DA layer: %w", err)
Expand Down

0 comments on commit 553e399

Please sign in to comment.