core: make GetHeaderHash accept uint32

It should've always been this way because block indexes are uint32.
This commit is contained in:
Roman Khimov 2022-11-18 23:19:50 +03:00
parent 16db4746cc
commit 0ad6e295ea
23 changed files with 74 additions and 81 deletions

View file

@ -63,7 +63,7 @@ func TestQueryTx(t *testing.T) {
_, height, err := e.Chain.GetTransaction(txHash) _, height, err := e.Chain.GetTransaction(txHash)
require.NoError(t, err) require.NoError(t, err)
e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(height).StringLE())
e.CheckNextLine(t, `Success:\s+true`) e.CheckNextLine(t, `Success:\s+true`)
e.CheckEOF(t) e.CheckEOF(t)
@ -117,7 +117,7 @@ func compareQueryTxVerbose(t *testing.T, e *testcli.Executor, tx *transaction.Tr
e.CheckNextLine(t, `OnChain:\s+true`) e.CheckNextLine(t, `OnChain:\s+true`)
_, height, err := e.Chain.GetTransaction(tx.Hash()) _, height, err := e.Chain.GetTransaction(tx.Hash())
require.NoError(t, err) require.NoError(t, err)
e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(int(height)).StringLE()) e.CheckNextLine(t, `BlockHash:\s+`+e.Chain.GetHeaderHash(height).StringLE())
res, _ := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application) res, _ := e.Chain.GetAppExecResults(tx.Hash(), trigger.Application)
e.CheckNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt)) e.CheckNextLine(t, fmt.Sprintf(`Success:\s+%t`, res[0].Execution.VMState == vmstate.Halt))

View file

@ -2,7 +2,6 @@ package fakechain
import ( import (
"errors" "errors"
"math"
"math/big" "math/big"
"sync/atomic" "sync/atomic"
@ -236,11 +235,8 @@ func (chain *FakeChain) GetNativeContractScriptHash(name string) (util.Uint160,
} }
// GetHeaderHash implements the Blockchainer interface. // GetHeaderHash implements the Blockchainer interface.
func (chain *FakeChain) GetHeaderHash(n int) util.Uint256 { func (chain *FakeChain) GetHeaderHash(n uint32) util.Uint256 {
if n < 0 || n > math.MaxUint32 { return chain.hdrHashes[n]
return util.Uint256{}
}
return chain.hdrHashes[uint32(n)]
} }
// GetHeader implements the Blockchainer interface. // GetHeader implements the Blockchainer interface.

View file

@ -158,7 +158,7 @@ func SignCommittee(h hash.Hashable) []byte {
func NewBlock(t *testing.T, bc Ledger, offset uint32, primary uint32, txs ...*transaction.Transaction) *block.Block { func NewBlock(t *testing.T, bc Ledger, offset uint32, primary uint32, txs ...*transaction.Transaction) *block.Block {
witness := transaction.Witness{VerificationScript: MultisigVerificationScript()} witness := transaction.Witness{VerificationScript: MultisigVerificationScript()}
height := bc.BlockHeight() height := bc.BlockHeight()
h := bc.GetHeaderHash(int(height)) h := bc.GetHeaderHash(height)
hdr, err := bc.GetHeader(h) hdr, err := bc.GetHeader(h)
require.NoError(t, err) require.NoError(t, err)
b := &block.Block{ b := &block.Block{

View file

@ -27,7 +27,7 @@ type Ledger interface {
FeePerByte() int64 FeePerByte() int64
GetBaseExecFee() int64 GetBaseExecFee() int64
GetHeader(hash util.Uint256) (*block.Header, error) GetHeader(hash util.Uint256) (*block.Header, error)
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
HeaderHeight() uint32 HeaderHeight() uint32
ManagementContractHash() util.Uint160 ManagementContractHash() util.Uint160
} }

View file

@ -119,7 +119,7 @@ func TestService_NextConsensus(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
checkNextConsensus := func(t *testing.T, bc *core.Blockchain, height uint32, h util.Uint160) { checkNextConsensus := func(t *testing.T, bc *core.Blockchain, height uint32, h util.Uint160) {
hdrHash := bc.GetHeaderHash(int(height)) hdrHash := bc.GetHeaderHash(height)
hdr, err := bc.GetHeader(hdrHash) hdr, err := bc.GetHeader(hdrHash)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, h, hdr.NextConsensus) require.Equal(t, h, hdr.NextConsensus)

View file

@ -109,10 +109,10 @@ func benchmarkForEachNEP17Transfer(t *testing.B, ps storage.Store, startFromBloc
e.CheckHalt(t, tx.Hash()) e.CheckHalt(t, tx.Hash())
} }
newestB, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()) - startFromBlock + 1)) newestB, err := bc.GetBlock(bc.GetHeaderHash(bc.BlockHeight() - uint32(startFromBlock) + 1))
require.NoError(t, err) require.NoError(t, err)
newestTimestamp := newestB.Timestamp newestTimestamp := newestB.Timestamp
oldestB, err := bc.GetBlock(bc.GetHeaderHash(int(newestB.Index) - nBlocksToTake)) oldestB, err := bc.GetBlock(bc.GetHeaderHash(newestB.Index - uint32(nBlocksToTake)))
require.NoError(t, err) require.NoError(t, err)
oldestTimestamp := oldestB.Timestamp oldestTimestamp := oldestB.Timestamp

View file

@ -721,7 +721,7 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
blocksCnt, batchCnt, keysCnt int blocksCnt, batchCnt, keysCnt int
) )
for i := height + 1; i <= currHeight; i++ { for i := height + 1; i <= currHeight; i++ {
err := cache.DeleteBlock(bc.GetHeaderHash(int(i))) err := cache.DeleteBlock(bc.GetHeaderHash(i))
if err != nil { if err != nil {
return fmt.Errorf("error while removing block %d: %w", i, err) return fmt.Errorf("error while removing block %d: %w", i, err)
} }
@ -849,7 +849,7 @@ func (bc *Blockchain) resetStateInternal(height uint32, stage stateChangeStage)
// Reset SYS-prefixed and IX-prefixed information. // Reset SYS-prefixed and IX-prefixed information.
bc.log.Info("trying to reset headers information") bc.log.Info("trying to reset headers information")
for i := height + 1; i <= hHeight; i++ { for i := height + 1; i <= hHeight; i++ {
cache.PurgeHeader(bc.GetHeaderHash(int(i))) cache.PurgeHeader(bc.GetHeaderHash(i))
} }
cache.DeleteHeaderHashes(height+1, headerBatchCount) cache.DeleteHeaderHashes(height+1, headerBatchCount)
cache.StoreAsCurrentBlock(b) cache.StoreAsCurrentBlock(b)
@ -1174,7 +1174,7 @@ func appendTokenTransferInfo(transferData *state.TokenTransferInfo,
func (bc *Blockchain) removeOldTransfers(index uint32) time.Duration { func (bc *Blockchain) removeOldTransfers(index uint32) time.Duration {
bc.log.Info("starting transfer data garbage collection", zap.Uint32("index", index)) bc.log.Info("starting transfer data garbage collection", zap.Uint32("index", index))
start := time.Now() start := time.Now()
h, err := bc.GetHeader(bc.GetHeaderHash(int(index))) h, err := bc.GetHeader(bc.GetHeaderHash(index))
if err != nil { if err != nil {
dur := time.Since(start) dur := time.Since(start)
bc.log.Error("failed to find block header for transfer GC", zap.Duration("time", dur), zap.Error(err)) bc.log.Error("failed to find block header for transfer GC", zap.Duration("time", dur), zap.Error(err))
@ -1464,7 +1464,7 @@ func (bc *Blockchain) addHeaders(verify bool, headers ...*block.Header) error {
} }
batch.PutCurrentHeader(lastHeader.Hash(), lastHeader.Index) batch.PutCurrentHeader(lastHeader.Hash(), lastHeader.Index)
updateHeaderHeightMetric(len(bc.headerHashes) - 1) updateHeaderHeightMetric(uint32(len(bc.headerHashes) - 1))
if _, err = batch.Persist(); err != nil { if _, err = batch.Persist(); err != nil {
return err return err
} }
@ -1650,7 +1650,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
return fmt.Errorf("error while trying to apply MPT changes: %w", err) return fmt.Errorf("error while trying to apply MPT changes: %w", err)
} }
if bc.config.StateRootInHeader && bc.HeaderHeight() > sr.Index { if bc.config.StateRootInHeader && bc.HeaderHeight() > sr.Index {
h, err := bc.GetHeader(bc.GetHeaderHash(int(sr.Index) + 1)) h, err := bc.GetHeader(bc.GetHeaderHash(sr.Index + 1))
if err != nil { if err != nil {
err = fmt.Errorf("failed to get next header: %w", err) err = fmt.Errorf("failed to get next header: %w", err)
} else if h.PrevStateRoot != sr.Root { } else if h.PrevStateRoot != sr.Root {
@ -2174,7 +2174,7 @@ func (bc *Blockchain) CurrentBlockHash() util.Uint256 {
tb := topBlock.(*block.Block) tb := topBlock.(*block.Block)
return tb.Hash() return tb.Hash()
} }
return bc.GetHeaderHash(int(bc.BlockHeight())) return bc.GetHeaderHash(bc.BlockHeight())
} }
// CurrentHeaderHash returns the hash of the latest known header. // CurrentHeaderHash returns the hash of the latest known header.
@ -2187,11 +2187,11 @@ func (bc *Blockchain) CurrentHeaderHash() util.Uint256 {
// GetHeaderHash returns hash of the header/block with specified index, if // GetHeaderHash returns hash of the header/block with specified index, if
// Blockchain doesn't have a hash for this height, zero Uint256 value is returned. // Blockchain doesn't have a hash for this height, zero Uint256 value is returned.
func (bc *Blockchain) GetHeaderHash(i int) util.Uint256 { func (bc *Blockchain) GetHeaderHash(i uint32) util.Uint256 {
bc.headerHashesLock.RLock() bc.headerHashesLock.RLock()
defer bc.headerHashesLock.RUnlock() defer bc.headerHashesLock.RUnlock()
hashesLen := len(bc.headerHashes) hashesLen := uint32(len(bc.headerHashes))
if hashesLen <= i { if hashesLen <= i {
return util.Uint256{} return util.Uint256{}
} }
@ -2744,7 +2744,7 @@ func (bc *Blockchain) GetTestHistoricVM(t trigger.Type, tx *transaction.Transact
func (bc *Blockchain) getFakeNextBlock(nextBlockHeight uint32) (*block.Block, error) { func (bc *Blockchain) getFakeNextBlock(nextBlockHeight uint32) (*block.Block, error) {
b := block.New(bc.config.StateRootInHeader) b := block.New(bc.config.StateRootInHeader)
b.Index = nextBlockHeight b.Index = nextBlockHeight
hdr, err := bc.GetHeader(bc.GetHeaderHash(int(nextBlockHeight - 1))) hdr, err := bc.GetHeader(bc.GetHeaderHash(nextBlockHeight - 1))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -304,7 +304,7 @@ func TestChainWithVolatileNumOfValidators(t *testing.T) {
}, },
} }
curWit = nextWit curWit = nextWit
b.PrevHash = bc.GetHeaderHash(i - 1) b.PrevHash = bc.GetHeaderHash(uint32(i) - 1)
b.Timestamp = uint64(time.Now().UTC().Unix())*1000 + uint64(i) b.Timestamp = uint64(time.Now().UTC().Unix())*1000 + uint64(i)
b.Index = uint32(i) b.Index = uint32(i)
b.RebuildMerkleRoot() b.RebuildMerkleRoot()

View file

@ -1964,12 +1964,12 @@ func TestBlockchain_ResetState(t *testing.T) {
neoH := e.NativeHash(t, nativenames.Neo) neoH := e.NativeHash(t, nativenames.Neo)
gasID := e.NativeID(t, nativenames.Gas) gasID := e.NativeID(t, nativenames.Gas)
neoID := e.NativeID(t, nativenames.Neo) neoID := e.NativeID(t, nativenames.Neo)
resetBlockHash := bc.GetHeaderHash(int(resetBlockIndex)) resetBlockHash := bc.GetHeaderHash(resetBlockIndex)
resetBlockHeader, err := bc.GetHeader(resetBlockHash) resetBlockHeader, err := bc.GetHeader(resetBlockHash)
require.NoError(t, err) require.NoError(t, err)
topBlockHeight := bc.BlockHeight() topBlockHeight := bc.BlockHeight()
topBH := bc.GetHeaderHash(int(bc.BlockHeight())) topBH := bc.GetHeaderHash(bc.BlockHeight())
staleBH := bc.GetHeaderHash(int(resetBlockIndex + 1)) staleBH := bc.GetHeaderHash(resetBlockIndex + 1)
staleB, err := bc.GetBlock(staleBH) staleB, err := bc.GetBlock(staleBH)
require.NoError(t, err) require.NoError(t, err)
staleTx := staleB.Transactions[0] staleTx := staleB.Transactions[0]
@ -2037,7 +2037,7 @@ func TestBlockchain_ResetState(t *testing.T) {
require.Equal(t, uint32(0), bc.GetStateModule().CurrentValidatedHeight()) require.Equal(t, uint32(0), bc.GetStateModule().CurrentValidatedHeight())
// Try to get the latest block\header. // Try to get the latest block\header.
bh := bc.GetHeaderHash(int(resetBlockIndex)) bh := bc.GetHeaderHash(resetBlockIndex)
require.Equal(t, resetBlockHash, bh) require.Equal(t, resetBlockHash, bh)
h, err := bc.GetHeader(bh) h, err := bc.GetHeader(bh)
require.NoError(t, err) require.NoError(t, err)
@ -2048,7 +2048,7 @@ func TestBlockchain_ResetState(t *testing.T) {
// Check that stale blocks/headers/txs/aers/sr are not reachable. // Check that stale blocks/headers/txs/aers/sr are not reachable.
for i := resetBlockIndex + 1; i <= topBlockHeight; i++ { for i := resetBlockIndex + 1; i <= topBlockHeight; i++ {
hHash := bc.GetHeaderHash(int(i)) hHash := bc.GetHeaderHash(i)
require.Equal(t, util.Uint256{}, hHash) require.Equal(t, util.Uint256{}, hHash)
_, err = bc.GetStateRoot(i) _, err = bc.GetStateRoot(i)
require.Error(t, err) require.Error(t, err)

View file

@ -14,14 +14,14 @@ type DumperRestorer interface {
AddBlock(block *block.Block) error AddBlock(block *block.Block) error
GetBlock(hash util.Uint256) (*block.Block, error) GetBlock(hash util.Uint256) (*block.Block, error)
GetConfig() config.ProtocolConfiguration GetConfig() config.ProtocolConfiguration
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
} }
// Dump writes count blocks from start to the provided writer. // Dump writes count blocks from start to the provided writer.
// Note: header needs to be written separately by a client. // Note: header needs to be written separately by a client.
func Dump(bc DumperRestorer, w *io.BinWriter, start, count uint32) error { func Dump(bc DumperRestorer, w *io.BinWriter, start, count uint32) error {
for i := start; i < start+count; i++ { for i := start; i < start+count; i++ {
bh := bc.GetHeaderHash(int(i)) bh := bc.GetHeaderHash(i)
b, err := bc.GetBlock(bh) b, err := bc.GetBlock(bh)
if err != nil { if err != nil {
return err return err

View file

@ -59,7 +59,7 @@ func (bc *Blockchain) newBlock(txs ...*transaction.Transaction) *block.Block {
lastBlock, ok := bc.topBlock.Load().(*block.Block) lastBlock, ok := bc.topBlock.Load().(*block.Block)
if !ok { if !ok {
var err error var err error
lastBlock, err = bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()))) lastBlock, err = bc.GetBlock(bc.GetHeaderHash(bc.BlockHeight()))
if err != nil { if err != nil {
panic(err) panic(err)
} }

View file

@ -40,7 +40,7 @@ type Ledger interface {
CurrentBlockHash() util.Uint256 CurrentBlockHash() util.Uint256
GetBlock(hash util.Uint256) (*block.Block, error) GetBlock(hash util.Uint256) (*block.Block, error)
GetConfig() config.ProtocolConfiguration GetConfig() config.ProtocolConfiguration
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
} }
// Context represents context in which interops are executed. // Context represents context in which interops are executed.
@ -377,7 +377,7 @@ func (ic *Context) BlockHeight() uint32 {
// CurrentBlockHash returns current block hash got from Context's block if it's set. // CurrentBlockHash returns current block hash got from Context's block if it's set.
func (ic *Context) CurrentBlockHash() util.Uint256 { func (ic *Context) CurrentBlockHash() util.Uint256 {
if ic.Block != nil { if ic.Block != nil {
return ic.Chain.GetHeaderHash(int(ic.Block.Index - 1)) // Persisting block is not yet stored. return ic.Chain.GetHeaderHash(ic.Block.Index - 1) // Persisting block is not yet stored.
} }
return ic.Chain.CurrentBlockHash() return ic.Chain.CurrentBlockHash()
} }

View file

@ -196,7 +196,7 @@ func getBlockHashFromItem(ic *interop.Context, item stackitem.Item) util.Uint256
if uint32(index) > ic.BlockHeight() { if uint32(index) > ic.BlockHeight() {
panic(fmt.Errorf("no block with index %d", index)) panic(fmt.Errorf("no block with index %d", index))
} }
return ic.Chain.GetHeaderHash(int(index)) return ic.Chain.GetHeaderHash(uint32(index))
} }
hash, err := getUint256FromItem(item) hash, err := getUint256FromItem(item)
if err != nil { if err != nil {

View file

@ -111,7 +111,7 @@ func TestLedger_GetTransactionFromBlock(t *testing.T) {
ledgerInvoker := c.WithSigners(c.Committee) ledgerInvoker := c.WithSigners(c.Committee)
ledgerInvoker.Invoke(t, e.Chain.BlockHeight(), "currentIndex") // Adds a block. ledgerInvoker.Invoke(t, e.Chain.BlockHeight(), "currentIndex") // Adds a block.
b := e.GetBlockByIndex(t, int(e.Chain.BlockHeight())) b := e.GetBlockByIndex(t, e.Chain.BlockHeight())
check := func(t testing.TB, stack []stackitem.Item) { check := func(t testing.TB, stack []stackitem.Item) {
require.Equal(t, 1, len(stack)) require.Equal(t, 1, len(stack))
@ -148,8 +148,8 @@ func TestLedger_GetBlock(t *testing.T) {
e := c.Executor e := c.Executor
ledgerInvoker := c.WithSigners(c.Committee) ledgerInvoker := c.WithSigners(c.Committee)
ledgerInvoker.Invoke(t, e.Chain.GetHeaderHash(int(e.Chain.BlockHeight())).BytesBE(), "currentHash") // Adds a block. ledgerInvoker.Invoke(t, e.Chain.GetHeaderHash(e.Chain.BlockHeight()).BytesBE(), "currentHash") // Adds a block.
b := e.GetBlockByIndex(t, int(e.Chain.BlockHeight())) b := e.GetBlockByIndex(t, e.Chain.BlockHeight())
expected := []stackitem.Item{ expected := []stackitem.Item{
stackitem.NewByteArray(b.Hash().BytesBE()), stackitem.NewByteArray(b.Hash().BytesBE()),

View file

@ -44,7 +44,7 @@ func updatePersistedHeightMetric(pHeight uint32) {
persistedHeight.Set(float64(pHeight)) persistedHeight.Set(float64(pHeight))
} }
func updateHeaderHeightMetric(hHeight int) { func updateHeaderHeightMetric(hHeight uint32) {
headerHeight.Set(float64(hHeight)) headerHeight.Set(float64(hHeight))
} }

View file

@ -66,7 +66,7 @@ type Ledger interface {
BlockHeight() uint32 BlockHeight() uint32
GetConfig() config.ProtocolConfiguration GetConfig() config.ProtocolConfiguration
GetHeader(hash util.Uint256) (*block.Header, error) GetHeader(hash util.Uint256) (*block.Header, error)
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
HeaderHeight() uint32 HeaderHeight() uint32
} }
@ -214,7 +214,7 @@ func (s *Module) defineSyncStage() error {
s.log.Info("MPT is in sync", s.log.Info("MPT is in sync",
zap.Uint32("stateroot height", s.stateMod.CurrentLocalHeight())) zap.Uint32("stateroot height", s.stateMod.CurrentLocalHeight()))
} else if s.syncStage&headersSynced != 0 { } else if s.syncStage&headersSynced != 0 {
header, err := s.bc.GetHeader(s.bc.GetHeaderHash(int(s.syncPoint + 1))) header, err := s.bc.GetHeader(s.bc.GetHeaderHash(s.syncPoint + 1))
if err != nil { if err != nil {
return fmt.Errorf("failed to get header to initialize MPT billet: %w", err) return fmt.Errorf("failed to get header to initialize MPT billet: %w", err)
} }

View file

@ -16,9 +16,9 @@ import (
) )
func TestStateSyncModule_Init(t *testing.T) { func TestStateSyncModule_Init(t *testing.T) {
var ( const (
stateSyncInterval = 2 stateSyncInterval = 2
maxTraceable uint32 = 3 maxTraceable = 3
) )
spoutCfg := func(c *config.ProtocolConfiguration) { spoutCfg := func(c *config.ProtocolConfiguration) {
c.StateRootInHeader = true c.StateRootInHeader = true
@ -55,7 +55,7 @@ func TestStateSyncModule_Init(t *testing.T) {
t.Run("inactive: bolt chain height is close enough to spout chain height", func(t *testing.T) { t.Run("inactive: bolt chain height is close enough to spout chain height", func(t *testing.T) {
bcBolt, _, _ := chain.NewMultiWithCustomConfig(t, boltCfg) bcBolt, _, _ := chain.NewMultiWithCustomConfig(t, boltCfg)
for i := 1; i < int(bcSpout.BlockHeight())-stateSyncInterval; i++ { for i := uint32(1); i < bcSpout.BlockHeight()-stateSyncInterval; i++ {
b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i)) b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, bcBolt.AddBlock(b)) require.NoError(t, bcBolt.AddBlock(b))
@ -114,9 +114,9 @@ func TestStateSyncModule_Init(t *testing.T) {
require.NoError(t, module.Init(bcSpout.BlockHeight())) require.NoError(t, module.Init(bcSpout.BlockHeight()))
// firstly, fetch all headers to create proper DB state (where headers are in sync) // firstly, fetch all headers to create proper DB state (where headers are in sync)
stateSyncPoint := (int(bcSpout.BlockHeight()) / stateSyncInterval) * stateSyncInterval stateSyncPoint := (bcSpout.BlockHeight() / stateSyncInterval) * stateSyncInterval
var expectedHeader *block.Header var expectedHeader *block.Header
for i := 1; i <= int(bcSpout.HeaderHeight()); i++ { for i := uint32(1); i <= bcSpout.HeaderHeight(); i++ {
header, err := bcSpout.GetHeader(bcSpout.GetHeaderHash(i)) header, err := bcSpout.GetHeader(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, module.AddHeaders(header)) require.NoError(t, module.AddHeaders(header))
@ -142,7 +142,7 @@ func TestStateSyncModule_Init(t *testing.T) {
require.Equal(t, expectedHeader.PrevStateRoot, unknownNodes[0]) require.Equal(t, expectedHeader.PrevStateRoot, unknownNodes[0])
// add several blocks to create DB state where blocks are not in sync yet, but it's not a genesis. // add several blocks to create DB state where blocks are not in sync yet, but it's not a genesis.
for i := stateSyncPoint - int(maxTraceable) + 1; i <= stateSyncPoint-stateSyncInterval-1; i++ { for i := stateSyncPoint - maxTraceable + 1; i <= stateSyncPoint-stateSyncInterval-1; i++ {
block, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i)) block, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, module.AddBlock(block)) require.NoError(t, module.AddBlock(block))
@ -283,10 +283,10 @@ func TestStateSyncModule_Init(t *testing.T) {
func TestStateSyncModule_RestoreBasicChain(t *testing.T) { func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
check := func(t *testing.T, spoutEnableGC bool) { check := func(t *testing.T, spoutEnableGC bool) {
var ( const (
stateSyncInterval = 4 stateSyncInterval = 4
maxTraceable uint32 = 6 maxTraceable = 6
stateSyncPoint = 24 stateSyncPoint = 24
) )
spoutCfg := func(c *config.ProtocolConfiguration) { spoutCfg := func(c *config.ProtocolConfiguration) {
c.KeepOnlyLatestState = spoutEnableGC c.KeepOnlyLatestState = spoutEnableGC
@ -325,7 +325,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
require.Error(t, module.AddHeaders(h)) require.Error(t, module.AddHeaders(h))
}) })
t.Run("no error: add blocks before initialisation", func(t *testing.T) { t.Run("no error: add blocks before initialisation", func(t *testing.T) {
b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(int(bcSpout.BlockHeight()))) b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(bcSpout.BlockHeight()))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, module.AddBlock(b)) require.NoError(t, module.AddBlock(b))
}) })
@ -342,7 +342,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
// add headers to module // add headers to module
headers := make([]*block.Header, 0, bcSpout.HeaderHeight()) headers := make([]*block.Header, 0, bcSpout.HeaderHeight())
for i := uint32(1); i <= bcSpout.HeaderHeight(); i++ { for i := uint32(1); i <= bcSpout.HeaderHeight(); i++ {
h, err := bcSpout.GetHeader(bcSpout.GetHeaderHash(int(i))) h, err := bcSpout.GetHeader(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
headers = append(headers, h) headers = append(headers, h)
} }
@ -355,7 +355,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
// add blocks // add blocks
t.Run("error: unexpected block index", func(t *testing.T) { t.Run("error: unexpected block index", func(t *testing.T) {
b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(stateSyncPoint - int(maxTraceable))) b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(stateSyncPoint - maxTraceable))
require.NoError(t, err) require.NoError(t, err)
require.Error(t, module.AddBlock(b)) require.Error(t, module.AddBlock(b))
}) })
@ -379,7 +379,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
require.Error(t, module.AddBlock(b)) require.Error(t, module.AddBlock(b))
}) })
for i := stateSyncPoint - int(maxTraceable) + 1; i <= stateSyncPoint; i++ { for i := uint32(stateSyncPoint - maxTraceable + 1); i <= stateSyncPoint; i++ {
b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i)) b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, module.AddBlock(b)) require.NoError(t, module.AddBlock(b))
@ -432,7 +432,7 @@ func TestStateSyncModule_RestoreBasicChain(t *testing.T) {
require.Equal(t, uint32(stateSyncPoint), bcBolt.BlockHeight()) require.Equal(t, uint32(stateSyncPoint), bcBolt.BlockHeight())
// add missing blocks to bcBolt: should be ok, because state is synced // add missing blocks to bcBolt: should be ok, because state is synced
for i := stateSyncPoint + 1; i <= int(bcSpout.BlockHeight()); i++ { for i := uint32(stateSyncPoint + 1); i <= bcSpout.BlockHeight(); i++ {
b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i)) b, err := bcSpout.GetBlock(bcSpout.GetHeaderHash(i))
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, bcBolt.AddBlock(b)) require.NoError(t, bcBolt.AddBlock(b))

View file

@ -52,7 +52,7 @@ func NewExecutor(t testing.TB, bc *core.Blockchain, validator, committee Signer)
// TopBlock returns the block with the highest index. // TopBlock returns the block with the highest index.
func (e *Executor) TopBlock(t testing.TB) *block.Block { func (e *Executor) TopBlock(t testing.TB) *block.Block {
b, err := e.Chain.GetBlock(e.Chain.GetHeaderHash(int(e.Chain.BlockHeight()))) b, err := e.Chain.GetBlock(e.Chain.GetHeaderHash(e.Chain.BlockHeight()))
require.NoError(t, err) require.NoError(t, err)
return b return b
} }
@ -361,7 +361,7 @@ func (e *Executor) AddBlockCheckHalt(t testing.TB, txs ...*transaction.Transacti
// TestInvoke creates a test VM with a dummy block and executes a transaction in it. // TestInvoke creates a test VM with a dummy block and executes a transaction in it.
func TestInvoke(bc *core.Blockchain, tx *transaction.Transaction) (*vm.VM, error) { func TestInvoke(bc *core.Blockchain, tx *transaction.Transaction) (*vm.VM, error) {
lastBlock, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()))) lastBlock, err := bc.GetBlock(bc.GetHeaderHash(bc.BlockHeight()))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -392,7 +392,7 @@ func (e *Executor) GetTransaction(t testing.TB, h util.Uint256) (*transaction.Tr
} }
// GetBlockByIndex returns a block by the specified index. // GetBlockByIndex returns a block by the specified index.
func (e *Executor) GetBlockByIndex(t testing.TB, idx int) *block.Block { func (e *Executor) GetBlockByIndex(t testing.TB, idx uint32) *block.Block {
h := e.Chain.GetHeaderHash(idx) h := e.Chain.GetHeaderHash(idx)
require.NotEmpty(t, h) require.NotEmpty(t, h)
b, err := e.Chain.GetBlock(h) b, err := e.Chain.GetBlock(h)

View file

@ -61,7 +61,7 @@ type (
GetBlock(hash util.Uint256) (*block.Block, error) GetBlock(hash util.Uint256) (*block.Block, error)
GetConfig() config.ProtocolConfiguration GetConfig() config.ProtocolConfiguration
GetHeader(hash util.Uint256) (*block.Header, error) GetHeader(hash util.Uint256) (*block.Header, error)
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
GetMaxVerificationGAS() int64 GetMaxVerificationGAS() int64
GetMemPool() *mempool.Pool GetMemPool() *mempool.Pool
GetNotaryBalance(acc util.Uint160) *big.Int GetNotaryBalance(acc util.Uint160) *big.Int
@ -972,7 +972,7 @@ func (s *Server) handleGetBlocksCmd(p Peer, gb *payload.GetBlocks) error {
} }
blockHashes := make([]util.Uint256, 0) blockHashes := make([]util.Uint256, 0)
for i := start.Index + 1; i <= start.Index+uint32(count); i++ { for i := start.Index + 1; i <= start.Index+uint32(count); i++ {
hash := s.chain.GetHeaderHash(int(i)) hash := s.chain.GetHeaderHash(i)
if hash.Equals(util.Uint256{}) { if hash.Equals(util.Uint256{}) {
break break
} }
@ -995,7 +995,7 @@ func (s *Server) handleGetBlockByIndexCmd(p Peer, gbd *payload.GetBlockByIndex)
count = payload.MaxHashesCount count = payload.MaxHashesCount
} }
for i := gbd.IndexStart; i < gbd.IndexStart+uint32(count); i++ { for i := gbd.IndexStart; i < gbd.IndexStart+uint32(count); i++ {
hash := s.chain.GetHeaderHash(int(i)) hash := s.chain.GetHeaderHash(i)
if hash.Equals(util.Uint256{}) { if hash.Equals(util.Uint256{}) {
break break
} }
@ -1026,7 +1026,7 @@ func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlockByIndex) error
resp := payload.Headers{} resp := payload.Headers{}
resp.Hdrs = make([]*block.Header, 0, count) resp.Hdrs = make([]*block.Header, 0, count)
for i := gh.IndexStart; i < gh.IndexStart+uint32(count); i++ { for i := gh.IndexStart; i < gh.IndexStart+uint32(count); i++ {
hash := s.chain.GetHeaderHash(int(i)) hash := s.chain.GetHeaderHash(i)
if hash.Equals(util.Uint256{}) { if hash.Equals(util.Uint256{}) {
break break
} }

View file

@ -1272,7 +1272,7 @@ func TestInvokeVerify(t *testing.T) {
}) })
t.Run("positive, historic, by block, with signer", func(t *testing.T) { t.Run("positive, historic, by block, with signer", func(t *testing.T) {
res, err := c.InvokeContractVerifyWithState(chain.GetHeaderHash(int(chain.BlockHeight())-1), contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}}) res, err := c.InvokeContractVerifyWithState(chain.GetHeaderHash(chain.BlockHeight()-1), contract, []smartcontract.Parameter{}, []transaction.Signer{{Account: testchain.PrivateKeyByID(0).PublicKey().GetScriptHash()}})
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "HALT", res.State) require.Equal(t, "HALT", res.State)
require.Equal(t, 1, len(res.Stack)) require.Equal(t, 1, len(res.Stack))

View file

@ -78,7 +78,7 @@ type (
GetEnrollments() ([]state.Validator, error) GetEnrollments() ([]state.Validator, error)
GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint32) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint32)
GetHeader(hash util.Uint256) (*block.Header, error) GetHeader(hash util.Uint256) (*block.Header, error)
GetHeaderHash(int) util.Uint256 GetHeaderHash(uint32) util.Uint256
GetMaxVerificationGAS() int64 GetMaxVerificationGAS() int64
GetMemPool() *mempool.Pool GetMemPool() *mempool.Pool
GetNEP11Contracts() []util.Uint160 GetNEP11Contracts() []util.Uint160
@ -652,7 +652,7 @@ func (s *Server) fillBlockMetadata(obj io.Serializable, h *block.Header) result.
Confirmations: s.chain.BlockHeight() - h.Index + 1, Confirmations: s.chain.BlockHeight() - h.Index + 1,
} }
hash := s.chain.GetHeaderHash(int(h.Index) + 1) hash := s.chain.GetHeaderHash(h.Index + 1)
if !hash.Equals(util.Uint256{}) { if !hash.Equals(util.Uint256{}) {
res.NextBlockHash = &hash res.NextBlockHash = &hash
} }
@ -1646,7 +1646,7 @@ func (s *Server) getrawtransaction(reqParams params.Params) (interface{}, *neorp
if height == math.MaxUint32 { // Mempooled transaction. if height == math.MaxUint32 { // Mempooled transaction.
return res, nil return res, nil
} }
_header := s.chain.GetHeaderHash(int(height)) _header := s.chain.GetHeaderHash(height)
header, err := s.chain.GetHeader(_header) header, err := s.chain.GetHeader(_header)
if err != nil { if err != nil {
return nil, neorpc.NewRPCError("Failed to get header for the transaction", err.Error()) return nil, neorpc.NewRPCError("Failed to get header for the transaction", err.Error())
@ -2037,15 +2037,12 @@ func (s *Server) getHistoricParams(reqParams params.Params) (uint32, *neorpc.Err
if err != nil { if err != nil {
return 0, neorpc.NewInvalidParamsError(fmt.Sprintf("unknown block or stateroot: %s", err)) return 0, neorpc.NewInvalidParamsError(fmt.Sprintf("unknown block or stateroot: %s", err))
} }
height = int(stateH) height = stateH
} else { } else {
height = int(b.Index) height = b.Index
} }
} }
if height > math.MaxUint32 { return height + 1, nil
return 0, neorpc.NewInvalidParamsError("historic height exceeds max uint32 value")
}
return uint32(height) + 1, nil
} }
func (s *Server) prepareInvocationContext(t trigger.Type, script []byte, contractScriptHash util.Uint160, tx *transaction.Transaction, nextH *uint32, verbose bool) (*interop.Context, *neorpc.Error) { func (s *Server) prepareInvocationContext(t trigger.Type, script []byte, contractScriptHash util.Uint160, tx *transaction.Transaction, nextH *uint32, verbose bool) (*interop.Context, *neorpc.Error) {
@ -2683,16 +2680,16 @@ drainloop:
close(s.notaryRequestCh) close(s.notaryRequestCh)
} }
func (s *Server) blockHeightFromParam(param *params.Param) (int, *neorpc.Error) { func (s *Server) blockHeightFromParam(param *params.Param) (uint32, *neorpc.Error) {
num, err := param.GetInt() num, err := param.GetInt()
if err != nil { if err != nil {
return 0, neorpc.ErrInvalidParams return 0, neorpc.ErrInvalidParams
} }
if num < 0 || num > int(s.chain.BlockHeight()) { if num < 0 || int64(num) > int64(s.chain.BlockHeight()) {
return 0, invalidBlockHeightError(0, num) return 0, invalidBlockHeightError(0, num)
} }
return num, nil return uint32(num), nil
} }
func (s *Server) packResponse(r *params.In, result interface{}, respErr *neorpc.Error) abstract { func (s *Server) packResponse(r *params.In, result interface{}, respErr *neorpc.Error) abstract {

View file

@ -2271,7 +2271,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
}) })
t.Run("verbose != 0", func(t *testing.T) { t.Run("verbose != 0", func(t *testing.T) {
nextHash := chain.GetHeaderHash(int(hdr.Index) + 1) nextHash := chain.GetHeaderHash(hdr.Index + 1)
expected := &result.Header{ expected := &result.Header{
Header: *hdr, Header: *hdr,
BlockMetadata: result.BlockMetadata{ BlockMetadata: result.BlockMetadata{
@ -2315,7 +2315,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
testNEP17T := func(t *testing.T, start, stop, limit, page int, sent, rcvd []int) { testNEP17T := func(t *testing.T, start, stop, limit, page int, sent, rcvd []int) {
ps := []string{`"` + testchain.PrivateKeyByID(0).Address() + `"`} ps := []string{`"` + testchain.PrivateKeyByID(0).Address() + `"`}
if start != 0 { if start != 0 {
h, err := e.chain.GetHeader(e.chain.GetHeaderHash(start)) h, err := e.chain.GetHeader(e.chain.GetHeaderHash(uint32(start)))
var ts uint64 var ts uint64
if err == nil { if err == nil {
ts = h.Timestamp ts = h.Timestamp
@ -2325,7 +2325,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
ps = append(ps, strconv.FormatUint(ts, 10)) ps = append(ps, strconv.FormatUint(ts, 10))
} }
if stop != 0 { if stop != 0 {
h, err := e.chain.GetHeader(e.chain.GetHeaderHash(stop)) h, err := e.chain.GetHeader(e.chain.GetHeaderHash(uint32(stop)))
var ts uint64 var ts uint64
if err == nil { if err == nil {
ts = h.Timestamp ts = h.Timestamp
@ -2846,7 +2846,7 @@ func checkNep17TransfersAux(t *testing.T, e *executor, acc interface{}, sent, rc
rublesHash, err := util.Uint160DecodeStringLE(testContractHash) rublesHash, err := util.Uint160DecodeStringLE(testContractHash)
require.NoError(t, err) require.NoError(t, err)
blockWithFAULTedTx, err := e.chain.GetBlock(e.chain.GetHeaderHash(int(faultedTxBlock))) // Transaction with ABORT inside. blockWithFAULTedTx, err := e.chain.GetBlock(e.chain.GetHeaderHash(faultedTxBlock)) // Transaction with ABORT inside.
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 1, len(blockWithFAULTedTx.Transactions)) require.Equal(t, 1, len(blockWithFAULTedTx.Transactions))
txFAULTed := blockWithFAULTedTx.Transactions[0] txFAULTed := blockWithFAULTedTx.Transactions[0]

View file

@ -66,7 +66,7 @@ func main() {
handleError("can't get next block validators", err) handleError("can't get next block validators", err)
valScript, err := smartcontract.CreateDefaultMultiSigRedeemScript(nbVals) valScript, err := smartcontract.CreateDefaultMultiSigRedeemScript(nbVals)
handleError("can't create verification script", err) handleError("can't create verification script", err)
lastBlock, err := bc.GetBlock(bc.GetHeaderHash(int(bc.BlockHeight()))) lastBlock, err := bc.GetBlock(bc.GetHeaderHash(bc.BlockHeight()))
handleError("can't fetch last block", err) handleError("can't fetch last block", err)
txMoveNeo, err := testchain.NewTransferFromOwner(bc, bc.GoverningTokenHash(), h, native.NEOTotalSupply, 0, 2) txMoveNeo, err := testchain.NewTransferFromOwner(bc, bc.GoverningTokenHash(), h, native.NEOTotalSupply, 0, 2)