internal/ethapi: fix prev hashes in eth_simulate
This commit is contained in:
parent
fc12dbe40b
commit
71b86a994e
|
@ -770,7 +770,7 @@ func (api *BlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockN
|
||||||
//
|
//
|
||||||
// Note, this function doesn't make any changes in the state/blockchain and is
|
// Note, this function doesn't make any changes in the state/blockchain and is
|
||||||
// useful to execute and retrieve values.
|
// useful to execute and retrieve values.
|
||||||
func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
|
func (api *BlockChainAPI) SimulateV1(ctx context.Context, opts simOpts, blockNrOrHash *rpc.BlockNumberOrHash) ([]*simBlockResult, error) {
|
||||||
if len(opts.BlockStateCalls) == 0 {
|
if len(opts.BlockStateCalls) == 0 {
|
||||||
return nil, &invalidParamsError{message: "empty input"}
|
return nil, &invalidParamsError{message: "empty input"}
|
||||||
} else if len(opts.BlockStateCalls) > maxSimulateBlocks {
|
} else if len(opts.BlockStateCalls) > maxSimulateBlocks {
|
||||||
|
|
|
@ -73,6 +73,19 @@ func (r *simCallResult) MarshalJSON() ([]byte, error) {
|
||||||
return json.Marshal((*callResultAlias)(r))
|
return json.Marshal((*callResultAlias)(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// simBlockResult is the result of a simulated block.
|
||||||
|
type simBlockResult struct {
|
||||||
|
sim *simulator
|
||||||
|
Block *types.Block
|
||||||
|
Calls []simCallResult
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *simBlockResult) MarshalJSON() ([]byte, error) {
|
||||||
|
blockData := RPCMarshalBlock(r.Block, true, r.sim.fullTx, r.sim.chainConfig)
|
||||||
|
blockData["calls"] = r.Calls
|
||||||
|
return json.Marshal(blockData)
|
||||||
|
}
|
||||||
|
|
||||||
// simOpts are the inputs to eth_simulateV1.
|
// simOpts are the inputs to eth_simulateV1.
|
||||||
type simOpts struct {
|
type simOpts struct {
|
||||||
BlockStateCalls []simBlock
|
BlockStateCalls []simBlock
|
||||||
|
@ -95,7 +108,7 @@ type simulator struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute runs the simulation of a series of blocks.
|
// execute runs the simulation of a series of blocks.
|
||||||
func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[string]interface{}, error) {
|
func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]*simBlockResult, error) {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -123,19 +136,21 @@ func (sim *simulator) execute(ctx context.Context, blocks []simBlock) ([]map[str
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
results = make([]map[string]interface{}, len(blocks))
|
results = make([]*simBlockResult, len(blocks))
|
||||||
parent = sim.base
|
// prevHeaders is the header for all previously simulated blocks.
|
||||||
|
// It is "filled" compared to the barebone header available prior to execution.
|
||||||
|
// It will be used for serving the BLOCKHASH opcode.
|
||||||
|
prevHeaders = make([]*types.Header, 0, len(blocks))
|
||||||
|
parent = sim.base
|
||||||
)
|
)
|
||||||
for bi, block := range blocks {
|
for bi, block := range blocks {
|
||||||
result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, headers[:bi], timeout)
|
result, callResults, err := sim.processBlock(ctx, &block, headers[bi], parent, prevHeaders, timeout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
enc := RPCMarshalBlock(result, true, sim.fullTx, sim.chainConfig)
|
results[bi] = &simBlockResult{sim: sim, Block: result, Calls: callResults}
|
||||||
enc["calls"] = callResults
|
parent = result.Header()
|
||||||
results[bi] = enc
|
prevHeaders = append(prevHeaders, parent)
|
||||||
|
|
||||||
parent = headers[bi]
|
|
||||||
}
|
}
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,11 @@
|
||||||
package ethapi
|
package ethapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
"github.com/ethereum/go-ethereum/internal/ethapi/override"
|
||||||
|
@ -119,3 +121,18 @@ func TestSimulateSanitizeBlockOrder(t *testing.T) {
|
||||||
func newInt(n int64) *hexutil.Big {
|
func newInt(n int64) *hexutil.Big {
|
||||||
return (*hexutil.Big)(big.NewInt(n))
|
return (*hexutil.Big)(big.NewInt(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHeaderPassing(t *testing.T) {
|
||||||
|
sl := []*types.Header{new(types.Header)}
|
||||||
|
procHeader(sl[0])
|
||||||
|
fmt.Printf("sl[0].Number: %v\n", sl[0].Number)
|
||||||
|
fmt.Printf("sl[0].ParentHash: %v\n", sl[0].ParentHash)
|
||||||
|
if sl[0].Number.Cmp(big.NewInt(100)) != 0 {
|
||||||
|
t.Errorf("Header not processed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func procHeader(h *types.Header) {
|
||||||
|
h.Number = big.NewInt(100)
|
||||||
|
h.ParentHash = common.HexToHash("0x1")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue