github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/helper_test.go (about)

     1  package core
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/nspcc-dev/neo-go/internal/testchain"
     8  	"github.com/nspcc-dev/neo-go/pkg/config"
     9  	"github.com/nspcc-dev/neo-go/pkg/core/block"
    10  	"github.com/nspcc-dev/neo-go/pkg/core/storage"
    11  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    12  	"github.com/nspcc-dev/neo-go/pkg/smartcontract"
    13  	"github.com/nspcc-dev/neo-go/pkg/util"
    14  	"github.com/stretchr/testify/require"
    15  	"go.uber.org/zap"
    16  	"go.uber.org/zap/zaptest"
    17  )
    18  
    19  // newTestChain should be called before newBlock invocation to properly setup
    20  // global state.
    21  func newTestChain(t testing.TB) *Blockchain {
    22  	return newTestChainWithCustomCfg(t, nil)
    23  }
    24  
    25  func newTestChainWithCustomCfg(t testing.TB, f func(*config.Config)) *Blockchain {
    26  	return newTestChainWithCustomCfgAndStore(t, nil, f)
    27  }
    28  
    29  func newTestChainWithCustomCfgAndStore(t testing.TB, st storage.Store, f func(*config.Config)) *Blockchain {
    30  	chain := initTestChain(t, st, f)
    31  	go chain.Run()
    32  	t.Cleanup(chain.Close)
    33  	return chain
    34  }
    35  
    36  func initTestChain(t testing.TB, st storage.Store, f func(*config.Config)) *Blockchain {
    37  	chain, err := initTestChainNoCheck(t, st, f)
    38  	require.NoError(t, err)
    39  	return chain
    40  }
    41  
    42  func initTestChainNoCheck(t testing.TB, st storage.Store, f func(*config.Config)) (*Blockchain, error) {
    43  	unitTestNetCfg, err := config.Load("../../config", testchain.Network())
    44  	require.NoError(t, err)
    45  	if f != nil {
    46  		f(&unitTestNetCfg)
    47  	}
    48  	if st == nil {
    49  		st = storage.NewMemoryStore()
    50  	}
    51  	log := zaptest.NewLogger(t)
    52  	if _, ok := t.(*testing.B); ok {
    53  		log = zap.NewNop()
    54  	}
    55  	return NewBlockchain(st, unitTestNetCfg.Blockchain(), log)
    56  }
    57  
    58  func (bc *Blockchain) newBlock(txs ...*transaction.Transaction) *block.Block {
    59  	lastBlock, ok := bc.topBlock.Load().(*block.Block)
    60  	if !ok {
    61  		var err error
    62  		lastBlock, err = bc.GetBlock(bc.GetHeaderHash(bc.BlockHeight()))
    63  		if err != nil {
    64  			panic(err)
    65  		}
    66  	}
    67  	if bc.config.StateRootInHeader {
    68  		sr, err := bc.GetStateModule().GetStateRoot(bc.BlockHeight())
    69  		if err != nil {
    70  			panic(err)
    71  		}
    72  		return newBlockWithState(bc.config.ProtocolConfiguration, lastBlock.Index+1, lastBlock.Hash(), &sr.Root, txs...)
    73  	}
    74  	return newBlock(bc.config.ProtocolConfiguration, lastBlock.Index+1, lastBlock.Hash(), txs...)
    75  }
    76  
    77  func newBlock(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256, txs ...*transaction.Transaction) *block.Block {
    78  	return newBlockWithState(cfg, index, prev, nil, txs...)
    79  }
    80  
    81  func newBlockCustom(cfg config.ProtocolConfiguration, f func(b *block.Block),
    82  	txs ...*transaction.Transaction) *block.Block {
    83  	validators, _, _ := validatorsFromConfig(cfg)
    84  	valScript, _ := smartcontract.CreateDefaultMultiSigRedeemScript(validators)
    85  	witness := transaction.Witness{
    86  		VerificationScript: valScript,
    87  	}
    88  	b := &block.Block{
    89  		Header: block.Header{
    90  			NextConsensus: witness.ScriptHash(),
    91  			Script:        witness,
    92  		},
    93  		Transactions: txs,
    94  	}
    95  	f(b)
    96  
    97  	b.RebuildMerkleRoot()
    98  	b.Script.InvocationScript = testchain.Sign(b)
    99  	return b
   100  }
   101  
   102  func newBlockWithState(cfg config.ProtocolConfiguration, index uint32, prev util.Uint256,
   103  	prevState *util.Uint256, txs ...*transaction.Transaction) *block.Block {
   104  	return newBlockCustom(cfg, func(b *block.Block) {
   105  		b.PrevHash = prev
   106  		b.Timestamp = uint64(time.Now().UTC().Unix())*1000 + uint64(index)
   107  		b.Index = index
   108  
   109  		if prevState != nil {
   110  			b.StateRootEnabled = true
   111  			b.PrevStateRoot = *prevState
   112  		}
   113  	}, txs...)
   114  }
   115  
   116  func (bc *Blockchain) genBlocks(n int) ([]*block.Block, error) {
   117  	blocks := make([]*block.Block, n)
   118  	lastHash := bc.topBlock.Load().(*block.Block).Hash()
   119  	lastIndex := bc.topBlock.Load().(*block.Block).Index
   120  	for i := 0; i < n; i++ {
   121  		blocks[i] = newBlock(bc.config.ProtocolConfiguration, uint32(i)+lastIndex+1, lastHash)
   122  		if err := bc.AddBlock(blocks[i]); err != nil {
   123  			return blocks, err
   124  		}
   125  		lastHash = blocks[i].Hash()
   126  	}
   127  	return blocks, nil
   128  }