diff --git a/go/enclave/rpc/EstimateGas.go b/go/enclave/rpc/EstimateGas.go index 0c583da43e..13a337e129 100644 --- a/go/enclave/rpc/EstimateGas.go +++ b/go/enclave/rpc/EstimateGas.go @@ -94,7 +94,7 @@ func EstimateGasExecute(builder *CallBuilder[CallParamsWithBlock, hexutil.Uint64 // TODO: Change to fixed time period quotes, rather than this. publishingGas = publishingGas.Mul(publishingGas, gethcommon.Big2) - executionGasEstimate, err := rpc.doEstimateGas(builder.ctx, txArgs, blockNumber, rpc.config.GasLocalExecutionCapFlag) + executionGasEstimate, gasPrice, err := rpc.doEstimateGas(builder.ctx, txArgs, blockNumber, rpc.config.GasLocalExecutionCapFlag) if err != nil { err = fmt.Errorf("unable to estimate transaction - %w", err) @@ -107,7 +107,17 @@ func EstimateGasExecute(builder *CallBuilder[CallParamsWithBlock, hexutil.Uint64 return nil } - totalGasEstimate := hexutil.Uint64(publishingGas.Uint64() + uint64(executionGasEstimate)) + totalGasEstimateUint64 := publishingGas.Uint64() + uint64(executionGasEstimate) + totalGasEstimate := hexutil.Uint64(totalGasEstimateUint64) + balance, err := rpc.chain.GetBalanceAtBlock(builder.ctx, *txArgs.From, blockNumber) + if err != nil { + return err + } + + if balance.ToInt().Cmp(big.NewInt(0).Mul(gasPrice, big.NewInt(0).SetUint64(totalGasEstimateUint64))) < 0 { + return fmt.Errorf("insufficient funds for gas estimate") + } + builder.ReturnValue = &totalGasEstimate return nil } @@ -116,7 +126,7 @@ func EstimateGasExecute(builder *CallBuilder[CallParamsWithBlock, hexutil.Uint64 // This is a copy of https://github.com/ethereum/go-ethereum/blob/master/internal/ethapi/api.go#L1055 // there's a high complexity to the method due to geth business rules (which is mimic'd here) // once the work of obscuro gas mechanics is established this method should be simplified -func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.TransactionArgs, blkNumber *gethrpc.BlockNumber, gasCap uint64) (hexutil.Uint64, common.SystemError) { //nolint: gocognit +func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.TransactionArgs, blkNumber *gethrpc.BlockNumber, gasCap uint64) (hexutil.Uint64, *big.Int, common.SystemError) { //nolint: gocognit // Binary search the gas requirement, as it may be higher than the amount used var ( //nolint: revive lo = params.TxGas - 1 @@ -148,7 +158,7 @@ func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.T // Normalize the max fee per gas the call is willing to spend. var feeCap *big.Int if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { - return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") + return 0, gethcommon.Big0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") } else if args.GasPrice != nil { feeCap = args.GasPrice.ToInt() } else if args.MaxFeePerGas != nil { @@ -160,13 +170,13 @@ func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.T if feeCap.BitLen() != 0 { //nolint:nestif balance, err := rpc.chain.GetBalanceAtBlock(ctx, *args.From, blkNumber) if err != nil { - return 0, fmt.Errorf("unable to fetch account balance - %w", err) + return 0, gethcommon.Big0, fmt.Errorf("unable to fetch account balance - %w", err) } available := new(big.Int).Set(balance.ToInt()) if args.Value != nil { if args.Value.ToInt().Cmp(available) >= 0 { - return 0, errors.New("insufficient funds for transfer") + return 0, gethcommon.Big0, errors.New("insufficient funds for transfer") } available.Sub(available, args.Value.ToInt()) } @@ -204,7 +214,7 @@ func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.T // call or transaction will never be accepted no matter how much gas it is // assigned. Return the error directly, don't struggle any more. if err != nil { - return 0, err + return 0, gethcommon.Big0, err } if failed { lo = mid @@ -216,20 +226,20 @@ func (rpc *EncryptionManager) doEstimateGas(ctx context.Context, args *gethapi.T if hi == cap { //nolint:nestif failed, result, err := rpc.isGasEnough(ctx, args, hi, blkNumber) if err != nil { - return 0, err + return 0, gethcommon.Big0, err } if failed { if result != nil && result.Err != vm.ErrOutOfGas { //nolint: errorlint if len(result.Revert()) > 0 { - return 0, newRevertError(result) + return 0, gethcommon.Big0, newRevertError(result) } - return 0, result.Err + return 0, gethcommon.Big0, result.Err } // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, gethcommon.Big0, fmt.Errorf("gas required exceeds allowance (%d)", cap) } } - return hexutil.Uint64(hi), nil + return hexutil.Uint64(hi), feeCap, nil } // Create a helper to check if a gas allowance results in an executable transaction diff --git a/go/host/enclave/guardian.go b/go/host/enclave/guardian.go index 8ff5ead9ff..105a34baa2 100644 --- a/go/host/enclave/guardian.go +++ b/go/host/enclave/guardian.go @@ -123,7 +123,6 @@ func (g *Guardian) Start() error { // Note: after HA work this will need additional check that we are the **active** sequencer enclave go g.periodicBatchProduction() go g.periodicRollupProduction() - //go g.periodicBundleSubmission() } // subscribe for L1 and P2P data @@ -626,55 +625,6 @@ func (g *Guardian) periodicRollupProduction() { } } -func (g *Guardian) periodicBundleSubmission() { - defer g.logger.Info("Stopping bundle submission") - - interval := g.crossChainInterval - g.logger.Info("Starting cross chain bundle submission", "interval", interval) - - bundleSubmissionTicker := time.NewTicker(interval) - - fromSequenceNumber := uint64(0) - - for { - select { - case <-bundleSubmissionTicker.C: - from, to, err := g.sl.L1Publisher().GetBundleRangeFromManagementContract() - if err != nil { - g.logger.Error("Unable to get bundle range from management contract", log.ErrKey, err) - continue - } - - if from.Uint64() > fromSequenceNumber { - fromSequenceNumber = from.Uint64() - } - - bundle, err := g.enclaveClient.ExportCrossChainData(context.Background(), fromSequenceNumber, to.Uint64()) - if err != nil { - if !errors.Is(err, errutil.ErrCrossChainBundleNoBatches) { - g.logger.Error("Unable to export cross chain bundle from enclave", log.ErrKey, err) - } - continue - } - - if len(bundle.CrossChainRootHashes) == 0 { - g.logger.Debug("No cross chain data to submit") - fromSequenceNumber = to.Uint64() + 1 - continue - } - - err = g.sl.L1Publisher().PublishCrossChainBundle(bundle) - if err != nil { - g.logger.Error("Unable to publish cross chain bundle", log.ErrKey, err) - continue - } - case <-g.hostInterrupter.Done(): - bundleSubmissionTicker.Stop() - return - } - } -} - func (g *Guardian) streamEnclaveData() { defer g.logger.Info("Stopping enclave data stream") g.logger.Info("Starting L2 update stream from enclave")