mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'fix' into fasza
This commit is contained in:
commit
f6806b2b04
7 changed files with 519 additions and 4 deletions
|
|
@ -18,6 +18,8 @@ package core
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"encoding/json"
|
||||
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
|
|
@ -160,3 +162,55 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg)
|
||||
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
|
||||
}
|
||||
|
||||
func applyTransactionWithResult(msg *Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, msgTx *Message, usedGas *uint64, evm *vm.EVM, txHash common.Hash) (*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.GetRefund()
|
||||
|
||||
} 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: 0, PostState: root, CumulativeGasUsed: *usedGas}
|
||||
if result.Failed() {
|
||||
receipt.Status = types.ReceiptStatusFailed
|
||||
} else {
|
||||
receipt.Status = types.ReceiptStatusSuccessful
|
||||
}
|
||||
// receipt.TxHash = tx.Hash()
|
||||
receipt.GasUsed = result.UsedGas
|
||||
|
||||
// Set the receipt logs and create the bloom filter.
|
||||
receipt.BlockHash = header.Hash()
|
||||
receipt.BlockNumber = header.Number
|
||||
receipt.TransactionIndex = uint(statedb.TxIndex())
|
||||
receipt.Logs = statedb.GetLogs(txHash, header.Number.Uint64(), header.Hash())
|
||||
return receipt, result, err
|
||||
}
|
||||
|
||||
func ApplyTransactionWithResult(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, msg *Message, usedGas *uint64, cfg vm.Config, txHash common.Hash) (*types.Receipt, *ExecutionResult, error) {
|
||||
// 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)
|
||||
receipt, result, err := applyTransactionWithResult(msg, config, bc, author, gp, statedb, header, msg, usedGas, vmenv, txHash)
|
||||
return receipt, result, err
|
||||
}
|
||||
|
||||
type TracerResult interface {
|
||||
GetResult() (json.RawMessage, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -582,3 +582,20 @@ func deriveChainId(v *big.Int) *big.Int {
|
|||
v = new(big.Int).Sub(v, big.NewInt(35))
|
||||
return v.Div(v, big.NewInt(2))
|
||||
}
|
||||
|
||||
func MakeSigner2(config *params.ChainConfig, blockNumber *big.Int) Signer {
|
||||
var signer Signer
|
||||
switch {
|
||||
case config.IsLondon(blockNumber):
|
||||
signer = NewLondonSigner(config.ChainID)
|
||||
case config.IsBerlin(blockNumber):
|
||||
signer = NewEIP2930Signer(config.ChainID)
|
||||
case config.IsEIP155(blockNumber):
|
||||
signer = NewEIP155Signer(config.ChainID)
|
||||
case config.IsHomestead(blockNumber):
|
||||
signer = HomesteadSigner{}
|
||||
default:
|
||||
signer = FrontierSigner{}
|
||||
}
|
||||
return signer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,7 +299,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())...)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -49,6 +50,384 @@ import (
|
|||
"github.com/tyler-smith/go-bip39"
|
||||
)
|
||||
|
||||
type BundleAPI struct {
|
||||
b Backend
|
||||
chain *core.BlockChain
|
||||
}
|
||||
|
||||
func NewBundleAPI(b Backend, chain *core.BlockChain) *BundleAPI {
|
||||
return &BundleAPI{b, chain}
|
||||
}
|
||||
|
||||
func (s *BlockChainAPI) CallNew(ctx context.Context, args TransactionArgsBundle, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (map[string]interface{}, error) {
|
||||
result, err := DoCallBundle(ctx, s.b, args, blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs, overrides *StateOverride) (map[string]interface{}, error) {
|
||||
if len(args.Transactions) == 0 {
|
||||
return nil, errors.New("bundle missing txs")
|
||||
}
|
||||
|
||||
if len(args.BlockNumbers) != len(args.Transactions) {
|
||||
return nil, errors.New("bundle txs and block numbers mismatch")
|
||||
}
|
||||
|
||||
if len(args.Timestamps) != len(args.Transactions) {
|
||||
return nil, errors.New("bundle txs and timestamps mismatch")
|
||||
}
|
||||
|
||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||
|
||||
timeoutMilliSeconds := int64(5000)
|
||||
if args.Timeout != nil {
|
||||
timeoutMilliSeconds = *args.Timeout
|
||||
}
|
||||
timeout := time.Millisecond * time.Duration(timeoutMilliSeconds)
|
||||
state, parent, err := s.b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := overrides.Apply(state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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.BlockNumbers[0].Int64())) {
|
||||
baseFee = misc.CalcBaseFee(s.b.ChainConfig(), parent)
|
||||
}
|
||||
|
||||
// Setup context so it may be cancelled 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()
|
||||
|
||||
vmconfig := vm.Config{}
|
||||
vmconfig.NoBaseFee = true
|
||||
// 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)
|
||||
|
||||
var totalGasUsed uint64
|
||||
gasFees := new(big.Int)
|
||||
for i, tx := range args.Transactions {
|
||||
header := &types.Header{
|
||||
ParentHash: parent.Hash(),
|
||||
Number: big.NewInt(int64(args.BlockNumbers[i])),
|
||||
GasLimit: gasLimit,
|
||||
Time: *args.Timestamps[i],
|
||||
Difficulty: difficulty,
|
||||
Coinbase: coinbase,
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
msg, err := tx.ToMessage(0, header.BaseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
coinbaseBalanceBeforeTx := state.GetBalance(coinbase)
|
||||
randomHash := common.HexToHash("0x" + strconv.Itoa(i))
|
||||
state.SetTxContext(randomHash, i)
|
||||
|
||||
receipt, result, err := core.ApplyTransactionWithResult(s.b.ChainConfig(), s.chain, &coinbase, gp, state, header, msg, &header.GasUsed, vmconfig, randomHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err: %w; txhash %s", err, randomHash)
|
||||
}
|
||||
|
||||
txHash := randomHash.String()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err: %w; txhash %s", err, randomHash)
|
||||
}
|
||||
logs := receipt.Logs
|
||||
if logs == nil {
|
||||
logs = []*types.Log{}
|
||||
}
|
||||
jsonResult := map[string]interface{}{
|
||||
"txHash": txHash,
|
||||
"gasUsed": receipt.GasUsed,
|
||||
"logs": logs,
|
||||
"status": receipt.Status,
|
||||
}
|
||||
totalGasUsed += receipt.GasUsed
|
||||
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["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()
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func doCallBundle(ctx context.Context, b Backend, chain *core.BlockChain, args CallBundleArgs, overrides *StateOverride) (map[string]interface{}, error) {
|
||||
if len(args.Transactions) == 0 {
|
||||
return nil, errors.New("bundle missing txs")
|
||||
}
|
||||
|
||||
if len(args.BlockNumbers) != len(args.Transactions) {
|
||||
return nil, errors.New("bundle txs and block numbers mismatch")
|
||||
}
|
||||
|
||||
if len(args.Timestamps) != len(args.Transactions) {
|
||||
return nil, errors.New("bundle txs and timestamps mismatch, len1" + strconv.Itoa(len(args.Timestamps)) + " len2 " + strconv.Itoa(len(args.Transactions)))
|
||||
}
|
||||
|
||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||
|
||||
timeoutMilliSeconds := int64(5000)
|
||||
if args.Timeout != nil {
|
||||
timeoutMilliSeconds = *args.Timeout
|
||||
}
|
||||
timeout := time.Millisecond * time.Duration(timeoutMilliSeconds)
|
||||
state, parent, err := b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash)
|
||||
if state == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := overrides.Apply(state); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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 b.ChainConfig().IsLondon(big.NewInt(args.BlockNumbers[0].Int64())) {
|
||||
baseFee = misc.CalcBaseFee(b.ChainConfig(), parent)
|
||||
}
|
||||
|
||||
// Setup context so it may be cancelled 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()
|
||||
|
||||
vmconfig := vm.Config{}
|
||||
vmconfig.NoBaseFee = true
|
||||
// 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)
|
||||
|
||||
var totalGasUsed uint64
|
||||
gasFees := new(big.Int)
|
||||
lastReverted := false
|
||||
for i, tx := range args.Transactions {
|
||||
header := &types.Header{
|
||||
ParentHash: parent.Hash(),
|
||||
Number: big.NewInt(int64(args.BlockNumbers[i])),
|
||||
GasLimit: gasLimit,
|
||||
Time: *args.Timestamps[i],
|
||||
Difficulty: difficulty,
|
||||
Coinbase: coinbase,
|
||||
BaseFee: baseFee,
|
||||
}
|
||||
msg, err := tx.ToMessage(0, header.BaseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
coinbaseBalanceBeforeTx := state.GetBalance(coinbase)
|
||||
randomHash := common.HexToHash("0x" + strconv.Itoa(i))
|
||||
state.SetTxContext(randomHash, i)
|
||||
|
||||
receipt, result, err := core.ApplyTransactionWithResult(b.ChainConfig(), chain, &coinbase, gp, state, header, msg, &header.GasUsed, vmconfig, randomHash)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err: %w; txhash %s", err, randomHash)
|
||||
}
|
||||
|
||||
txHash := randomHash.String()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("err: %w; txhash %s", err, randomHash)
|
||||
}
|
||||
logs := receipt.Logs
|
||||
if logs == nil {
|
||||
logs = []*types.Log{}
|
||||
}
|
||||
jsonResult := map[string]interface{}{
|
||||
"txHash": txHash,
|
||||
"gasUsed": receipt.GasUsed,
|
||||
"logs": logs,
|
||||
"status": receipt.Status,
|
||||
"input": tx.Input,
|
||||
}
|
||||
totalGasUsed += receipt.GasUsed
|
||||
if result.Err != nil {
|
||||
jsonResult["error"] = result.Err.Error()
|
||||
revert := result.Revert()
|
||||
if len(revert) > 0 {
|
||||
jsonResult["revert"] = string(revert)
|
||||
}
|
||||
// if we are last transaction
|
||||
if i == len(args.Transactions)-1 {
|
||||
lastReverted = true
|
||||
}
|
||||
} 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["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["lastReverted"] = lastReverted
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (s *BundleAPI) CallBundleArray(ctx context.Context, args []CallBundleArgs, overrides *StateOverride) ([]map[string]interface{}, error) {
|
||||
ret := []map[string]interface{}{}
|
||||
for _, arg := range args {
|
||||
result, err := doCallBundle(ctx, s.b, s.chain, arg, overrides)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, result)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (s *BundleAPI) SearchMaxWallet(ctx context.Context, args MaxWalletSearchArgs, overrides *StateOverride) (map[string]interface{}, error) {
|
||||
timeoutMilliSeconds := int64(5000)
|
||||
timeout := time.Millisecond * time.Duration(timeoutMilliSeconds)
|
||||
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()
|
||||
currentPercentage := 50000 // 100000 = 100%
|
||||
lower := 0
|
||||
upper := 100000
|
||||
resultPercentage := 0
|
||||
lastResult := map[string]interface{}{}
|
||||
lastPercentage := 0
|
||||
for {
|
||||
if (lastPercentage == currentPercentage) || (currentPercentage <= 1) {
|
||||
resultPercentage = currentPercentage
|
||||
break
|
||||
}
|
||||
// convert percentage to hex and pad with 0s until 64 chars
|
||||
percentageHex := fmt.Sprintf("%064s", strconv.FormatInt(int64(currentPercentage), 16))
|
||||
originalFirst10Chars := args.MaxWalletTransaction.Data.String()[0:10]
|
||||
m := hexutil.Bytes{}
|
||||
m.UnmarshalText([]byte(originalFirst10Chars + percentageHex))
|
||||
|
||||
args.MaxWalletTransaction.setInput(m)
|
||||
callBundleArgs := CallBundleArgs{
|
||||
Transactions: append(args.Transactions, args.MaxWalletTransaction),
|
||||
BlockNumbers: append(args.BlockNumbers, args.MaxWalletBlockNumber),
|
||||
Timestamps: append(args.Timestamps, args.MaxWalletTimestamp),
|
||||
StateBlockNumberOrHash: args.StateBlockNumberOrHash,
|
||||
}
|
||||
result, err := doCallBundle(ctx, s.b, s.chain, callBundleArgs, overrides)
|
||||
lastResult = result
|
||||
if err != nil {
|
||||
return lastResult, err
|
||||
}
|
||||
// if results last tx reverted, we found the max wallet
|
||||
if result["lastReverted"] == true && currentPercentage <= 1 {
|
||||
resultPercentage = 0
|
||||
break
|
||||
}
|
||||
if currentPercentage >= 90000 {
|
||||
resultPercentage = 90000
|
||||
break
|
||||
}
|
||||
if result["lastReverted"] == true {
|
||||
upper = currentPercentage
|
||||
} else {
|
||||
lower = currentPercentage
|
||||
}
|
||||
lastPercentage = currentPercentage
|
||||
currentPercentage = int((upper + lower) / 2)
|
||||
}
|
||||
lastResult["percentage"] = resultPercentage
|
||||
return lastResult, nil
|
||||
}
|
||||
|
||||
// EthereumAPI provides an API to access Ethereum related information.
|
||||
type EthereumAPI struct {
|
||||
b Backend
|
||||
|
|
@ -2171,4 +2550,4 @@ func toHexSlice(b [][]byte) []string {
|
|||
r[i] = hexutil.Encode(b[i])
|
||||
}
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
|
@ -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,11 @@ func GetAPIs(apiBackend Backend) []rpc.API {
|
|||
}, {
|
||||
Namespace: "personal",
|
||||
Service: NewPersonalAccountAPI(apiBackend, nonceLock),
|
||||
}, {
|
||||
Namespace: "eth",
|
||||
Version: "1.0",
|
||||
Service: NewBundleAPI(apiBackend, chain),
|
||||
Public: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,62 @@ type TransactionArgs struct {
|
|||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
}
|
||||
|
||||
type TransactionArgsBundle struct {
|
||||
Transactions1 []TransactionArgs `json:"transactions1"`
|
||||
Transactions2 []TransactionArgs `json:"transactions2"`
|
||||
BlockNumbers1 []rpc.BlockNumber `json:"blockNumbers1"`
|
||||
BlockNumbers2 []rpc.BlockNumber `json:"blockNumbers2"`
|
||||
}
|
||||
|
||||
type MaxWalletSearchArgs struct {
|
||||
Transactions []TransactionArgs `json:"transactions"`
|
||||
MaxWalletTransaction TransactionArgs `json:"maxWalletTransaction"`
|
||||
BlockNumbers []rpc.BlockNumber `json:"blockNumbers"`
|
||||
MaxWalletBlockNumber rpc.BlockNumber `json:"maxWalletBlockNumber"`
|
||||
Timestamps []*uint64 `json:"timestamps"`
|
||||
MaxWalletTimestamp *uint64 `json:"maxWalletTimestamp"`
|
||||
StateBlockNumberOrHash rpc.BlockNumberOrHash `json:"stateBlockNumber"`
|
||||
}
|
||||
|
||||
type CallBundleArgs struct {
|
||||
Transactions []TransactionArgs `json:"transactions"`
|
||||
BlockNumbers []rpc.BlockNumber `json:"blockNumbers"`
|
||||
Timestamps []*uint64 `json:"timestamps"`
|
||||
StateBlockNumberOrHash rpc.BlockNumberOrHash `json:"stateBlockNumber"`
|
||||
Coinbase *string `json:"coinbase"`
|
||||
Timeout *int64 `json:"timeout"`
|
||||
GasLimit *uint64 `json:"gasLimit"`
|
||||
Difficulty *big.Int `json:"difficulty"`
|
||||
BaseFee *big.Int `json:"baseFee"`
|
||||
}
|
||||
|
||||
type TransactionArgs2 struct {
|
||||
From *common.Address `json:"from"`
|
||||
To *common.Address `json:"to"`
|
||||
Gas *hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice"`
|
||||
MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"`
|
||||
MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"`
|
||||
Value *hexutil.Big `json:"value"`
|
||||
Nonce *hexutil.Uint64 `json:"nonce"`
|
||||
Data *hexutil.Bytes `json:"data"`
|
||||
Input *hexutil.Bytes `json:"input"`
|
||||
AccessList *types.AccessList `json:"accessList,omitempty"`
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
From1 *common.Address `json:"from1"`
|
||||
To1 *common.Address `json:"to1"`
|
||||
Gas1 *hexutil.Uint64 `json:"gas1"`
|
||||
GasPrice1 *hexutil.Big `json:"gasPrice1"`
|
||||
MaxFeePerGas1 *hexutil.Big `json:"maxFeePerGas1"`
|
||||
MaxPriorityFeePerGas1 *hexutil.Big `json:"maxPriorityFeePerGas1"`
|
||||
Value1 *hexutil.Big `json:"value1"`
|
||||
Nonce1 *hexutil.Uint64 `json:"nonce1"`
|
||||
Data1 *hexutil.Bytes `json:"data1"`
|
||||
Input1 *hexutil.Bytes `json:"input1"`
|
||||
AccessList1 *types.AccessList `json:"accessList1,omitempty"`
|
||||
ChainID1 *hexutil.Big `json:"chainId1,omitempty"`
|
||||
}
|
||||
|
||||
// from retrieves the transaction sender address.
|
||||
func (args *TransactionArgs) from() common.Address {
|
||||
if args.From == nil {
|
||||
|
|
@ -74,6 +130,10 @@ func (args *TransactionArgs) data() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (args *TransactionArgs) setInput(data []byte) {
|
||||
args.Input = (*hexutil.Bytes)(&data)
|
||||
}
|
||||
|
||||
// setDefaults fills in default values for unspecified tx fields.
|
||||
func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error {
|
||||
if err := args.setFeeDefaults(ctx, b); err != nil {
|
||||
|
|
|
|||
|
|
@ -288,7 +288,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{
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue