core, rpc: fix height-related issue of historic call functionality
Specifying a certain stateroot R as `invoke*historic` RPC-call parameter, we're willing to perform historic call based on the storage state of root R. Thus, next block should be of the height h(R)+1. This allows to use historic functionality for the current blockchain height.
This commit is contained in:
parent
5108d1c2c7
commit
7c48edaccb
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
|
block index or stateroot hash as the first parameter and the list of parameters
|
||||||
that is the same as of `invokecontractverify`, `invokefunction` and
|
that is the same as of `invokecontractverify`, `invokefunction` and
|
||||||
`invokescript` correspondingly. The historical call assumes that the contracts'
|
`invokescript` correspondingly. The historical call assumes that the contracts'
|
||||||
storage state has all its values got from MPT with the specified stateroot and
|
storage state has all its values got from MPT with the specified stateroot (or,
|
||||||
the transaction will be invoked using interop context with block of the specified
|
which is the same, with the stateroot of the block of the specified height) and
|
||||||
height. This allows to perform test invocation using the specified past chain
|
the transaction will be invoked using interop context with block which is next to
|
||||||
state. These methods may be useful for debugging purposes.
|
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
|
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
|
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
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to retrieve stateroot for height %d: %w", b.Index, err)
|
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)
|
height = int(b.Index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b, err := s.getFakeNextBlock(uint32(height))
|
b, err := s.getFakeNextBlock(uint32(height + 1))
|
||||||
if err != nil {
|
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
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue