Skip to content

Commit

Permalink
Merge branch 'main' into mpeter/poc-index-finalized-block-results
Browse files Browse the repository at this point in the history
  • Loading branch information
peterargue authored Jan 30, 2025
2 parents 91b1ec0 + b23dc80 commit 2ddd052
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 42 deletions.
32 changes: 17 additions & 15 deletions bootstrap/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,25 +568,25 @@ func setupStorage(
storageAddress := evm.StorageAccountAddress(config.FlowNetworkID)
registerStore := pebble.NewRegisterStorage(store, storageAddress)

batch := store.NewBatch()
defer func() {
err := batch.Close()
if err != nil {
// we don't know what went wrong, so this is fatal
logger.Fatal().Err(err).Msg("failed to close batch")
}
}()

// hard set the start cadence height, this is used when force reindexing
if config.ForceStartCadenceHeight != 0 {
logger.Warn().Uint64("height", config.ForceStartCadenceHeight).Msg("force setting starting Cadence height!!!")
if err := blocks.SetLatestCadenceHeight(config.ForceStartCadenceHeight, nil); err != nil {
if err := blocks.SetLatestCadenceHeight(config.ForceStartCadenceHeight, batch); err != nil {
return nil, nil, err
}
}

// if database is not initialized require init height
if _, err := blocks.LatestCadenceHeight(); errors.Is(err, errs.ErrStorageNotInitialized) {
batch := store.NewBatch()
defer func(batch *pebbleDB.Batch) {
err := batch.Close()
if err != nil {
// we don't know what went wrong, so this is fatal
logger.Fatal().Err(err).Msg("failed to close batch")
}
}(batch)

cadenceHeight := config.InitCadenceHeight
evmBlokcHeight := uint64(0)
cadenceBlock, err := client.GetBlockHeaderByHeight(context.Background(), cadenceHeight)
Expand Down Expand Up @@ -624,11 +624,6 @@ func setupStorage(
)
}

err = batch.Commit(pebbleDB.Sync)
if err != nil {
return nil, nil, fmt.Errorf("could not commit register updates: %w", err)
}

logger.Info().
Stringer("fvm_address_for_evm_storage_account", storageAddress).
Msgf("database initialized with cadence height: %d", cadenceHeight)
Expand All @@ -637,6 +632,13 @@ func setupStorage(
// // TODO(JanezP): verify storage account owner is correct
// }

if batch.Count() > 0 {
err = batch.Commit(pebbleDB.Sync)
if err != nil {
return nil, nil, fmt.Errorf("could not commit setup updates: %w", err)
}
}

return db, &Storages{
Storage: store,
Blocks: blocks,
Expand Down
53 changes: 33 additions & 20 deletions metrics/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,24 @@ type Collector interface {
MeasureRequestDuration(start time.Time, method string)
OperatorBalance(account *flow.Account)
AvailableSigningKeys(count int)
GasEstimationIterations(count int)
}

var _ Collector = &DefaultCollector{}

type DefaultCollector struct {
// TODO: for now we cannot differentiate which api request failed number of times
apiErrorsCounter prometheus.Counter
serverPanicsCounters *prometheus.CounterVec
cadenceBlockHeight prometheus.Gauge
evmBlockHeight prometheus.Gauge
evmBlockIndexedCounter prometheus.Counter
evmTxIndexedCounter prometheus.Counter
operatorBalance prometheus.Gauge
evmAccountCallCounters *prometheus.CounterVec
requestDurations *prometheus.HistogramVec
availableSigningkeys prometheus.Gauge
apiErrorsCounter prometheus.Counter
serverPanicsCounters *prometheus.CounterVec
cadenceBlockHeight prometheus.Gauge
evmBlockHeight prometheus.Gauge
evmBlockIndexedCounter prometheus.Counter
evmTxIndexedCounter prometheus.Counter
operatorBalance prometheus.Gauge
evmAccountCallCounters *prometheus.CounterVec
requestDurations *prometheus.HistogramVec
availableSigningkeys prometheus.Gauge
gasEstimationIterations prometheus.Gauge
}

func NewCollector(logger zerolog.Logger) Collector {
Expand Down Expand Up @@ -90,6 +92,11 @@ func NewCollector(logger zerolog.Logger) Collector {
Help: "Number of keys available for transaction signing",
})

gasEstimationIterations := prometheus.NewGauge(prometheus.GaugeOpts{
Name: prefixedName("gas_estimation_iterations"),
Help: "Number of iterations taken to estimate the gas of a EVM call/tx",
})

metrics := []prometheus.Collector{
apiErrors,
serverPanicsCounters,
Expand All @@ -101,23 +108,25 @@ func NewCollector(logger zerolog.Logger) Collector {
evmAccountCallCounters,
requestDurations,
availableSigningKeys,
gasEstimationIterations,
}
if err := registerMetrics(logger, metrics...); err != nil {
logger.Info().Msg("using noop collector as metric register failed")
return NopCollector
}

return &DefaultCollector{
apiErrorsCounter: apiErrors,
serverPanicsCounters: serverPanicsCounters,
cadenceBlockHeight: cadenceBlockHeight,
evmBlockHeight: evmBlockHeight,
evmBlockIndexedCounter: evmBlockIndexedCounter,
evmTxIndexedCounter: evmTxIndexedCounter,
evmAccountCallCounters: evmAccountCallCounters,
requestDurations: requestDurations,
operatorBalance: operatorBalance,
availableSigningkeys: availableSigningKeys,
apiErrorsCounter: apiErrors,
serverPanicsCounters: serverPanicsCounters,
cadenceBlockHeight: cadenceBlockHeight,
evmBlockHeight: evmBlockHeight,
evmBlockIndexedCounter: evmBlockIndexedCounter,
evmTxIndexedCounter: evmTxIndexedCounter,
evmAccountCallCounters: evmAccountCallCounters,
requestDurations: requestDurations,
operatorBalance: operatorBalance,
availableSigningkeys: availableSigningKeys,
gasEstimationIterations: gasEstimationIterations,
}
}

Expand Down Expand Up @@ -172,6 +181,10 @@ func (c *DefaultCollector) AvailableSigningKeys(count int) {
c.availableSigningkeys.Set(float64(count))
}

func (c *DefaultCollector) GasEstimationIterations(count int) {
c.gasEstimationIterations.Set(float64(count))
}

func prefixedName(name string) string {
return fmt.Sprintf("evm_gateway_%s", name)
}
1 change: 1 addition & 0 deletions metrics/nop.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ func (c *nopCollector) EVMAccountInteraction(string) {}
func (c *nopCollector) MeasureRequestDuration(time.Time, string) {}
func (c *nopCollector) OperatorBalance(*flow.Account) {}
func (c *nopCollector) AvailableSigningKeys(count int) {}
func (c *nopCollector) GasEstimationIterations(count int) {}
3 changes: 2 additions & 1 deletion services/requester/key_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (

flowsdk "github.com/onflow/flow-go-sdk"
"github.com/onflow/flow-go-sdk/crypto"
"github.com/onflow/flow-go/model/flow"
)

var ErrNoKeysAvailable = fmt.Errorf("no keys available")

const accountKeyBlockExpiration = 1_000
const accountKeyBlockExpiration = flow.DefaultTransactionExpiry

type AccountKey struct {
flowsdk.AccountKey
Expand Down
25 changes: 19 additions & 6 deletions services/requester/requester.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ func (e *EVM) EstimateGas(
height uint64,
stateOverrides *ethTypes.StateOverride,
) (uint64, error) {
iterations := 0

dryRun := func(gasLimit uint64) (*evmTypes.Result, error) {
tx.Gas = gasLimit
result, err := e.dryRunTx(tx, from, height, stateOverrides, nil)
iterations += 1
return result, err
}

// Note: The following algorithm, is largely inspired from
// https://github.com/onflow/go-ethereum/blob/master/eth/gasestimator/gasestimator.go#L49-L192,
// and adapted to fit our use-case.
Expand All @@ -323,10 +332,10 @@ func (e *EVM) EstimateGas(
if tx.Gas >= gethParams.TxGas {
passingGasLimit = tx.Gas
}
tx.Gas = passingGasLimit

// We first execute the transaction at the highest allowable gas limit,
// since if this fails we can return the error immediately.
result, err := e.dryRunTx(tx, from, height, stateOverrides, nil)
result, err := dryRun(passingGasLimit)
if err != nil {
return 0, err
}
Expand All @@ -338,6 +347,12 @@ func (e *EVM) EstimateGas(
return 0, errs.NewFailedTransactionError(resultSummary.ErrorMessage)
}

// We do not want to report iterations for calls/transactions
// that errored out or had their execution reverted.
defer func() {
e.collector.GasEstimationIterations(iterations)
}()

// For almost any transaction, the gas consumed by the unconstrained execution
// above lower-bounds the gas limit required for it to succeed. One exception
// is those that explicitly check gas remaining in order to execute within a
Expand All @@ -350,8 +365,7 @@ func (e *EVM) EstimateGas(
// Explicitly check that gas amount and use as a limit for the binary search.
optimisticGasLimit := (result.GasConsumed + result.GasRefund + gethParams.CallStipend) * 64 / 63
if optimisticGasLimit < passingGasLimit {
tx.Gas = optimisticGasLimit
result, err = e.dryRunTx(tx, from, height, stateOverrides, nil)
result, err := dryRun(optimisticGasLimit)
if err != nil {
// This should not happen under normal conditions since if we make it this far the
// transaction had run without error at least once before.
Expand Down Expand Up @@ -380,8 +394,7 @@ func (e *EVM) EstimateGas(
// range here is skewed to favor the low side.
mid = failingGasLimit * 2
}
tx.Gas = mid
result, err = e.dryRunTx(tx, from, height, stateOverrides, nil)
result, err := dryRun(mid)
if err != nil {
return 0, err
}
Expand Down

0 comments on commit 2ddd052

Please sign in to comment.