Merge pull request #2556 from nspcc-dev/fix-historiccall

core, rpc: fix height-related issue of historic call functionality
This commit is contained in:
Roman Khimov 2022-06-24 09:33:45 +03:00 committed by GitHub
commit 2a24983727
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 7 deletions

View file

@ -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

View file

@ -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)
}

View file

@ -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
}