This commit is contained in:
vahoo5 2023-05-24 16:32:58 +02:00
parent 85a7b34b79
commit 0508948569
2 changed files with 118 additions and 81 deletions

View file

@ -1055,68 +1055,104 @@ func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash
return result, nil return result, nil
} }
// func DoCallBundle(ctx context.Context, b Backend, args TransactionArgsBundle, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) ([]map[string]interface{}, error) { func DoCallBundle(ctx context.Context, b Backend, args TransactionArgsBundle, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (map[string]interface{}, error) {
// defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
// state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
// if state == nil || err != nil { if state == nil || err != nil {
// return nil, err return nil, err
// } }
// if err := overrides.Apply(state); err != nil { if err := overrides.Apply(state); err != nil {
// return nil, err return nil, err
// } }
// // Setup context so it may be cancelled the call has completed // Setup context so it may be cancelled the call has completed
// // or, in case of unmetered gas, setup a context with a timeout. // or, in case of unmetered gas, setup a context with a timeout.
// var cancel context.CancelFunc var cancel context.CancelFunc
// if timeout > 0 { if timeout > 0 {
// ctx, cancel = context.WithTimeout(ctx, timeout) ctx, cancel = context.WithTimeout(ctx, timeout)
// } else { } else {
// ctx, cancel = context.WithCancel(ctx) ctx, cancel = context.WithCancel(ctx)
// } }
// // Make sure the context is cancelled when the call has completed // Make sure the context is cancelled when the call has completed
// // this makes sure resources are cleaned up. // this makes sure resources are cleaned up.
// defer cancel() defer cancel()
// // Get a new instance of the EVM. transactions1 := args.Transactions1
// results := []map[string]interface{}{} transactions2 := args.Transactions2
// // tx will be the first of the bundle // Get a new instance of the EVM.
// blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) msg, err := transactions1[0].ToMessage(globalGasCap, header.BaseFee)
// if blockOverrides != nil { if err != nil {
// blockOverrides.Apply(&blockCtx) return nil, err
// } }
blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil)
if blockOverrides != nil {
blockOverrides.Apply(&blockCtx)
}
// gp := new(core.GasPool).AddGas(math.MaxUint64) results1 := []map[string]interface{}{}
// for i, tx := range args.Transactions { results2 := []map[string]interface{}{}
// msg, err := tx.ToMessage(globalGasCap, header.BaseFee) // Execute the message.
// if err != nil { gp := new(core.GasPool).AddGas(math.MaxUint64)
// return nil, err ret := map[string]interface{}{}
// } for i, tx2 := range transactions2 {
evm, vmError := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx)
for j, tx := range transactions1 {
// result, err := core.ApplyTransaction(s.b.ChainConfig(), ) msg, err = tx.ToMessage(globalGasCap, header.BaseFee)
// // print result if err != nil {
// fmt.Println(result) return nil, err
// jsonResult := map[string]interface{}{ }
// "gasUsed": result.UsedGas, blockNumber := args.BlockNumbers1[j]
// } blockCtx.BlockNumber = big.NewInt(int64(blockNumber))
// fmt.Println(i) result, _ := core.ApplyMessage(evm, msg, gp)
// if result.Err != nil { if err := vmError(); err != nil {
// fmt.Println("error 1") return nil, err
// jsonResult["error"] = result.Err.Error() }
// revert := result.Revert() jsonResult := map[string]interface{}{}
// if len(revert) > 0 { if result.Err != nil {
// jsonResult["revert"] = string(revert) jsonResult["error"] = result.Err.Error()
// } revert := result.Revert()
// } else { if len(revert) > 0 {
// fmt.Println("error 2") jsonResult["revert"] = string(revert)
// dst := make([]byte, hex.EncodedLen(len(result.Return()))) }
// hex.Encode(dst, result.Return()) } else {
// jsonResult["value"] = "0x" + string(dst) dst := make([]byte, hex.EncodedLen(len(result.Return())))
// } hex.Encode(dst, result.Return())
// results = append(results, jsonResult) jsonResult["value"] = "0x" + string(dst)
// } }
// return results, nil results1 = append(results1, jsonResult)
// } }
msg, err = tx2.ToMessage(globalGasCap, header.BaseFee)
if err != nil {
return nil, err
}
blockNumber := args.BlockNumbers2[i]
blockCtx.BlockNumber = big.NewInt(int64(blockNumber))
result, _ := core.ApplyMessage(evm, msg, gp)
if err := vmError(); err != nil {
return nil, err
}
jsonResult := map[string]interface{}{}
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)
}
results2 = append(results2, jsonResult)
}
ret["results1"] = results1
ret["results2"] = results2
return ret, nil
}
func DoCall2(ctx context.Context, b Backend, args TransactionArgs2, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { func DoCall2(ctx context.Context, b Backend, args TransactionArgs2, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
@ -1255,6 +1291,15 @@ func (s *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrO
return result.Return(), result.Err return result.Return(), result.Err
} }
func (s *BlockChainAPI) Call2(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 *BlockChainAPI) BatchCall(ctx context.Context, args TransactionArgs2, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) { func (s *BlockChainAPI) BatchCall(ctx context.Context, args TransactionArgs2, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) (hexutil.Bytes, error) {
result, err := DoCall2(ctx, s.b, args, blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) result, err := DoCall2(ctx, s.b, args, blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap())
if err != nil { if err != nil {
@ -1267,19 +1312,10 @@ func (s *BlockChainAPI) BatchCall(ctx context.Context, args TransactionArgs2, bl
return result.Return(), result.Err return result.Return(), result.Err
} }
// func (s *BundleAPI) BundleCall(ctx context.Context, args TransactionArgsBundle, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, blockOverrides *BlockOverrides) ([]map[string]interface{}, error) {
// result, _ := DoCallBundle(ctx, s.b, args, blockNrOrHash, overrides, blockOverrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap())
// return result, nil
// }
func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs) (map[string]interface{}, error) { func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs) (map[string]interface{}, error) {
if len(args.Transactions) == 0 { if len(args.Transactions) == 0 {
return nil, errors.New("bundle missing txs") return nil, errors.New("bundle missing txs")
} }
if args.BlockNumber == 0 {
return nil, errors.New("bundle missing blockNumber")
}
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
@ -1288,13 +1324,11 @@ func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs) (map[st
timeoutMilliSeconds = *args.Timeout timeoutMilliSeconds = *args.Timeout
} }
timeout := time.Millisecond * time.Duration(timeoutMilliSeconds) timeout := time.Millisecond * time.Duration(timeoutMilliSeconds)
fmt.Println("state", args.StateBlockNumberOrHash)
state, parent, err := s.b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash) state, parent, err := s.b.StateAndHeaderByNumberOrHash(ctx, args.StateBlockNumberOrHash)
if state == nil || err != nil { if state == nil || err != nil {
return nil, err return nil, err
} }
blockNumber := big.NewInt(int64(args.BlockNumber))
fmt.Println("blockNumber", blockNumber)
timestamp := parent.Time + 1 timestamp := parent.Time + 1
if args.Timestamp != nil { if args.Timestamp != nil {
timestamp = *args.Timestamp timestamp = *args.Timestamp
@ -1314,18 +1348,9 @@ func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs) (map[st
var baseFee *big.Int var baseFee *big.Int
if args.BaseFee != nil { if args.BaseFee != nil {
baseFee = args.BaseFee baseFee = args.BaseFee
} else if s.b.ChainConfig().IsLondon(big.NewInt(args.BlockNumber.Int64())) { } else if s.b.ChainConfig().IsLondon(big.NewInt(args.BlockNumbers[0].Int64())) {
baseFee = misc.CalcBaseFee(s.b.ChainConfig(), parent) 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,
}
// Setup context so it may be cancelled the call has completed // Setup context so it may be cancelled the call has completed
// or, in case of unmetered gas, setup a context with a timeout. // or, in case of unmetered gas, setup a context with a timeout.
@ -1351,6 +1376,15 @@ func (s *BundleAPI) CallBundle(ctx context.Context, args CallBundleArgs) (map[st
var totalGasUsed uint64 var totalGasUsed uint64
gasFees := new(big.Int) gasFees := new(big.Int)
for i, tx := range args.Transactions { for i, tx := range args.Transactions {
header := &types.Header{
ParentHash: parent.Hash(),
Number: big.NewInt(int64(args.BlockNumbers[i])),
GasLimit: gasLimit,
Time: timestamp,
Difficulty: difficulty,
Coinbase: coinbase,
BaseFee: baseFee,
}
msg, err := tx.ToMessage(0, header.BaseFee) msg, err := tx.ToMessage(0, header.BaseFee)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -56,12 +56,15 @@ type TransactionArgs struct {
} }
type TransactionArgsBundle struct { type TransactionArgsBundle struct {
Transactions []TransactionArgs `json:"transactions"` Transactions1 []TransactionArgs `json:"transactions1"`
Transactions2 []TransactionArgs `json:"transactions2"`
BlockNumbers1 []rpc.BlockNumber `json:"blockNumbers"`
BlockNumbers2 []rpc.BlockNumber `json:"blockNumbers2"`
} }
type CallBundleArgs struct { type CallBundleArgs struct {
Transactions []TransactionArgs `json:"transactions"` Transactions []TransactionArgs `json:"transactions"`
BlockNumber rpc.BlockNumber `json:"blockNumber"` BlockNumbers []rpc.BlockNumber `json:"blockNumbers"`
StateBlockNumberOrHash rpc.BlockNumberOrHash `json:"stateBlockNumber"` StateBlockNumberOrHash rpc.BlockNumberOrHash `json:"stateBlockNumber"`
Coinbase *string `json:"coinbase"` Coinbase *string `json:"coinbase"`
Timestamp *uint64 `json:"timestamp"` Timestamp *uint64 `json:"timestamp"`