Merge pull request #2556 from nspcc-dev/fix-historiccall
core, rpc: fix height-related issue of historic call functionality
This commit is contained in:
commit
2a24983727
3 changed files with 13 additions and 7 deletions
10
docs/rpc.md
10
docs/rpc.md
|
@ -174,10 +174,12 @@ These methods provide the ability of *historical* calls and accept block hash or
|
|||
block index or stateroot hash as the first parameter and the list of parameters
|
||||
that is the same as of `invokecontractverify`, `invokefunction` and
|
||||
`invokescript` correspondingly. The historical call assumes that the contracts'
|
||||
storage state has all its values got from MPT with the specified stateroot and
|
||||
the transaction will be invoked using interop context with block of the specified
|
||||
height. This allows to perform test invocation using the specified past chain
|
||||
state. These methods may be useful for debugging purposes.
|
||||
storage state has all its values got from MPT with the specified stateroot (or,
|
||||
which is the same, with the stateroot of the block of the specified height) and
|
||||
the transaction will be invoked using interop context with block which is next to
|
||||
the block with the specified height. This allows to perform test invocation using
|
||||
the specified past chain state. These methods may be useful for debugging
|
||||
purposes.
|
||||
|
||||
Behavior note: any historical RPC call need the historical chain state to be
|
||||
presented in the node storage, thus if the node keeps only latest MPT state
|
||||
|
|
|
@ -2187,7 +2187,11 @@ func (bc *Blockchain) GetTestHistoricVM(t trigger.Type, tx *transaction.Transact
|
|||
}
|
||||
mode |= mpt.ModeGCFlag
|
||||
}
|
||||
sr, err := bc.stateRoot.GetStateRoot(b.Index)
|
||||
if b.Index < 1 || b.Index > bc.BlockHeight()+1 {
|
||||
return nil, fmt.Errorf("unsupported historic chain's height: requested state for %d, chain height %d", b.Index, bc.blockHeight)
|
||||
}
|
||||
// Assuming that block N-th is processing during historic call, the historic invocation should be based on the storage state of height N-1.
|
||||
sr, err := bc.stateRoot.GetStateRoot(b.Index - 1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve stateroot for height %d: %w", b.Index, err)
|
||||
}
|
||||
|
|
|
@ -1780,9 +1780,9 @@ func (s *Server) getHistoricParams(reqParams request.Params) (*block.Block, *res
|
|||
height = int(b.Index)
|
||||
}
|
||||
}
|
||||
b, err := s.getFakeNextBlock(uint32(height))
|
||||
b, err := s.getFakeNextBlock(uint32(height + 1))
|
||||
if err != nil {
|
||||
return nil, response.NewInternalServerError(fmt.Sprintf("can't create fake block for height %d: %s", height, err))
|
||||
return nil, response.NewInternalServerError(fmt.Sprintf("can't create fake block for height %d: %s", height+1, err))
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue