forked from TrueCloudLab/neoneo-go
core: remove untraceable blocks wrt StateSyncInterval
This commit is contained in:
parent
6ca7983be8
commit
35501a281a
2 changed files with 96 additions and 25 deletions
|
@ -740,8 +740,22 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bc.config.RemoveUntraceableBlocks {
|
if bc.config.RemoveUntraceableBlocks {
|
||||||
if block.Index > bc.config.MaxTraceableBlocks {
|
var start, stop uint32
|
||||||
index := block.Index - bc.config.MaxTraceableBlocks // is at least 1
|
if bc.config.P2PStateExchangeExtensions {
|
||||||
|
// remove batch of old blocks starting from P2-MaxTraceableBlocks-StateSyncInterval up to P2-MaxTraceableBlocks
|
||||||
|
if block.Index >= 2*uint32(bc.config.StateSyncInterval) &&
|
||||||
|
block.Index >= uint32(bc.config.StateSyncInterval)+bc.config.MaxTraceableBlocks && // check this in case if MaxTraceableBlocks>StateSyncInterval
|
||||||
|
int(block.Index)%bc.config.StateSyncInterval == 0 {
|
||||||
|
stop = block.Index - uint32(bc.config.StateSyncInterval) - bc.config.MaxTraceableBlocks
|
||||||
|
if stop > uint32(bc.config.StateSyncInterval) {
|
||||||
|
start = stop - uint32(bc.config.StateSyncInterval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if block.Index > bc.config.MaxTraceableBlocks {
|
||||||
|
start = block.Index - bc.config.MaxTraceableBlocks // is at least 1
|
||||||
|
stop = start + 1
|
||||||
|
}
|
||||||
|
for index := start; index < stop; index++ {
|
||||||
err := kvcache.DeleteBlock(bc.headerHashes[index], writeBuf)
|
err := kvcache.DeleteBlock(bc.headerHashes[index], writeBuf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bc.log.Warn("error while removing old block",
|
bc.log.Warn("error while removing old block",
|
||||||
|
|
|
@ -1579,35 +1579,92 @@ func TestDumpAndRestore(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoveUntraceable(t *testing.T) {
|
func TestRemoveUntraceable(t *testing.T) {
|
||||||
bc := newTestChainWithCustomCfg(t, func(c *config.Config) {
|
check := func(t *testing.T, bc *Blockchain, tHash, bHash util.Uint256, errorExpected bool) {
|
||||||
c.ProtocolConfiguration.MaxTraceableBlocks = 2
|
_, _, err := bc.GetTransaction(tHash)
|
||||||
c.ProtocolConfiguration.RemoveUntraceableBlocks = true
|
if errorExpected {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
_, err = bc.GetAppExecResults(tHash, trigger.Application)
|
||||||
|
if errorExpected {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
_, err = bc.GetBlock(bHash)
|
||||||
|
if errorExpected {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
_, err = bc.GetHeader(bHash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
t.Run("P2PStateExchangeExtensions off", func(t *testing.T) {
|
||||||
|
bc := newTestChainWithCustomCfg(t, func(c *config.Config) {
|
||||||
|
c.ProtocolConfiguration.MaxTraceableBlocks = 2
|
||||||
|
c.ProtocolConfiguration.RemoveUntraceableBlocks = true
|
||||||
|
})
|
||||||
|
|
||||||
|
tx1, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
b1 := bc.newBlock(tx1)
|
||||||
|
require.NoError(t, bc.AddBlock(b1))
|
||||||
|
tx1Height := bc.BlockHeight()
|
||||||
|
|
||||||
|
tx2, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NoError(t, bc.AddBlock(bc.newBlock(tx2)))
|
||||||
|
|
||||||
|
_, h1, err := bc.GetTransaction(tx1.Hash())
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tx1Height, h1)
|
||||||
|
|
||||||
|
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||||
|
|
||||||
|
check(t, bc, tx1.Hash(), b1.Hash(), true)
|
||||||
})
|
})
|
||||||
|
t.Run("P2PStateExchangeExtensions on", func(t *testing.T) {
|
||||||
|
bc := newTestChainWithCustomCfg(t, func(c *config.Config) {
|
||||||
|
c.ProtocolConfiguration.MaxTraceableBlocks = 2
|
||||||
|
c.ProtocolConfiguration.RemoveUntraceableBlocks = true
|
||||||
|
c.ProtocolConfiguration.P2PStateExchangeExtensions = true
|
||||||
|
c.ProtocolConfiguration.StateSyncInterval = 2
|
||||||
|
c.ProtocolConfiguration.StateRootInHeader = true
|
||||||
|
})
|
||||||
|
|
||||||
tx1, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
tx1, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
b1 := bc.newBlock(tx1)
|
b1 := bc.newBlock(tx1)
|
||||||
require.NoError(t, bc.AddBlock(b1))
|
require.NoError(t, bc.AddBlock(b1))
|
||||||
tx1Height := bc.BlockHeight()
|
tx1Height := bc.BlockHeight()
|
||||||
|
|
||||||
tx2, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
tx2, err := testchain.NewTransferFromOwner(bc, bc.contracts.NEO.Hash, util.Uint160{}, 1, 0, bc.BlockHeight()+1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, bc.AddBlock(bc.newBlock(tx2)))
|
b2 := bc.newBlock(tx2)
|
||||||
|
require.NoError(t, bc.AddBlock(b2))
|
||||||
|
tx2Height := bc.BlockHeight()
|
||||||
|
|
||||||
_, h1, err := bc.GetTransaction(tx1.Hash())
|
_, h1, err := bc.GetTransaction(tx1.Hash())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tx1Height, h1)
|
require.Equal(t, tx1Height, h1)
|
||||||
|
|
||||||
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||||
|
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||||
|
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||||
|
|
||||||
_, _, err = bc.GetTransaction(tx1.Hash())
|
check(t, bc, tx1.Hash(), b1.Hash(), false)
|
||||||
require.Error(t, err)
|
check(t, bc, tx2.Hash(), b2.Hash(), false)
|
||||||
_, err = bc.GetAppExecResults(tx1.Hash(), trigger.Application)
|
|
||||||
require.Error(t, err)
|
require.NoError(t, bc.AddBlock(bc.newBlock()))
|
||||||
_, err = bc.GetBlock(b1.Hash())
|
|
||||||
require.Error(t, err)
|
check(t, bc, tx1.Hash(), b1.Hash(), true)
|
||||||
_, err = bc.GetHeader(b1.Hash())
|
check(t, bc, tx2.Hash(), b2.Hash(), false)
|
||||||
require.NoError(t, err)
|
_, h2, err := bc.GetTransaction(tx2.Hash())
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tx2Height, h2)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidNotification(t *testing.T) {
|
func TestInvalidNotification(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue