mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
Merge pull request #2370 from nspcc-dev/nonzero-blockchain-start
core: add tests for non-zero blockchain start
This commit is contained in:
commit
473d11d24e
4 changed files with 288 additions and 36 deletions
|
@ -332,22 +332,22 @@ func (bc *Blockchain) init() error {
|
|||
return bc.storeBlock(genesisBlock, nil)
|
||||
}
|
||||
if ver.Value != version {
|
||||
return fmt.Errorf("storage version mismatch betweeen %s and %s", version, ver.Value)
|
||||
return fmt.Errorf("storage version mismatch (expected=%s, actual=%s)", version, ver.Value)
|
||||
}
|
||||
if ver.StateRootInHeader != bc.config.StateRootInHeader {
|
||||
return fmt.Errorf("StateRootInHeader setting mismatch (config=%t, db=%t)",
|
||||
ver.StateRootInHeader, bc.config.StateRootInHeader)
|
||||
bc.config.StateRootInHeader, ver.StateRootInHeader)
|
||||
}
|
||||
if ver.P2PSigExtensions != bc.config.P2PSigExtensions {
|
||||
return fmt.Errorf("P2PSigExtensions setting mismatch (old=%t, new=%t",
|
||||
return fmt.Errorf("P2PSigExtensions setting mismatch (old=%t, new=%t)",
|
||||
ver.P2PSigExtensions, bc.config.P2PSigExtensions)
|
||||
}
|
||||
if ver.P2PStateExchangeExtensions != bc.config.P2PStateExchangeExtensions {
|
||||
return fmt.Errorf("P2PStateExchangeExtensions setting mismatch (old=%t, new=%t",
|
||||
return fmt.Errorf("P2PStateExchangeExtensions setting mismatch (old=%t, new=%t)",
|
||||
ver.P2PStateExchangeExtensions, bc.config.P2PStateExchangeExtensions)
|
||||
}
|
||||
if ver.KeepOnlyLatestState != bc.config.KeepOnlyLatestState {
|
||||
return fmt.Errorf("KeepOnlyLatestState setting mismatch: old=%v, new=%v",
|
||||
return fmt.Errorf("KeepOnlyLatestState setting mismatch (old=%v, new=%v)",
|
||||
ver.KeepOnlyLatestState, bc.config.KeepOnlyLatestState)
|
||||
}
|
||||
bc.dao.Version = ver
|
||||
|
@ -367,7 +367,7 @@ func (bc *Blockchain) init() error {
|
|||
|
||||
currHeaderHeight, currHeaderHash, err := bc.dao.GetCurrentHeaderHeight()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to retrieve current header info: %w", err)
|
||||
}
|
||||
if bc.storedHeaderCount == 0 && currHeaderHeight == 0 {
|
||||
bc.headerHashes = append(bc.headerHashes, currHeaderHash)
|
||||
|
@ -425,7 +425,7 @@ func (bc *Blockchain) init() error {
|
|||
|
||||
bHeight, err := bc.dao.GetCurrentBlockHeight()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to retrieve current block height: %w", err)
|
||||
}
|
||||
bc.blockHeight = bHeight
|
||||
bc.persistedHeight = bHeight
|
||||
|
@ -448,13 +448,16 @@ func (bc *Blockchain) init() error {
|
|||
// contract state from DAO via high-level bc API.
|
||||
for _, c := range bc.contracts.Contracts {
|
||||
md := c.Metadata()
|
||||
storedCS := bc.GetContractState(md.Hash)
|
||||
history := md.UpdateHistory
|
||||
if len(history) == 0 || history[0] > bHeight {
|
||||
if storedCS != nil {
|
||||
return fmt.Errorf("native contract %s is already stored, but marked as inactive for height %d in config", md.Name, bHeight)
|
||||
}
|
||||
continue
|
||||
}
|
||||
storedCS := bc.GetContractState(md.Hash)
|
||||
if storedCS == nil {
|
||||
return fmt.Errorf("native contract %s is not stored", md.Name)
|
||||
return fmt.Errorf("native contract %s is not stored, but should be active at height %d according to config", md.Name, bHeight)
|
||||
}
|
||||
storedCSBytes, err := stackitem.SerializeConvertible(storedCS)
|
||||
if err != nil {
|
||||
|
|
|
@ -17,10 +17,12 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/chaindump"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativeprices"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
|
@ -1578,7 +1580,7 @@ func TestDumpAndRestore(t *testing.T) {
|
|||
})
|
||||
t.Run("with state root", func(t *testing.T) {
|
||||
testDumpAndRestore(t, func(c *config.Config) {
|
||||
c.ProtocolConfiguration.StateRootInHeader = false
|
||||
c.ProtocolConfiguration.StateRootInHeader = true
|
||||
}, nil)
|
||||
})
|
||||
t.Run("remove untraceable", func(t *testing.T) {
|
||||
|
@ -1834,6 +1836,7 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
|
|||
c.ProtocolConfiguration.P2PStateExchangeExtensions = true
|
||||
c.ProtocolConfiguration.StateSyncInterval = stateSyncInterval
|
||||
c.ProtocolConfiguration.MaxTraceableBlocks = maxTraceable
|
||||
c.ProtocolConfiguration.KeepOnlyLatestState = true
|
||||
}
|
||||
bcSpout := newTestChainWithCustomCfg(t, spountCfg)
|
||||
initBasicChain(t, bcSpout)
|
||||
|
@ -1865,14 +1868,15 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
|
|||
_, err := batch.Persist()
|
||||
require.NoError(t, err)
|
||||
|
||||
checkNewBlockchainErr := func(t *testing.T, cfg func(c *config.Config), store storage.Store, shouldFail bool) {
|
||||
checkNewBlockchainErr := func(t *testing.T, cfg func(c *config.Config), store storage.Store, errText string) {
|
||||
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
|
||||
require.NoError(t, err)
|
||||
cfg(&unitTestNetCfg)
|
||||
log := zaptest.NewLogger(t)
|
||||
_, err = NewBlockchain(store, unitTestNetCfg.ProtocolConfiguration, log)
|
||||
if shouldFail {
|
||||
if len(errText) != 0 {
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), errText))
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@ -1888,22 +1892,22 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
|
|||
checkNewBlockchainErr(t, func(c *config.Config) {
|
||||
boltCfg(c)
|
||||
c.ProtocolConfiguration.RemoveUntraceableBlocks = false
|
||||
}, bcSpout.dao.Store, true)
|
||||
}, bcSpout.dao.Store, "state jump was not completed, but P2PStateExchangeExtensions are disabled or archival node capability is on")
|
||||
})
|
||||
t.Run("invalid state jump stage format", func(t *testing.T) {
|
||||
bcSpout.dao.Store.Put(bPrefix, []byte{0x01, 0x02})
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, true)
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, "invalid state jump stage format")
|
||||
})
|
||||
t.Run("missing state sync point", func(t *testing.T) {
|
||||
bcSpout.dao.Store.Put(bPrefix, []byte{byte(stateJumpStarted)})
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, true)
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, "failed to get state sync point from the storage")
|
||||
})
|
||||
t.Run("invalid state sync point", func(t *testing.T) {
|
||||
bcSpout.dao.Store.Put(bPrefix, []byte{byte(stateJumpStarted)})
|
||||
point := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(point, uint32(len(bcSpout.headerHashes)))
|
||||
bcSpout.dao.Store.Put([]byte{byte(storage.SYSStateSyncPoint)}, point)
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, true)
|
||||
checkNewBlockchainErr(t, boltCfg, bcSpout.dao.Store, "invalid state sync point")
|
||||
})
|
||||
for _, stage := range []stateJumpStage{stateJumpStarted, newStorageItemsAdded, genesisStateRemoved, 0x03} {
|
||||
t.Run(fmt.Sprintf("state jump stage %d", stage), func(t *testing.T) {
|
||||
|
@ -1911,8 +1915,11 @@ func TestBlockchain_InitWithIncompleteStateJump(t *testing.T) {
|
|||
point := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(point, uint32(stateSyncPoint))
|
||||
bcSpout.dao.Store.Put([]byte{byte(storage.SYSStateSyncPoint)}, point)
|
||||
shouldFail := stage == 0x03 // unknown stage
|
||||
checkNewBlockchainErr(t, spountCfg, bcSpout.dao.Store, shouldFail)
|
||||
var errText string
|
||||
if stage == 0x03 {
|
||||
errText = "unknown state jump stage"
|
||||
}
|
||||
checkNewBlockchainErr(t, spountCfg, bcSpout.dao.Store, errText)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1998,3 +2005,227 @@ func setSigner(tx *transaction.Transaction, h util.Uint160) {
|
|||
Scopes: transaction.Global,
|
||||
}}
|
||||
}
|
||||
|
||||
func TestBlockchain_StartFromExistingDB(t *testing.T) {
|
||||
ps, path := newLevelDBForTestingWithPath(t, "")
|
||||
customConfig := func(c *config.Config) {
|
||||
c.ProtocolConfiguration.StateRootInHeader = true // Need for P2PStateExchangeExtensions check.
|
||||
}
|
||||
bc := initTestChain(t, ps, customConfig)
|
||||
go bc.Run()
|
||||
initBasicChain(t, bc)
|
||||
require.True(t, bc.BlockHeight() > 5, "ensure that basic chain is correctly initialised")
|
||||
|
||||
// Information for further tests.
|
||||
h := bc.BlockHeight()
|
||||
cryptoLibHash, err := bc.GetNativeContractScriptHash(nativenames.CryptoLib)
|
||||
require.NoError(t, err)
|
||||
cryptoLibState := bc.GetContractState(cryptoLibHash)
|
||||
require.NotNil(t, cryptoLibState)
|
||||
var (
|
||||
managementID = -1
|
||||
managementContractPrefix = 8
|
||||
)
|
||||
|
||||
bc.Close() // Ensure persist is done and persistent store is properly closed.
|
||||
|
||||
newPS := func(t *testing.T) storage.Store {
|
||||
ps, _ = newLevelDBForTestingWithPath(t, path)
|
||||
t.Cleanup(func() { require.NoError(t, ps.Close()) })
|
||||
return ps
|
||||
}
|
||||
t.Run("mismatch storage version", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
d := dao.NewSimple(cache, bc.config.StateRootInHeader, bc.config.P2PStateExchangeExtensions)
|
||||
d.PutVersion(dao.Version{
|
||||
Value: "0.0.0",
|
||||
})
|
||||
_, err := d.Persist() // Persist to `cache` wrapper.
|
||||
require.NoError(t, err)
|
||||
_, err = initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "storage version mismatch"))
|
||||
})
|
||||
t.Run("mismatch StateRootInHeader", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, func(c *config.Config) {
|
||||
customConfig(c)
|
||||
c.ProtocolConfiguration.StateRootInHeader = false
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "StateRootInHeader setting mismatch"))
|
||||
})
|
||||
t.Run("mismatch P2PSigExtensions", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, func(c *config.Config) {
|
||||
customConfig(c)
|
||||
c.ProtocolConfiguration.P2PSigExtensions = false
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "P2PSigExtensions setting mismatch"))
|
||||
})
|
||||
t.Run("mismatch P2PStateExchangeExtensions", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, func(c *config.Config) {
|
||||
customConfig(c)
|
||||
c.ProtocolConfiguration.StateRootInHeader = true
|
||||
c.ProtocolConfiguration.P2PStateExchangeExtensions = true
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "P2PStateExchangeExtensions setting mismatch"))
|
||||
})
|
||||
t.Run("mismatch KeepOnlyLatestState", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, func(c *config.Config) {
|
||||
customConfig(c)
|
||||
c.ProtocolConfiguration.KeepOnlyLatestState = true
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "KeepOnlyLatestState setting mismatch"))
|
||||
})
|
||||
t.Run("corrupted headers", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Corrupt headers hashes batch.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
key := make([]byte, 5)
|
||||
key[0] = byte(storage.IXHeaderHashList)
|
||||
binary.BigEndian.PutUint32(key[1:], 1)
|
||||
cache.Put(key, []byte{1, 2, 3})
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "failed to read batch of 2000"))
|
||||
})
|
||||
t.Run("corrupted current header height", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Remove current header.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
cache.Delete([]byte{byte(storage.SYSCurrentHeader)})
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "failed to retrieve current header"))
|
||||
})
|
||||
t.Run("missing last batch of 2000 headers and missing last header", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Remove latest headers hashes batch and current header.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
cache.Delete([]byte{byte(storage.IXHeaderHashList)})
|
||||
currHeaderInfo, err := cache.Get([]byte{byte(storage.SYSCurrentHeader)})
|
||||
require.NoError(t, err)
|
||||
currHeaderHash, err := util.Uint256DecodeBytesLE(currHeaderInfo[:32])
|
||||
require.NoError(t, err)
|
||||
cache.Delete(append([]byte{byte(storage.DataExecutable)}, currHeaderHash.BytesBE()...))
|
||||
|
||||
_, err = initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "could not get header"))
|
||||
})
|
||||
t.Run("missing last block", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Remove current block from storage.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
cache.Delete([]byte{byte(storage.SYSCurrentBlock)})
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "failed to retrieve current block height"))
|
||||
})
|
||||
t.Run("missing last stateroot", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Remove latest stateroot from storage.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
key := make([]byte, 5)
|
||||
key[0] = byte(storage.DataMPTAux)
|
||||
binary.BigEndian.PutUint32(key, h)
|
||||
cache.Delete(key)
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "can't init MPT at height"))
|
||||
})
|
||||
t.Run("failed native Management initialisation", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Corrupt serialised CryptoLib state.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
key := make([]byte, 1+4+1+20)
|
||||
key[0] = byte(storage.STStorage)
|
||||
binary.LittleEndian.PutUint32(key[1:], uint32(managementID))
|
||||
key[5] = byte(managementContractPrefix)
|
||||
copy(key[6:], cryptoLibHash.BytesBE())
|
||||
cache.Put(key, []byte{1, 2, 3})
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), "can't init cache for Management native contract"))
|
||||
})
|
||||
t.Run("invalid native contract deactivation", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, func(c *config.Config) {
|
||||
customConfig(c)
|
||||
c.ProtocolConfiguration.NativeUpdateHistories = map[string][]uint32{
|
||||
nativenames.Policy: {0},
|
||||
nativenames.Neo: {0},
|
||||
nativenames.Gas: {0},
|
||||
nativenames.Designation: {0},
|
||||
nativenames.StdLib: {0},
|
||||
nativenames.Management: {0},
|
||||
nativenames.Oracle: {0},
|
||||
nativenames.Ledger: {0},
|
||||
nativenames.Notary: {0},
|
||||
nativenames.CryptoLib: {h + 10},
|
||||
}
|
||||
})
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), fmt.Sprintf("native contract %s is already stored, but marked as inactive for height %d in config", nativenames.CryptoLib, h)))
|
||||
})
|
||||
t.Run("invalid native contract activation", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Remove CryptoLib from storage.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
key := make([]byte, 1+4+1+20)
|
||||
key[0] = byte(storage.STStorage)
|
||||
binary.LittleEndian.PutUint32(key[1:], uint32(managementID))
|
||||
key[5] = byte(managementContractPrefix)
|
||||
copy(key[6:], cryptoLibHash.BytesBE())
|
||||
cache.Delete(key)
|
||||
|
||||
_, err := initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), fmt.Sprintf("native contract %s is not stored, but should be active at height %d according to config", nativenames.CryptoLib, h)))
|
||||
})
|
||||
t.Run("stored and autogenerated native contract's states mismatch", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
|
||||
// Change stored CryptoLib state.
|
||||
cache := storage.NewMemCachedStore(ps) // Extra wrapper to avoid good DB corruption.
|
||||
key := make([]byte, 1+4+1+20)
|
||||
key[0] = byte(storage.STStorage)
|
||||
binary.LittleEndian.PutUint32(key[1:], uint32(managementID))
|
||||
key[5] = byte(managementContractPrefix)
|
||||
copy(key[6:], cryptoLibHash.BytesBE())
|
||||
cs := *cryptoLibState
|
||||
cs.ID = -123
|
||||
csBytes, err := stackitem.SerializeConvertible(&cs)
|
||||
require.NoError(t, err)
|
||||
cache.Put(key, csBytes)
|
||||
|
||||
_, err = initTestChainNoCheck(t, cache, customConfig)
|
||||
require.Error(t, err)
|
||||
require.True(t, strings.Contains(err.Error(), fmt.Sprintf("native %s: version mismatch (stored contract state differs from autogenerated one)", nativenames.CryptoLib)))
|
||||
})
|
||||
|
||||
t.Run("good", func(t *testing.T) {
|
||||
ps = newPS(t)
|
||||
_, err := initTestChainNoCheck(t, ps, customConfig)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
iocore "io"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
|
@ -513,18 +514,20 @@ func (dao *Simple) GetStateSyncCurrentBlockHeight() (uint32, error) {
|
|||
func (dao *Simple) GetHeaderHashes() ([]util.Uint256, error) {
|
||||
var hashes = make([]util.Uint256, 0)
|
||||
|
||||
var seekErr error
|
||||
dao.Store.Seek(storage.SeekRange{
|
||||
Prefix: dao.mkKeyPrefix(storage.IXHeaderHashList),
|
||||
}, func(k, v []byte) bool {
|
||||
newHashes, err := read2000Uint256Hashes(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
seekErr = fmt.Errorf("failed to read batch of 2000 header hashes: %w", err)
|
||||
return false
|
||||
}
|
||||
hashes = append(hashes, newHashes...)
|
||||
return true
|
||||
})
|
||||
|
||||
return hashes, nil
|
||||
return hashes, seekErr
|
||||
}
|
||||
|
||||
// GetTransaction returns Transaction and its height by the given hash
|
||||
|
|
|
@ -68,27 +68,44 @@ func newTestChainWithCustomCfgAndStore(t testing.TB, st storage.Store, f func(*c
|
|||
}
|
||||
|
||||
func newLevelDBForTesting(t testing.TB) storage.Store {
|
||||
ldbDir := t.TempDir()
|
||||
dbConfig := storage.DBConfiguration{
|
||||
Type: "leveldb",
|
||||
LevelDBOptions: storage.LevelDBOptions{
|
||||
DataDirectoryPath: ldbDir,
|
||||
},
|
||||
}
|
||||
newLevelStore, err := storage.NewLevelDBStore(dbConfig.LevelDBOptions)
|
||||
require.Nil(t, err, "NewLevelDBStore error")
|
||||
newLevelStore, _ := newLevelDBForTestingWithPath(t, "")
|
||||
return newLevelStore
|
||||
}
|
||||
|
||||
func newLevelDBForTestingWithPath(t testing.TB, dbPath string) (storage.Store, string) {
|
||||
if dbPath == "" {
|
||||
dbPath = t.TempDir()
|
||||
}
|
||||
dbOptions := storage.LevelDBOptions{
|
||||
DataDirectoryPath: dbPath,
|
||||
}
|
||||
newLevelStore, err := storage.NewLevelDBStore(dbOptions)
|
||||
require.Nil(t, err, "NewLevelDBStore error")
|
||||
return newLevelStore, dbPath
|
||||
}
|
||||
|
||||
func newBoltStoreForTesting(t testing.TB) storage.Store {
|
||||
d := t.TempDir()
|
||||
testFileName := filepath.Join(d, "test_bolt_db")
|
||||
boltDBStore, err := storage.NewBoltDBStore(storage.BoltDBOptions{FilePath: testFileName})
|
||||
require.NoError(t, err)
|
||||
boltDBStore, _ := newBoltStoreForTestingWithPath(t, "")
|
||||
return boltDBStore
|
||||
}
|
||||
|
||||
func newBoltStoreForTestingWithPath(t testing.TB, dbPath string) (storage.Store, string) {
|
||||
if dbPath == "" {
|
||||
d := t.TempDir()
|
||||
dbPath = filepath.Join(d, "test_bolt_db")
|
||||
}
|
||||
boltDBStore, err := storage.NewBoltDBStore(storage.BoltDBOptions{FilePath: dbPath})
|
||||
require.NoError(t, err)
|
||||
return boltDBStore, dbPath
|
||||
}
|
||||
|
||||
func initTestChain(t testing.TB, st storage.Store, f func(*config.Config)) *Blockchain {
|
||||
chain, err := initTestChainNoCheck(t, st, f)
|
||||
require.NoError(t, err)
|
||||
return chain
|
||||
}
|
||||
|
||||
func initTestChainNoCheck(t testing.TB, st storage.Store, f func(*config.Config)) (*Blockchain, error) {
|
||||
unitTestNetCfg, err := config.Load("../../config", testchain.Network())
|
||||
require.NoError(t, err)
|
||||
if f != nil {
|
||||
|
@ -101,9 +118,7 @@ func initTestChain(t testing.TB, st storage.Store, f func(*config.Config)) *Bloc
|
|||
if _, ok := t.(*testing.B); ok {
|
||||
log = zap.NewNop()
|
||||
}
|
||||
chain, err := NewBlockchain(st, unitTestNetCfg.ProtocolConfiguration, log)
|
||||
require.NoError(t, err)
|
||||
return chain
|
||||
return NewBlockchain(st, unitTestNetCfg.ProtocolConfiguration, log)
|
||||
}
|
||||
|
||||
func (bc *Blockchain) newBlock(txs ...*transaction.Transaction) *block.Block {
|
||||
|
|
Loading…
Reference in a new issue