github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/internal/fakechain/fakechain.go (about)

     1  package fakechain
     2  
     3  import (
     4  	"errors"
     5  	"math/big"
     6  	"sync/atomic"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/config"
     9  	"github.com/nspcc-dev/neo-go/pkg/config/netmode"
    10  	"github.com/nspcc-dev/neo-go/pkg/core/block"
    11  	"github.com/nspcc-dev/neo-go/pkg/core/interop"
    12  	"github.com/nspcc-dev/neo-go/pkg/core/mempool"
    13  	"github.com/nspcc-dev/neo-go/pkg/core/mpt"
    14  	"github.com/nspcc-dev/neo-go/pkg/core/native"
    15  	"github.com/nspcc-dev/neo-go/pkg/core/state"
    16  	"github.com/nspcc-dev/neo-go/pkg/core/transaction"
    17  	"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
    18  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    19  	"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
    20  	"github.com/nspcc-dev/neo-go/pkg/util"
    21  )
    22  
    23  // FakeChain implements the Blockchainer interface, but does not provide real functionality.
    24  type FakeChain struct {
    25  	config.Blockchain
    26  	*mempool.Pool
    27  	blocksCh                 []chan *block.Block
    28  	Blockheight              atomic.Uint32
    29  	PoolTxF                  func(*transaction.Transaction) error
    30  	poolTxWithData           func(*transaction.Transaction, any, *mempool.Pool) error
    31  	blocks                   map[util.Uint256]*block.Block
    32  	hdrHashes                map[uint32]util.Uint256
    33  	txs                      map[util.Uint256]*transaction.Transaction
    34  	VerifyWitnessF           func() (int64, error)
    35  	MaxVerificationGAS       int64
    36  	NotaryContractScriptHash util.Uint160
    37  	NotaryDepositExpiration  uint32
    38  	PostBlock                []func(func(*transaction.Transaction, *mempool.Pool, bool) bool, *mempool.Pool, *block.Block)
    39  	UtilityTokenBalance      *big.Int
    40  }
    41  
    42  // FakeStateSync implements the StateSync interface.
    43  type FakeStateSync struct {
    44  	IsActiveFlag      atomic.Bool
    45  	IsInitializedFlag atomic.Bool
    46  	RequestHeaders    atomic.Bool
    47  	InitFunc          func(h uint32) error
    48  	TraverseFunc      func(root util.Uint256, process func(node mpt.Node, nodeBytes []byte) bool) error
    49  	AddMPTNodesFunc   func(nodes [][]byte) error
    50  }
    51  
    52  // NewFakeChain returns a new FakeChain structure.
    53  func NewFakeChain() *FakeChain {
    54  	return NewFakeChainWithCustomCfg(nil)
    55  }
    56  
    57  // NewFakeChainWithCustomCfg returns a new FakeChain structure with the specified protocol configuration.
    58  func NewFakeChainWithCustomCfg(protocolCfg func(c *config.Blockchain)) *FakeChain {
    59  	cfg := config.Blockchain{ProtocolConfiguration: config.ProtocolConfiguration{Magic: netmode.UnitTestNet, P2PNotaryRequestPayloadPoolSize: 10}}
    60  	if protocolCfg != nil {
    61  		protocolCfg(&cfg)
    62  	}
    63  	return &FakeChain{
    64  		Pool:           mempool.New(10, 0, false, nil),
    65  		PoolTxF:        func(*transaction.Transaction) error { return nil },
    66  		poolTxWithData: func(*transaction.Transaction, any, *mempool.Pool) error { return nil },
    67  		blocks:         make(map[util.Uint256]*block.Block),
    68  		hdrHashes:      make(map[uint32]util.Uint256),
    69  		txs:            make(map[util.Uint256]*transaction.Transaction),
    70  		Blockchain:     cfg,
    71  	}
    72  }
    73  
    74  // PutBlock implements the Blockchainer interface.
    75  func (chain *FakeChain) PutBlock(b *block.Block) {
    76  	chain.blocks[b.Hash()] = b
    77  	chain.hdrHashes[b.Index] = b.Hash()
    78  	chain.Blockheight.Store(b.Index)
    79  }
    80  
    81  // PutHeader implements the Blockchainer interface.
    82  func (chain *FakeChain) PutHeader(b *block.Block) {
    83  	chain.hdrHashes[b.Index] = b.Hash()
    84  }
    85  
    86  // PutTx implements the Blockchainer interface.
    87  func (chain *FakeChain) PutTx(tx *transaction.Transaction) {
    88  	chain.txs[tx.Hash()] = tx
    89  }
    90  
    91  // InitVerificationContext initializes context for witness check.
    92  func (chain *FakeChain) InitVerificationContext(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error {
    93  	panic("TODO")
    94  }
    95  
    96  // IsExtensibleAllowed implements the Blockchainer interface.
    97  func (*FakeChain) IsExtensibleAllowed(uint160 util.Uint160) bool {
    98  	return true
    99  }
   100  
   101  // GetNatives implements the blockchainer.Blockchainer interface.
   102  func (*FakeChain) GetNatives() []state.Contract {
   103  	panic("TODO")
   104  }
   105  
   106  // GetNotaryDepositExpiration implements the Blockchainer interface.
   107  func (chain *FakeChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 {
   108  	if chain.NotaryDepositExpiration != 0 {
   109  		return chain.NotaryDepositExpiration
   110  	}
   111  	panic("TODO")
   112  }
   113  
   114  // GetNotaryContractScriptHash implements the Blockchainer interface.
   115  func (chain *FakeChain) GetNotaryContractScriptHash() util.Uint160 {
   116  	if !chain.NotaryContractScriptHash.Equals(util.Uint160{}) {
   117  		return chain.NotaryContractScriptHash
   118  	}
   119  	panic("TODO")
   120  }
   121  
   122  // GetNotaryBalance implements the Blockchainer interface.
   123  func (chain *FakeChain) GetNotaryBalance(acc util.Uint160) *big.Int {
   124  	panic("TODO")
   125  }
   126  
   127  // GetNotaryServiceFeePerKey implements the Blockchainer interface.
   128  func (chain *FakeChain) GetNotaryServiceFeePerKey() int64 {
   129  	panic("TODO")
   130  }
   131  
   132  // GetBaseExecFee implements the Policer interface.
   133  func (chain *FakeChain) GetBaseExecFee() int64 {
   134  	return interop.DefaultBaseExecFee
   135  }
   136  
   137  // GetStoragePrice implements the Policer interface.
   138  func (chain *FakeChain) GetStoragePrice() int64 {
   139  	return native.DefaultStoragePrice
   140  }
   141  
   142  // GetMaxVerificationGAS implements the Policer interface.
   143  func (chain *FakeChain) GetMaxVerificationGAS() int64 {
   144  	if chain.MaxVerificationGAS != 0 {
   145  		return chain.MaxVerificationGAS
   146  	}
   147  	panic("TODO")
   148  }
   149  
   150  // PoolTxWithData implements the Blockchainer interface.
   151  func (chain *FakeChain) PoolTxWithData(t *transaction.Transaction, data any, mp *mempool.Pool, feer mempool.Feer, verificationFunction func(t *transaction.Transaction, data any) error) error {
   152  	return chain.poolTxWithData(t, data, mp)
   153  }
   154  
   155  // RegisterPostBlock implements the Blockchainer interface.
   156  func (chain *FakeChain) RegisterPostBlock(f func(func(*transaction.Transaction, *mempool.Pool, bool) bool, *mempool.Pool, *block.Block)) {
   157  	chain.PostBlock = append(chain.PostBlock, f)
   158  }
   159  
   160  // GetConfig implements the Blockchainer interface.
   161  func (chain *FakeChain) GetConfig() config.Blockchain {
   162  	return chain.Blockchain
   163  }
   164  
   165  // CalculateClaimable implements the Blockchainer interface.
   166  func (chain *FakeChain) CalculateClaimable(util.Uint160, uint32) (*big.Int, error) {
   167  	panic("TODO")
   168  }
   169  
   170  // FeePerByte implements Feer interface.
   171  func (chain *FakeChain) FeePerByte() int64 {
   172  	panic("TODO")
   173  }
   174  
   175  // P2PSigExtensionsEnabled implements Feer interface.
   176  func (chain *FakeChain) P2PSigExtensionsEnabled() bool {
   177  	return true
   178  }
   179  
   180  // AddHeaders implements the Blockchainer interface.
   181  func (chain *FakeChain) AddHeaders(...*block.Header) error {
   182  	panic("TODO")
   183  }
   184  
   185  // AddBlock implements the Blockchainer interface.
   186  func (chain *FakeChain) AddBlock(block *block.Block) error {
   187  	if block.Index == chain.Blockheight.Load()+1 {
   188  		chain.PutBlock(block)
   189  	}
   190  	return nil
   191  }
   192  
   193  // BlockHeight implements the Feer interface.
   194  func (chain *FakeChain) BlockHeight() uint32 {
   195  	return chain.Blockheight.Load()
   196  }
   197  
   198  // HeaderHeight implements the Blockchainer interface.
   199  func (chain *FakeChain) HeaderHeight() uint32 {
   200  	return chain.Blockheight.Load()
   201  }
   202  
   203  // GetAppExecResults implements the Blockchainer interface.
   204  func (chain *FakeChain) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([]state.AppExecResult, error) {
   205  	panic("TODO")
   206  }
   207  
   208  // GetBlock implements the Blockchainer interface.
   209  func (chain *FakeChain) GetBlock(hash util.Uint256) (*block.Block, error) {
   210  	if b, ok := chain.blocks[hash]; ok {
   211  		return b, nil
   212  	}
   213  	return nil, errors.New("not found")
   214  }
   215  
   216  // GetCommittee implements the Blockchainer interface.
   217  func (chain *FakeChain) GetCommittee() (keys.PublicKeys, error) {
   218  	panic("TODO")
   219  }
   220  
   221  // GetContractState implements the Blockchainer interface.
   222  func (chain *FakeChain) GetContractState(hash util.Uint160) *state.Contract {
   223  	panic("TODO")
   224  }
   225  
   226  // GetContractScriptHash implements the Blockchainer interface.
   227  func (chain *FakeChain) GetContractScriptHash(id int32) (util.Uint160, error) {
   228  	panic("TODO")
   229  }
   230  
   231  // GetNativeContractScriptHash implements the Blockchainer interface.
   232  func (chain *FakeChain) GetNativeContractScriptHash(name string) (util.Uint160, error) {
   233  	panic("TODO")
   234  }
   235  
   236  // GetHeaderHash implements the Blockchainer interface.
   237  func (chain *FakeChain) GetHeaderHash(n uint32) util.Uint256 {
   238  	return chain.hdrHashes[n]
   239  }
   240  
   241  // GetHeader implements the Blockchainer interface.
   242  func (chain *FakeChain) GetHeader(hash util.Uint256) (*block.Header, error) {
   243  	b, err := chain.GetBlock(hash)
   244  	if err != nil {
   245  		return nil, err
   246  	}
   247  	return &b.Header, nil
   248  }
   249  
   250  // GetNextBlockValidators implements the Blockchainer interface.
   251  func (chain *FakeChain) GetNextBlockValidators() ([]*keys.PublicKey, error) {
   252  	panic("TODO")
   253  }
   254  
   255  // GetNEP17Contracts implements the Blockchainer interface.
   256  func (chain *FakeChain) GetNEP11Contracts() []util.Uint160 {
   257  	panic("TODO")
   258  }
   259  
   260  // GetNEP17Contracts implements the Blockchainer interface.
   261  func (chain *FakeChain) GetNEP17Contracts() []util.Uint160 {
   262  	panic("TODO")
   263  }
   264  
   265  // GetNEP17LastUpdated implements the Blockchainer interface.
   266  func (chain *FakeChain) GetTokenLastUpdated(acc util.Uint160) (map[int32]uint32, error) {
   267  	panic("TODO")
   268  }
   269  
   270  // ForEachNEP17Transfer implements the Blockchainer interface.
   271  func (chain *FakeChain) ForEachNEP11Transfer(util.Uint160, uint64, func(*state.NEP11Transfer) (bool, error)) error {
   272  	panic("TODO")
   273  }
   274  
   275  // ForEachNEP17Transfer implements the Blockchainer interface.
   276  func (chain *FakeChain) ForEachNEP17Transfer(util.Uint160, uint64, func(*state.NEP17Transfer) (bool, error)) error {
   277  	panic("TODO")
   278  }
   279  
   280  // GetValidators implements the Blockchainer interface.
   281  func (chain *FakeChain) GetValidators() ([]*keys.PublicKey, error) {
   282  	panic("TODO")
   283  }
   284  
   285  // GetEnrollments implements the Blockchainer interface.
   286  func (chain *FakeChain) GetEnrollments() ([]state.Validator, error) {
   287  	panic("TODO")
   288  }
   289  
   290  // GetStorageItem implements the Blockchainer interface.
   291  func (chain *FakeChain) GetStorageItem(id int32, key []byte) state.StorageItem {
   292  	panic("TODO")
   293  }
   294  
   295  // GetTestVM implements the Blockchainer interface.
   296  func (chain *FakeChain) GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) (*interop.Context, error) {
   297  	panic("TODO")
   298  }
   299  
   300  // CurrentBlockHash implements the Blockchainer interface.
   301  func (chain *FakeChain) CurrentBlockHash() util.Uint256 {
   302  	return util.Uint256{}
   303  }
   304  
   305  // HasBlock implements the Blockchainer interface.
   306  func (chain *FakeChain) HasBlock(h util.Uint256) bool {
   307  	_, ok := chain.blocks[h]
   308  	return ok
   309  }
   310  
   311  // HasTransaction implements the Blockchainer interface.
   312  func (chain *FakeChain) HasTransaction(h util.Uint256) bool {
   313  	_, ok := chain.txs[h]
   314  	return ok
   315  }
   316  
   317  // GetTransaction implements the Blockchainer interface.
   318  func (chain *FakeChain) GetTransaction(h util.Uint256) (*transaction.Transaction, uint32, error) {
   319  	if tx, ok := chain.txs[h]; ok {
   320  		return tx, 1, nil
   321  	}
   322  	return nil, 0, errors.New("not found")
   323  }
   324  
   325  // GetMemPool implements the Blockchainer interface.
   326  func (chain *FakeChain) GetMemPool() *mempool.Pool {
   327  	return chain.Pool
   328  }
   329  
   330  // GetGoverningTokenBalance implements the Blockchainer interface.
   331  func (chain *FakeChain) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint32) {
   332  	panic("TODO")
   333  }
   334  
   335  // GetUtilityTokenBalance implements Feer interface.
   336  func (chain *FakeChain) GetUtilityTokenBalance(uint160 util.Uint160) *big.Int {
   337  	if chain.UtilityTokenBalance != nil {
   338  		return chain.UtilityTokenBalance
   339  	}
   340  	panic("TODO")
   341  }
   342  
   343  // PoolTx implements the Blockchainer interface.
   344  func (chain *FakeChain) PoolTx(tx *transaction.Transaction, _ ...*mempool.Pool) error {
   345  	return chain.PoolTxF(tx)
   346  }
   347  
   348  // SubscribeForBlocks implements the Blockchainer interface.
   349  func (chain *FakeChain) SubscribeForBlocks(ch chan *block.Block) {
   350  	chain.blocksCh = append(chain.blocksCh, ch)
   351  }
   352  
   353  // SubscribeForExecutions implements the Blockchainer interface.
   354  func (chain *FakeChain) SubscribeForExecutions(ch chan *state.AppExecResult) {
   355  	panic("TODO")
   356  }
   357  
   358  // SubscribeForNotifications implements the Blockchainer interface.
   359  func (chain *FakeChain) SubscribeForNotifications(ch chan *state.ContainedNotificationEvent) {
   360  	panic("TODO")
   361  }
   362  
   363  // SubscribeForTransactions implements the Blockchainer interface.
   364  func (chain *FakeChain) SubscribeForTransactions(ch chan *transaction.Transaction) {
   365  	panic("TODO")
   366  }
   367  
   368  // VerifyTx implements the Blockchainer interface.
   369  func (chain *FakeChain) VerifyTx(*transaction.Transaction) error {
   370  	panic("TODO")
   371  }
   372  
   373  // VerifyWitness implements the Blockchainer interface.
   374  func (chain *FakeChain) VerifyWitness(util.Uint160, hash.Hashable, *transaction.Witness, int64) (int64, error) {
   375  	if chain.VerifyWitnessF != nil {
   376  		return chain.VerifyWitnessF()
   377  	}
   378  	panic("TODO")
   379  }
   380  
   381  // UnsubscribeFromBlocks implements the Blockchainer interface.
   382  func (chain *FakeChain) UnsubscribeFromBlocks(ch chan *block.Block) {
   383  	for i, c := range chain.blocksCh {
   384  		if c == ch {
   385  			if i < len(chain.blocksCh) {
   386  				copy(chain.blocksCh[i:], chain.blocksCh[i+1:])
   387  			}
   388  			chain.blocksCh = chain.blocksCh[:len(chain.blocksCh)]
   389  		}
   390  	}
   391  }
   392  
   393  // UnsubscribeFromExecutions implements the Blockchainer interface.
   394  func (chain *FakeChain) UnsubscribeFromExecutions(ch chan *state.AppExecResult) {
   395  	panic("TODO")
   396  }
   397  
   398  // UnsubscribeFromNotifications implements the Blockchainer interface.
   399  func (chain *FakeChain) UnsubscribeFromNotifications(ch chan *state.ContainedNotificationEvent) {
   400  	panic("TODO")
   401  }
   402  
   403  // UnsubscribeFromTransactions implements the Blockchainer interface.
   404  func (chain *FakeChain) UnsubscribeFromTransactions(ch chan *transaction.Transaction) {
   405  	panic("TODO")
   406  }
   407  
   408  // AddBlock implements the StateSync interface.
   409  func (s *FakeStateSync) AddBlock(block *block.Block) error {
   410  	panic("TODO")
   411  }
   412  
   413  // AddHeaders implements the StateSync interface.
   414  func (s *FakeStateSync) AddHeaders(...*block.Header) error {
   415  	panic("TODO")
   416  }
   417  
   418  // AddMPTNodes implements the StateSync interface.
   419  func (s *FakeStateSync) AddMPTNodes(nodes [][]byte) error {
   420  	if s.AddMPTNodesFunc != nil {
   421  		return s.AddMPTNodesFunc(nodes)
   422  	}
   423  	panic("TODO")
   424  }
   425  
   426  // BlockHeight implements the StateSync interface.
   427  func (s *FakeStateSync) BlockHeight() uint32 {
   428  	return 0
   429  }
   430  
   431  // IsActive implements the StateSync interface.
   432  func (s *FakeStateSync) IsActive() bool { return s.IsActiveFlag.Load() }
   433  
   434  // IsInitialized implements the StateSync interface.
   435  func (s *FakeStateSync) IsInitialized() bool {
   436  	return s.IsInitializedFlag.Load()
   437  }
   438  
   439  // Init implements the StateSync interface.
   440  func (s *FakeStateSync) Init(currChainHeight uint32) error {
   441  	if s.InitFunc != nil {
   442  		return s.InitFunc(currChainHeight)
   443  	}
   444  	panic("TODO")
   445  }
   446  
   447  // NeedHeaders implements the StateSync interface.
   448  func (s *FakeStateSync) NeedHeaders() bool { return s.RequestHeaders.Load() }
   449  
   450  // NeedMPTNodes implements the StateSync interface.
   451  func (s *FakeStateSync) NeedMPTNodes() bool {
   452  	panic("TODO")
   453  }
   454  
   455  // Traverse implements the StateSync interface.
   456  func (s *FakeStateSync) Traverse(root util.Uint256, process func(node mpt.Node, nodeBytes []byte) bool) error {
   457  	if s.TraverseFunc != nil {
   458  		return s.TraverseFunc(root, process)
   459  	}
   460  	panic("TODO")
   461  }
   462  
   463  // GetUnknownMPTNodesBatch implements the StateSync interface.
   464  func (s *FakeStateSync) GetUnknownMPTNodesBatch(limit int) []util.Uint256 {
   465  	panic("TODO")
   466  }