From 61598ba1320ac8a033338371be8dab20edeebada Mon Sep 17 00:00:00 2001 From: shampoo bera Date: Tue, 16 May 2023 17:16:34 -0400 Subject: [PATCH 1/2] support processing of bundle txs and bundle API --- core/state_processor.go | 56 ++++++ eth/.api.go.swp | Bin 0 -> 16384 bytes eth/.backend.go.swp | Bin 0 -> 16384 bytes eth/backend.go | 2 +- go.mod | 1 - go.sum | 2 - internal/ethapi/.api.go.swp | Bin 0 -> 24576 bytes internal/ethapi/api.go | 335 ++++++++++++++++++++++++++++++++++++ internal/ethapi/backend.go | 5 +- internal/web3ext/web3ext.go | 10 ++ les/client.go | 2 +- 11 files changed, 407 insertions(+), 6 deletions(-) create mode 100644 eth/.api.go.swp create mode 100644 eth/.backend.go.swp create mode 100644 internal/ethapi/.api.go.swp diff --git a/core/state_processor.go b/core/state_processor.go index 25266f13b49f..9565184094d4 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -145,6 +145,51 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta return receipt, err } +func applyTransactionWithResult(msg *Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (*types.Receipt, *ExecutionResult, error) { + // Create a new context to be used in the EVM environment. + txContext := NewEVMTxContext(msg) + evm.Reset(txContext, statedb) + + // Apply the transaction to the current state (included in the env). + result, err := ApplyMessage(evm, msg, gp) + if err != nil { + return nil, nil, err + } + + // Update the state with pending changes. + var root []byte + if config.IsByzantium(header.Number) { + statedb.Finalise(true) + } else { + root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() + } + *usedGas += result.UsedGas + + // Create a new receipt for the transaction, storing the intermediate root and gas used + // by the tx. + receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: *usedGas} + if result.Failed() { + receipt.Status = types.ReceiptStatusFailed + } else { + receipt.Status = types.ReceiptStatusSuccessful + } + receipt.TxHash = tx.Hash() + receipt.GasUsed = result.UsedGas + + // If the transaction created a contract, store the creation address in the receipt. + if msg.To == nil { + receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) + } + + // Set the receipt logs and create the bloom filter. + receipt.Logs = statedb.GetLogs(tx.Hash(), header.Number.Uint64(), header.Hash()) + receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) + receipt.BlockHash = header.Hash() + receipt.BlockNumber = header.Number + receipt.TransactionIndex = uint(statedb.TxIndex()) + return receipt, result, err +} + // ApplyTransaction attempts to apply a transaction to the given state database // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, @@ -159,3 +204,14 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg) return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv) } + +func ApplyTransactionWithResult(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *ExecutionResult, error) { + msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee) + if err != nil { + return nil, nil, err + } + // Create a new context to be used in the EVM environment + blockContext := NewEVMBlockContext(header, bc, author) + vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg) + return applyTransactionWithResult(msg, config, bc, author, gp, statedb, header, tx, usedGas, vmenv) +} diff --git a/eth/.api.go.swp b/eth/.api.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..92231ea4e24220e85789dea35982029c10f4e697 GIT binary patch literal 16384 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 b980m^Wh6!6vucOWsGxeC5t!#7nRWjL_>MAp literal 0 HcmV?d00001 diff --git a/eth/.backend.go.swp b/eth/.backend.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..354fecf863fc89498958cbf6f8a5deb822804a02 GIT binary patch literal 16384 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 Ns_;6qI$x@5`7i5|sSW@D literal 0 HcmV?d00001 diff --git a/eth/backend.go b/eth/backend.go index 4caab9bad605..f7f68611b0ab 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -282,7 +282,7 @@ func makeExtraData(extra []byte) []byte { // APIs return the collection of RPC services the ethereum package offers. // NOTE, some of these services probably need to be moved to somewhere else. func (s *Ethereum) APIs() []rpc.API { - apis := ethapi.GetAPIs(s.APIBackend) + apis := ethapi.GetAPIs(s.APIBackend, s.BlockChain()) // Append any APIs exposed explicitly by the consensus engine apis = append(apis, s.engine.APIs(s.BlockChain())...) diff --git a/go.mod b/go.mod index c3e4ee0b49e5..10703446f9d3 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,6 @@ require ( github.com/deckarep/golang-set/v2 v2.1.0 github.com/docker/docker v1.6.2 github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 - github.com/edsrzf/mmap-go v1.0.0 github.com/fatih/color v1.7.0 github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 diff --git a/go.sum b/go.sum index 1022db1e43a9..7b7b0214bbe2 100644 --- a/go.sum +++ b/go.sum @@ -112,8 +112,6 @@ github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOG github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= diff --git a/internal/ethapi/.api.go.swp b/internal/ethapi/.api.go.swp new file mode 100644 index 0000000000000000000000000000000000000000..f21ba8394907d6bc36e01eff7fcc15db13e684cf GIT binary patch literal 24576 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 0 { + ctx, cancel = context.WithTimeout(ctx, timeout) + } else { + ctx, cancel = context.WithCancel(ctx) + } + // Make sure the context is cancelled when the call has completed + // this makes sure resources are cleaned up. + defer cancel() + + state, parent, err := s.b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash) + if state == nil || err != nil { + return nil, err + } + blockNumber := big.NewInt(int64(args.BlockNumber)) + + timestamp := parent.Time + 1 + if args.Timestamp != nil { + timestamp = *args.Timestamp + } + coinbase := parent.Coinbase + if args.Coinbase != nil { + coinbase = common.HexToAddress(*args.Coinbase) + } + difficulty := parent.Difficulty + if args.Difficulty != nil { + difficulty = args.Difficulty + } + gasLimit := parent.GasLimit + if args.GasLimit != nil { + gasLimit = *args.GasLimit + } + var baseFee *big.Int + if args.BaseFee != nil { + baseFee = args.BaseFee + } else if s.b.ChainConfig().IsLondon(big.NewInt(args.BlockNumber.Int64())) { + baseFee = misc.CalcBaseFee(s.b.ChainConfig(), parent) + } + header := &types.Header{ + ParentHash: parent.Hash(), + Number: blockNumber, + GasLimit: gasLimit, + Time: timestamp, + Difficulty: difficulty, + Coinbase: coinbase, + BaseFee: baseFee, + } + + vmconfig := vm.Config{} + + // Setup the gas pool (also for unmetered requests) + // and apply the message. + gp := new(core.GasPool).AddGas(math.MaxUint64) + + results := []map[string]interface{}{} + coinbaseBalanceBefore := state.GetBalance(coinbase) + + bundleHash := sha3.NewLegacyKeccak256() + signer := types.MakeSigner(s.b.ChainConfig(), blockNumber, 0) + var totalGasUsed uint64 + gasFees := new(big.Int) + for _, tx := range txs { + // Check if the context was cancelled (eg. timed-out) + if err := ctx.Err(); err != nil { + return nil, err + } + + coinbaseBalanceBeforeTx := state.GetBalance(coinbase) + isPostMerge := header.Difficulty.Cmp(common.Big0) == 0 + + cfg := s.b.ChainConfig() + rules := s.b.ChainConfig().Rules(header.Number, isPostMerge, header.Time) + + msg, err := core.TransactionToMessage(tx, types.MakeSigner(cfg, header.Number, header.Time), header.BaseFee) + state.Prepare(rules, msg.From, coinbase, msg.To, vm.ActivePrecompiles(rules), nil) + + receipt, result, err := core.ApplyTransactionWithResult(s.b.ChainConfig(), s.chain, &coinbase, gp, state, header, tx, &header.GasUsed, vmconfig) + if err != nil { + return nil, fmt.Errorf("err: %w; txhash %s", err, tx.Hash()) + } + + txHash := tx.Hash().String() + from, err := types.Sender(signer, tx) + if err != nil { + return nil, fmt.Errorf("err: %w; txhash %s", err, tx.Hash()) + } + to := "0x" + if tx.To() != nil { + to = tx.To().String() + } + jsonResult := map[string]interface{}{ + "txHash": txHash, + "gasUsed": receipt.GasUsed, + "fromAddress": from.String(), + "toAddress": to, + } + totalGasUsed += receipt.GasUsed + gasPrice, err := tx.EffectiveGasTip(header.BaseFee) + if err != nil { + return nil, fmt.Errorf("err: %w; txhash %s", err, tx.Hash()) + } + gasFeesTx := new(big.Int).Mul(big.NewInt(int64(receipt.GasUsed)), gasPrice) + gasFees.Add(gasFees, gasFeesTx) + bundleHash.Write(tx.Hash().Bytes()) + if result.Err != nil { + jsonResult["error"] = result.Err.Error() + revert := result.Revert() + if len(revert) > 0 { + jsonResult["revert"] = string(revert) + } + } else { + dst := make([]byte, hex.EncodedLen(len(result.Return()))) + hex.Encode(dst, result.Return()) + jsonResult["value"] = "0x" + string(dst) + } + coinbaseDiffTx := new(big.Int).Sub(state.GetBalance(coinbase), coinbaseBalanceBeforeTx) + jsonResult["coinbaseDiff"] = coinbaseDiffTx.String() + jsonResult["gasFees"] = gasFeesTx.String() + jsonResult["ethSentToCoinbase"] = new(big.Int).Sub(coinbaseDiffTx, gasFeesTx).String() + jsonResult["gasPrice"] = new(big.Int).Div(coinbaseDiffTx, big.NewInt(int64(receipt.GasUsed))).String() + jsonResult["gasUsed"] = receipt.GasUsed + results = append(results, jsonResult) + } + + ret := map[string]interface{}{} + ret["results"] = results + coinbaseDiff := new(big.Int).Sub(state.GetBalance(coinbase), coinbaseBalanceBefore) + ret["coinbaseDiff"] = coinbaseDiff.String() + ret["gasFees"] = gasFees.String() + ret["ethSentToCoinbase"] = new(big.Int).Sub(coinbaseDiff, gasFees).String() + ret["bundleGasPrice"] = new(big.Int).Div(coinbaseDiff, big.NewInt(int64(totalGasUsed))).String() + ret["totalGasUsed"] = totalGasUsed + ret["stateBlockNumber"] = parent.Number.Int64() + + ret["bundleHash"] = "0x" + common.Bytes2Hex(bundleHash.Sum(nil)) + return ret, nil +} + +// EstimateGasBundleArgs represents the arguments for a call +type EstimateGasBundleArgs struct { + Txs []TransactionArgs `json:"txs"` + BlockNumber rpc.BlockNumber `json:"blockNumber"` + StateBlockNumberOrHash rpc.BlockNumberOrHash `json:"stateBlockNumber"` + Coinbase *string `json:"coinbase"` + Timestamp *uint64 `json:"timestamp"` + Timeout *int64 `json:"timeout"` +} + +func (s *BundleAPI) EstimateGasBundle(ctx context.Context, args EstimateGasBundleArgs) (map[string]interface{}, error) { + if len(args.Txs) == 0 { + return nil, errors.New("bundle missing txs") + } + if args.BlockNumber == 0 { + return nil, errors.New("bundle missing blockNumber") + } + + timeoutMS := int64(5000) + if args.Timeout != nil { + timeoutMS = *args.Timeout + } + timeout := time.Millisecond * time.Duration(timeoutMS) + + // Setup context so it may be cancelled when the call + // has completed or, in case of unmetered gas, setup + // a context with a timeout + var cancel context.CancelFunc + if timeout > 0 { + ctx, cancel = context.WithTimeout(ctx, timeout) + } else { + ctx, cancel = context.WithCancel(ctx) + } + + // Make sure the context is cancelled when the call has completed + // This makes sure resources are cleaned up + defer cancel() + + state, parent, err := s.b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash) + if state == nil || err != nil { + return nil, err + } + blockNumber := big.NewInt(int64(args.BlockNumber)) + timestamp := parent.Time + 1 + if args.Timestamp != nil { + timestamp = *args.Timestamp + } + coinbase := parent.Coinbase + if args.Coinbase != nil { + coinbase = common.HexToAddress(*args.Coinbase) + } + + header := &types.Header{ + ParentHash: parent.Hash(), + Number: blockNumber, + GasLimit: parent.GasLimit, + Time: timestamp, + Difficulty: parent.Difficulty, + Coinbase: coinbase, + BaseFee: parent.BaseFee, + } + + // RPC Call gas cap + globalGasCap := s.b.RPCGasCap() + + // Results + results := []map[string]interface{}{} + + // Copy the original db so we don't modify it + statedb := state.Copy() + + // Gas pool + gp := new(core.GasPool).AddGas(math.MaxUint64) + + // Block context + blockContext := core.NewEVMBlockContext(header, s.chain, &coinbase) + + // Feed each of the transactions into the VM ctx + // And try and estimate the gas used + for _, txArgs := range args.Txs { + // Check if the context was cancelled (eg. timed-out) + if err := ctx.Err(); err != nil { + return nil, err + } + + // Since its a txCall we'll just prepare the + // state with a random hash + var randomHash common.Hash + rand.Read(randomHash[:]) + + // New random hash since its a call + + isPostMerge := header.Difficulty.Cmp(common.Big0) == 0 + + cfg := s.b.ChainConfig() + rules := s.b.ChainConfig().Rules(header.Number, isPostMerge, header.Time) + + msg, err := core.TransactionToMessage(txArgs.toTransaction(), types.MakeSigner(cfg, header.Number, header.Time), header.BaseFee) + state.Prepare(rules, msg.From, coinbase, msg.To, vm.ActivePrecompiles(rules), nil) + + // Convert tx args to msg to apply state transition + msg, err = txArgs.ToMessage(globalGasCap, header.BaseFee) + if err != nil { + return nil, err + } + + // Prepare the hashes + txContext := core.NewEVMTxContext(msg) + + // Get EVM Environment + vmenv := vm.NewEVM(blockContext, txContext, statedb, s.b.ChainConfig(), vm.Config{NoBaseFee: true}) + + // Apply state transition + result, err := core.ApplyMessage(vmenv, msg, gp) + if err != nil { + return nil, err + } + + // Modifications are committed to the state + // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect + statedb.Finalise(vmenv.ChainConfig().IsEIP158(blockNumber)) + + // Append result + jsonResult := map[string]interface{}{ + "gasUsed": result.UsedGas, + } + results = append(results, jsonResult) + } + + // Return results + ret := map[string]interface{}{} + ret["results"] = results + + return ret, nil +} diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 3e4ee505f389..3a1fd5e87eba 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -99,7 +99,7 @@ type Backend interface { ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) } -func GetAPIs(apiBackend Backend) []rpc.API { +func GetAPIs(apiBackend Backend, chain *core.BlockChain) []rpc.API { nonceLock := new(AddrLocker) return []rpc.API{ { @@ -123,6 +123,9 @@ func GetAPIs(apiBackend Backend) []rpc.API { }, { Namespace: "personal", Service: NewPersonalAccountAPI(apiBackend, nonceLock), + }, { + Namespace: "eth", + Service: NewBundleAPI(apiBackend, chain), }, } } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index a2fc3b5a9040..55c4aa271e51 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -611,6 +611,16 @@ web3._extend({ params: 4, inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputDefaultBlockNumberFormatter, null, null], }), + new web3._extend.Method({ + name: 'callBundle', + call: 'eth_callBundle', + params: 1, + }), + new web3._extend.Method({ + name: 'estimateGasBundle', + call: 'eth_estimateGasBundle', + params: 1, + }), ], properties: [ new web3._extend.Property({ diff --git a/les/client.go b/les/client.go index 9561ba777e0b..75277a0ca79a 100644 --- a/les/client.go +++ b/les/client.go @@ -289,7 +289,7 @@ func (s *LightDummyAPI) Mining() bool { // APIs returns the collection of RPC services the ethereum package offers. // NOTE, some of these services probably need to be moved to somewhere else. func (s *LightEthereum) APIs() []rpc.API { - apis := ethapi.GetAPIs(s.ApiBackend) + apis := ethapi.GetAPIs(s.ApiBackend, nil) apis = append(apis, s.engine.APIs(s.BlockChain().HeaderChain())...) return append(apis, []rpc.API{ { From f63bcf90e6849838c1332eb644229c582563aae5 Mon Sep 17 00:00:00 2001 From: shampoo bera Date: Wed, 17 May 2023 10:03:11 -0400 Subject: [PATCH 2/2] err checking --- eth/.api.go.swp | Bin 16384 -> 0 bytes eth/.backend.go.swp | Bin 16384 -> 0 bytes internal/ethapi/.api.go.swp | Bin 24576 -> 0 bytes internal/ethapi/api.go | 10 ++++++++++ 4 files changed, 10 insertions(+) delete mode 100644 eth/.api.go.swp delete mode 100644 eth/.backend.go.swp delete mode 100644 internal/ethapi/.api.go.swp diff --git a/eth/.api.go.swp b/eth/.api.go.swp deleted file mode 100644 index 92231ea4e24220e85789dea35982029c10f4e697..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 b980m^Wh6!6vucOWsGxeC5t!#7nRWjL_>MAp diff --git a/eth/.backend.go.swp b/eth/.backend.go.swp deleted file mode 100644 index 354fecf863fc89498958cbf6f8a5deb822804a02..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 Ns_;6qI$x@5`7i5|sSW@D diff --git a/internal/ethapi/.api.go.swp b/internal/ethapi/.api.go.swp deleted file mode 100644 index f21ba8394907d6bc36e01eff7fcc15db13e684cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 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