From 4ad9c7929b927e17ea356e1bf05cf68339bf6882 Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Mon, 1 Feb 2021 13:50:08 +0300 Subject: [PATCH] internals: move testchain from network to internals It'll be useful for tests outside of the network pkg. --- internal/fakechain/fakechain.go | 438 ++++++++++++++++++++++++++++++++ pkg/network/blockqueue_test.go | 3 +- pkg/network/helper_test.go | 318 +---------------------- pkg/network/server_test.go | 53 ++-- 4 files changed, 469 insertions(+), 343 deletions(-) create mode 100644 internal/fakechain/fakechain.go diff --git a/internal/fakechain/fakechain.go b/internal/fakechain/fakechain.go new file mode 100644 index 000000000..3b79ebc8b --- /dev/null +++ b/internal/fakechain/fakechain.go @@ -0,0 +1,438 @@ +package fakechain + +import ( + "errors" + "math/big" + "sync/atomic" + + "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/nspcc-dev/neo-go/pkg/core/block" + "github.com/nspcc-dev/neo-go/pkg/core/blockchainer" + "github.com/nspcc-dev/neo-go/pkg/core/blockchainer/services" + "github.com/nspcc-dev/neo-go/pkg/core/interop" + "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/state" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/crypto" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm" +) + +// FakeChain implements Blockchainer interface, but does not provide real functionality. +type FakeChain struct { + config.ProtocolConfiguration + *mempool.Pool + blocksCh []chan<- *block.Block + Blockheight uint32 + PoolTxF func(*transaction.Transaction) error + poolTxWithData func(*transaction.Transaction, interface{}, *mempool.Pool) error + blocks map[util.Uint256]*block.Block + hdrHashes map[uint32]util.Uint256 + txs map[util.Uint256]*transaction.Transaction + VerifyWitnessF func() error + MaxVerificationGAS int64 + NotaryContractScriptHash util.Uint160 + NotaryDepositExpiration uint32 + PostBlock []func(blockchainer.Blockchainer, *mempool.Pool, *block.Block) + UtilityTokenBalance *big.Int +} + +// NewFakeChain returns new FakeChain structure. +func NewFakeChain() *FakeChain { + return &FakeChain{ + Pool: mempool.New(10, 0, false), + PoolTxF: func(*transaction.Transaction) error { return nil }, + poolTxWithData: func(*transaction.Transaction, interface{}, *mempool.Pool) error { return nil }, + blocks: make(map[util.Uint256]*block.Block), + hdrHashes: make(map[uint32]util.Uint256), + txs: make(map[util.Uint256]*transaction.Transaction), + ProtocolConfiguration: config.ProtocolConfiguration{P2PNotaryRequestPayloadPoolSize: 10}, + } +} + +// PutBlock implements Blockchainer interface. +func (chain *FakeChain) PutBlock(b *block.Block) { + chain.blocks[b.Hash()] = b + chain.hdrHashes[b.Index] = b.Hash() + atomic.StoreUint32(&chain.Blockheight, b.Index) +} + +// PutHeader implements Blockchainer interface. +func (chain *FakeChain) PutHeader(b *block.Block) { + chain.hdrHashes[b.Index] = b.Hash() +} + +// PutTx implements Blockchainer interface. +func (chain *FakeChain) PutTx(tx *transaction.Transaction) { + chain.txs[tx.Hash()] = tx +} + +// ApplyPolicyToTxSet implements Blockchainer interface. +func (chain *FakeChain) ApplyPolicyToTxSet([]*transaction.Transaction) []*transaction.Transaction { + panic("TODO") +} + +// IsTxStillRelevant implements Blockchainer interface. +func (chain *FakeChain) IsTxStillRelevant(t *transaction.Transaction, txpool *mempool.Pool, isPartialTx bool) bool { + panic("TODO") +} + +// IsExtensibleAllowed implements Blockchainer interface. +func (*FakeChain) IsExtensibleAllowed(uint160 util.Uint160) bool { + return true +} + +// GetNotaryDepositExpiration implements Blockchainer interface. +func (chain *FakeChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 { + if chain.NotaryDepositExpiration != 0 { + return chain.NotaryDepositExpiration + } + panic("TODO") +} + +// GetNotaryContractScriptHash implements Blockchainer interface. +func (chain *FakeChain) GetNotaryContractScriptHash() util.Uint160 { + if !chain.NotaryContractScriptHash.Equals(util.Uint160{}) { + return chain.NotaryContractScriptHash + } + panic("TODO") +} + +// GetNotaryBalance implements Blockchainer interface. +func (chain *FakeChain) GetNotaryBalance(acc util.Uint160) *big.Int { + panic("TODO") +} + +// GetPolicer implements Blockchainer interface. +func (chain *FakeChain) GetPolicer() blockchainer.Policer { + return chain +} + +// GetBaseExecFee implements Policer interface. +func (chain *FakeChain) GetBaseExecFee() int64 { + return interop.DefaultBaseExecFee +} + +// GetStoragePrice implements Policer interface. +func (chain *FakeChain) GetStoragePrice() int64 { + return native.StoragePrice +} + +// GetMaxVerificationGAS implements Policer interface. +func (chain *FakeChain) GetMaxVerificationGAS() int64 { + if chain.MaxVerificationGAS != 0 { + return chain.MaxVerificationGAS + } + panic("TODO") +} + +// PoolTxWithData implements Blockchainer interface. +func (chain *FakeChain) PoolTxWithData(t *transaction.Transaction, data interface{}, mp *mempool.Pool, feer mempool.Feer, verificationFunction func(bc blockchainer.Blockchainer, t *transaction.Transaction, data interface{}) error) error { + return chain.poolTxWithData(t, data, mp) +} + +// RegisterPostBlock implements Blockchainer interface. +func (chain *FakeChain) RegisterPostBlock(f func(blockchainer.Blockchainer, *mempool.Pool, *block.Block)) { + chain.PostBlock = append(chain.PostBlock, f) +} + +// GetConfig implements Blockchainer interface. +func (chain *FakeChain) GetConfig() config.ProtocolConfiguration { + return chain.ProtocolConfiguration +} + +// CalculateClaimable implements Blockchainer interface. +func (chain *FakeChain) CalculateClaimable(util.Uint160, uint32) (*big.Int, error) { + panic("TODO") +} + +// FeePerByte implements Feer interface. +func (chain *FakeChain) FeePerByte() int64 { + panic("TODO") +} + +// P2PSigExtensionsEnabled implements Feer interface. +func (chain *FakeChain) P2PSigExtensionsEnabled() bool { + return true +} + +// GetMaxBlockSystemFee implements Policer interface. +func (chain *FakeChain) GetMaxBlockSystemFee() int64 { + panic("TODO") +} + +// GetMaxBlockSize implements Policer interface. +func (chain *FakeChain) GetMaxBlockSize() uint32 { + panic("TODO") +} + +// AddHeaders implements Blockchainer interface. +func (chain *FakeChain) AddHeaders(...*block.Header) error { + panic("TODO") +} + +// AddBlock implements Blockchainer interface. +func (chain *FakeChain) AddBlock(block *block.Block) error { + if block.Index == atomic.LoadUint32(&chain.Blockheight)+1 { + chain.PutBlock(block) + } + return nil +} + +// AddStateRoot implements Blockchainer interface. +func (chain *FakeChain) AddStateRoot(r *state.MPTRoot) error { + panic("TODO") +} + +// BlockHeight implements Feer interface. +func (chain *FakeChain) BlockHeight() uint32 { + return atomic.LoadUint32(&chain.Blockheight) +} + +// Close implements Blockchainer interface. +func (chain *FakeChain) Close() { + panic("TODO") +} + +// HeaderHeight implements Blockchainer interface. +func (chain *FakeChain) HeaderHeight() uint32 { + return atomic.LoadUint32(&chain.Blockheight) +} + +// GetAppExecResults implements Blockchainer interface. +func (chain *FakeChain) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([]state.AppExecResult, error) { + panic("TODO") +} + +// GetBlock implements Blockchainer interface. +func (chain *FakeChain) GetBlock(hash util.Uint256) (*block.Block, error) { + if b, ok := chain.blocks[hash]; ok { + return b, nil + } + return nil, errors.New("not found") +} + +// GetCommittee implements Blockchainer interface. +func (chain *FakeChain) GetCommittee() (keys.PublicKeys, error) { + panic("TODO") +} + +// GetContractState implements Blockchainer interface. +func (chain *FakeChain) GetContractState(hash util.Uint160) *state.Contract { + panic("TODO") +} + +// GetContractScriptHash implements Blockchainer interface. +func (chain *FakeChain) GetContractScriptHash(id int32) (util.Uint160, error) { + panic("TODO") +} + +// GetNativeContractScriptHash implements Blockchainer interface. +func (chain *FakeChain) GetNativeContractScriptHash(name string) (util.Uint160, error) { + panic("TODO") +} + +// GetHeaderHash implements Blockchainer interface. +func (chain *FakeChain) GetHeaderHash(n int) util.Uint256 { + return chain.hdrHashes[uint32(n)] +} + +// GetHeader implements Blockchainer interface. +func (chain *FakeChain) GetHeader(hash util.Uint256) (*block.Header, error) { + b, err := chain.GetBlock(hash) + if err != nil { + return nil, err + } + return b.Header(), nil +} + +// GetNextBlockValidators implements Blockchainer interface. +func (chain *FakeChain) GetNextBlockValidators() ([]*keys.PublicKey, error) { + panic("TODO") +} + +// ForEachNEP17Transfer implements Blockchainer interface. +func (chain *FakeChain) ForEachNEP17Transfer(util.Uint160, func(*state.NEP17Transfer) (bool, error)) error { + panic("TODO") +} + +// GetNEP17Balances implements Blockchainer interface. +func (chain *FakeChain) GetNEP17Balances(util.Uint160) *state.NEP17Balances { + panic("TODO") +} + +// GetValidators implements Blockchainer interface. +func (chain *FakeChain) GetValidators() ([]*keys.PublicKey, error) { + panic("TODO") +} + +// GetStandByCommittee implements Blockchainer interface. +func (chain *FakeChain) GetStandByCommittee() keys.PublicKeys { + panic("TODO") +} + +// GetStandByValidators implements Blockchainer interface. +func (chain *FakeChain) GetStandByValidators() keys.PublicKeys { + panic("TODO") +} + +// GetEnrollments implements Blockchainer interface. +func (chain *FakeChain) GetEnrollments() ([]state.Validator, error) { + panic("TODO") +} + +// GetStateProof implements Blockchainer interface. +func (chain *FakeChain) GetStateProof(util.Uint256, []byte) ([][]byte, error) { + panic("TODO") +} + +// GetStateRoot implements Blockchainer interface. +func (chain *FakeChain) GetStateRoot(height uint32) (*state.MPTRootState, error) { + panic("TODO") +} + +// GetStorageItem implements Blockchainer interface. +func (chain *FakeChain) GetStorageItem(id int32, key []byte) *state.StorageItem { + panic("TODO") +} + +// GetTestVM implements Blockchainer interface. +func (chain *FakeChain) GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *vm.VM { + panic("TODO") +} + +// GetStorageItems implements Blockchainer interface. +func (chain *FakeChain) GetStorageItems(id int32) (map[string]*state.StorageItem, error) { + panic("TODO") +} + +// CurrentHeaderHash implements Blockchainer interface. +func (chain *FakeChain) CurrentHeaderHash() util.Uint256 { + return util.Uint256{} +} + +// CurrentBlockHash implements Blockchainer interface. +func (chain *FakeChain) CurrentBlockHash() util.Uint256 { + return util.Uint256{} +} + +// HasBlock implements Blockchainer interface. +func (chain *FakeChain) HasBlock(h util.Uint256) bool { + _, ok := chain.blocks[h] + return ok +} + +// HasTransaction implements Blockchainer interface. +func (chain *FakeChain) HasTransaction(h util.Uint256) bool { + _, ok := chain.txs[h] + return ok +} + +// GetTransaction implements Blockchainer interface. +func (chain *FakeChain) GetTransaction(h util.Uint256) (*transaction.Transaction, uint32, error) { + if tx, ok := chain.txs[h]; ok { + return tx, 1, nil + } + return nil, 0, errors.New("not found") +} + +// GetMemPool implements Blockchainer interface. +func (chain *FakeChain) GetMemPool() *mempool.Pool { + return chain.Pool +} + +// GetGoverningTokenBalance implements Blockchainer interface. +func (chain *FakeChain) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint32) { + panic("TODO") +} + +// GetUtilityTokenBalance implements Feer interface. +func (chain *FakeChain) GetUtilityTokenBalance(uint160 util.Uint160) *big.Int { + if chain.UtilityTokenBalance != nil { + return chain.UtilityTokenBalance + } + panic("TODO") +} + +// ManagementContractHash implements Blockchainer interface. +func (chain FakeChain) ManagementContractHash() util.Uint160 { + panic("TODO") +} + +// PoolTx implements Blockchainer interface. +func (chain *FakeChain) PoolTx(tx *transaction.Transaction, _ ...*mempool.Pool) error { + return chain.PoolTxF(tx) +} + +// SetOracle implements Blockchainer interface. +func (chain FakeChain) SetOracle(services.Oracle) { + panic("TODO") +} + +// SetNotary implements Blockchainer interface. +func (chain *FakeChain) SetNotary(notary services.Notary) { + panic("TODO") +} + +// SubscribeForBlocks implements Blockchainer interface. +func (chain *FakeChain) SubscribeForBlocks(ch chan<- *block.Block) { + chain.blocksCh = append(chain.blocksCh, ch) +} + +// SubscribeForExecutions implements Blockchainer interface. +func (chain *FakeChain) SubscribeForExecutions(ch chan<- *state.AppExecResult) { + panic("TODO") +} + +// SubscribeForNotifications implements Blockchainer interface. +func (chain *FakeChain) SubscribeForNotifications(ch chan<- *state.NotificationEvent) { + panic("TODO") +} + +// SubscribeForTransactions implements Blockchainer interface. +func (chain *FakeChain) SubscribeForTransactions(ch chan<- *transaction.Transaction) { + panic("TODO") +} + +// VerifyTx implements Blockchainer interface. +func (chain *FakeChain) VerifyTx(*transaction.Transaction) error { + panic("TODO") +} + +// VerifyWitness implements Blockchainer interface. +func (chain *FakeChain) VerifyWitness(util.Uint160, crypto.Verifiable, *transaction.Witness, int64) error { + if chain.VerifyWitnessF != nil { + return chain.VerifyWitnessF() + } + panic("TODO") +} + +// UnsubscribeFromBlocks implements Blockchainer interface. +func (chain *FakeChain) UnsubscribeFromBlocks(ch chan<- *block.Block) { + for i, c := range chain.blocksCh { + if c == ch { + if i < len(chain.blocksCh) { + copy(chain.blocksCh[i:], chain.blocksCh[i+1:]) + } + chain.blocksCh = chain.blocksCh[:len(chain.blocksCh)] + } + } +} + +// UnsubscribeFromExecutions implements Blockchainer interface. +func (chain *FakeChain) UnsubscribeFromExecutions(ch chan<- *state.AppExecResult) { + panic("TODO") +} + +// UnsubscribeFromNotifications implements Blockchainer interface. +func (chain *FakeChain) UnsubscribeFromNotifications(ch chan<- *state.NotificationEvent) { + panic("TODO") +} + +// UnsubscribeFromTransactions implements Blockchainer interface. +func (chain *FakeChain) UnsubscribeFromTransactions(ch chan<- *transaction.Transaction) { + panic("TODO") +} diff --git a/pkg/network/blockqueue_test.go b/pkg/network/blockqueue_test.go index b796cf3f6..cf5a23ed1 100644 --- a/pkg/network/blockqueue_test.go +++ b/pkg/network/blockqueue_test.go @@ -4,13 +4,14 @@ import ( "testing" "time" + "github.com/nspcc-dev/neo-go/internal/fakechain" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/stretchr/testify/assert" "go.uber.org/zap/zaptest" ) func TestBlockQueue(t *testing.T) { - chain := newTestChain() + chain := fakechain.NewFakeChain() // notice, it's not yet running bq := newBlockQueue(0, chain, zaptest.NewLogger(t), nil) blocks := make([]*block.Block, 11) diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index eb4ab9509..e084a3252 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -1,336 +1,22 @@ package network import ( - "errors" "fmt" - "math/big" "net" "sync" "sync/atomic" "testing" "time" - "github.com/nspcc-dev/neo-go/pkg/config" + "github.com/nspcc-dev/neo-go/internal/fakechain" "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/blockchainer" - "github.com/nspcc-dev/neo-go/pkg/core/blockchainer/services" - "github.com/nspcc-dev/neo-go/pkg/core/interop" - "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/state" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/network/capability" "github.com/nspcc-dev/neo-go/pkg/network/payload" - "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) -type testChain struct { - config.ProtocolConfiguration - *mempool.Pool - blocksCh []chan<- *block.Block - blockheight uint32 - poolTx func(*transaction.Transaction) error - poolTxWithData func(*transaction.Transaction, interface{}, *mempool.Pool) error - blocks map[util.Uint256]*block.Block - hdrHashes map[uint32]util.Uint256 - txs map[util.Uint256]*transaction.Transaction - verifyWitnessF func() error - maxVerificationGAS int64 - notaryContractScriptHash util.Uint160 - notaryDepositExpiration uint32 - postBlock []func(blockchainer.Blockchainer, *mempool.Pool, *block.Block) - utilityTokenBalance *big.Int -} - -func newTestChain() *testChain { - return &testChain{ - Pool: mempool.New(10, 0, false), - poolTx: func(*transaction.Transaction) error { return nil }, - poolTxWithData: func(*transaction.Transaction, interface{}, *mempool.Pool) error { return nil }, - blocks: make(map[util.Uint256]*block.Block), - hdrHashes: make(map[uint32]util.Uint256), - txs: make(map[util.Uint256]*transaction.Transaction), - ProtocolConfiguration: config.ProtocolConfiguration{P2PNotaryRequestPayloadPoolSize: 10}, - } -} - -func (chain *testChain) putBlock(b *block.Block) { - chain.blocks[b.Hash()] = b - chain.hdrHashes[b.Index] = b.Hash() - atomic.StoreUint32(&chain.blockheight, b.Index) -} -func (chain *testChain) putHeader(b *block.Block) { - chain.hdrHashes[b.Index] = b.Hash() -} - -func (chain *testChain) putTx(tx *transaction.Transaction) { - chain.txs[tx.Hash()] = tx -} - -func (chain *testChain) ApplyPolicyToTxSet([]*transaction.Transaction) []*transaction.Transaction { - panic("TODO") -} - -func (chain *testChain) IsTxStillRelevant(t *transaction.Transaction, txpool *mempool.Pool, isPartialTx bool) bool { - panic("TODO") -} -func (*testChain) IsExtensibleAllowed(uint160 util.Uint160) bool { - return true -} - -func (chain *testChain) GetNotaryDepositExpiration(acc util.Uint160) uint32 { - if chain.notaryDepositExpiration != 0 { - return chain.notaryDepositExpiration - } - panic("TODO") -} - -func (chain *testChain) GetNotaryContractScriptHash() util.Uint160 { - if !chain.notaryContractScriptHash.Equals(util.Uint160{}) { - return chain.notaryContractScriptHash - } - panic("TODO") -} - -func (chain *testChain) GetNotaryBalance(acc util.Uint160) *big.Int { - panic("TODO") -} - -func (chain *testChain) GetPolicer() blockchainer.Policer { - return chain -} -func (chain *testChain) GetBaseExecFee() int64 { - return interop.DefaultBaseExecFee -} -func (chain *testChain) GetStoragePrice() int64 { - return native.StoragePrice -} -func (chain *testChain) GetMaxVerificationGAS() int64 { - if chain.maxVerificationGAS != 0 { - return chain.maxVerificationGAS - } - panic("TODO") -} - -func (chain *testChain) PoolTxWithData(t *transaction.Transaction, data interface{}, mp *mempool.Pool, feer mempool.Feer, verificationFunction func(bc blockchainer.Blockchainer, t *transaction.Transaction, data interface{}) error) error { - return chain.poolTxWithData(t, data, mp) -} - -func (chain *testChain) RegisterPostBlock(f func(blockchainer.Blockchainer, *mempool.Pool, *block.Block)) { - chain.postBlock = append(chain.postBlock, f) -} - -func (chain *testChain) GetConfig() config.ProtocolConfiguration { - return chain.ProtocolConfiguration -} -func (chain *testChain) CalculateClaimable(util.Uint160, uint32) (*big.Int, error) { - panic("TODO") -} - -func (chain *testChain) FeePerByte() int64 { - panic("TODO") -} - -func (chain *testChain) P2PSigExtensionsEnabled() bool { - return true -} - -func (chain *testChain) GetMaxBlockSystemFee() int64 { - panic("TODO") -} - -func (chain *testChain) GetMaxBlockSize() uint32 { - panic("TODO") -} - -func (chain *testChain) AddHeaders(...*block.Header) error { - panic("TODO") -} -func (chain *testChain) AddBlock(block *block.Block) error { - if block.Index == atomic.LoadUint32(&chain.blockheight)+1 { - chain.putBlock(block) - } - return nil -} -func (chain *testChain) AddStateRoot(r *state.MPTRoot) error { - panic("TODO") -} -func (chain *testChain) BlockHeight() uint32 { - return atomic.LoadUint32(&chain.blockheight) -} -func (chain *testChain) Close() { - panic("TODO") -} -func (chain *testChain) HeaderHeight() uint32 { - return atomic.LoadUint32(&chain.blockheight) -} -func (chain *testChain) GetAppExecResults(hash util.Uint256, trig trigger.Type) ([]state.AppExecResult, error) { - panic("TODO") -} -func (chain *testChain) GetBlock(hash util.Uint256) (*block.Block, error) { - if b, ok := chain.blocks[hash]; ok { - return b, nil - } - return nil, errors.New("not found") -} -func (chain *testChain) GetCommittee() (keys.PublicKeys, error) { - panic("TODO") -} -func (chain *testChain) GetContractState(hash util.Uint160) *state.Contract { - panic("TODO") -} -func (chain *testChain) GetContractScriptHash(id int32) (util.Uint160, error) { - panic("TODO") -} -func (chain *testChain) GetNativeContractScriptHash(name string) (util.Uint160, error) { - panic("TODO") -} -func (chain *testChain) GetHeaderHash(n int) util.Uint256 { - return chain.hdrHashes[uint32(n)] -} -func (chain *testChain) GetHeader(hash util.Uint256) (*block.Header, error) { - b, err := chain.GetBlock(hash) - if err != nil { - return nil, err - } - return b.Header(), nil -} - -func (chain *testChain) GetNextBlockValidators() ([]*keys.PublicKey, error) { - panic("TODO") -} -func (chain *testChain) ForEachNEP17Transfer(util.Uint160, func(*state.NEP17Transfer) (bool, error)) error { - panic("TODO") -} -func (chain *testChain) GetNEP17Balances(util.Uint160) *state.NEP17Balances { - panic("TODO") -} -func (chain *testChain) GetValidators() ([]*keys.PublicKey, error) { - panic("TODO") -} -func (chain *testChain) GetStandByCommittee() keys.PublicKeys { - panic("TODO") -} -func (chain *testChain) GetStandByValidators() keys.PublicKeys { - panic("TODO") -} -func (chain *testChain) GetEnrollments() ([]state.Validator, error) { - panic("TODO") -} -func (chain *testChain) GetStateProof(util.Uint256, []byte) ([][]byte, error) { - panic("TODO") -} -func (chain *testChain) GetStateRoot(height uint32) (*state.MPTRootState, error) { - panic("TODO") -} -func (chain *testChain) GetStorageItem(id int32, key []byte) *state.StorageItem { - panic("TODO") -} -func (chain *testChain) GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *vm.VM { - panic("TODO") -} -func (chain *testChain) GetStorageItems(id int32) (map[string]*state.StorageItem, error) { - panic("TODO") -} -func (chain *testChain) CurrentHeaderHash() util.Uint256 { - return util.Uint256{} -} -func (chain *testChain) CurrentBlockHash() util.Uint256 { - return util.Uint256{} -} -func (chain *testChain) HasBlock(h util.Uint256) bool { - _, ok := chain.blocks[h] - return ok -} -func (chain *testChain) HasTransaction(h util.Uint256) bool { - _, ok := chain.txs[h] - return ok -} -func (chain *testChain) GetTransaction(h util.Uint256) (*transaction.Transaction, uint32, error) { - if tx, ok := chain.txs[h]; ok { - return tx, 1, nil - } - return nil, 0, errors.New("not found") -} - -func (chain *testChain) GetMemPool() *mempool.Pool { - return chain.Pool -} - -func (chain *testChain) GetGoverningTokenBalance(acc util.Uint160) (*big.Int, uint32) { - panic("TODO") -} - -func (chain *testChain) GetUtilityTokenBalance(uint160 util.Uint160) *big.Int { - if chain.utilityTokenBalance != nil { - return chain.utilityTokenBalance - } - panic("TODO") -} -func (chain testChain) ManagementContractHash() util.Uint160 { - panic("TODO") -} - -func (chain *testChain) PoolTx(tx *transaction.Transaction, _ ...*mempool.Pool) error { - return chain.poolTx(tx) -} -func (chain testChain) SetOracle(services.Oracle) { - panic("TODO") -} -func (chain *testChain) SetNotary(notary services.Notary) { - panic("TODO") -} -func (chain *testChain) SubscribeForBlocks(ch chan<- *block.Block) { - chain.blocksCh = append(chain.blocksCh, ch) -} -func (chain *testChain) SubscribeForExecutions(ch chan<- *state.AppExecResult) { - panic("TODO") -} -func (chain *testChain) SubscribeForNotifications(ch chan<- *state.NotificationEvent) { - panic("TODO") -} -func (chain *testChain) SubscribeForTransactions(ch chan<- *transaction.Transaction) { - panic("TODO") -} - -func (chain *testChain) VerifyTx(*transaction.Transaction) error { - panic("TODO") -} -func (chain *testChain) VerifyWitness(util.Uint160, crypto.Verifiable, *transaction.Witness, int64) error { - if chain.verifyWitnessF != nil { - return chain.verifyWitnessF() - } - panic("TODO") -} - -func (chain *testChain) UnsubscribeFromBlocks(ch chan<- *block.Block) { - for i, c := range chain.blocksCh { - if c == ch { - if i < len(chain.blocksCh) { - copy(chain.blocksCh[i:], chain.blocksCh[i+1:]) - } - chain.blocksCh = chain.blocksCh[:len(chain.blocksCh)] - } - } -} -func (chain *testChain) UnsubscribeFromExecutions(ch chan<- *state.AppExecResult) { - panic("TODO") -} -func (chain *testChain) UnsubscribeFromNotifications(ch chan<- *state.NotificationEvent) { - panic("TODO") -} -func (chain *testChain) UnsubscribeFromTransactions(ch chan<- *transaction.Transaction) { - panic("TODO") -} - type testDiscovery struct { sync.Mutex bad []string @@ -503,7 +189,7 @@ func (p *localPeer) CanProcessAddr() bool { } func newTestServer(t *testing.T, serverConfig ServerConfig) *Server { - s, err := newServerFromConstructors(serverConfig, newTestChain(), zaptest.NewLogger(t), + s, err := newServerFromConstructors(serverConfig, fakechain.NewFakeChain(), zaptest.NewLogger(t), newFakeTransp, newFakeConsensus, newTestDiscovery) require.NoError(t, err) return s diff --git a/pkg/network/server_test.go b/pkg/network/server_test.go index 04cf91ca7..ef3d6432f 100644 --- a/pkg/network/server_test.go +++ b/pkg/network/server_test.go @@ -9,6 +9,7 @@ import ( "testing" "time" + "github.com/nspcc-dev/neo-go/internal/fakechain" "github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" @@ -47,7 +48,7 @@ func (f *fakeConsensus) OnTransaction(tx *transaction.Transaction) { f.txs = func (f *fakeConsensus) GetPayload(h util.Uint256) *payload.Extensible { panic("implement me") } func TestNewServer(t *testing.T) { - bc := &testChain{} + bc := &fakechain.FakeChain{} s, err := newServerFromConstructors(ServerConfig{}, bc, nil, newFakeTransp, newFakeConsensus, newTestDiscovery) require.Error(t, err) @@ -223,7 +224,7 @@ func TestGetBlocksByIndex(t *testing.T) { checkPingRespond(t, 3, 5000, 1+3*payload.MaxHashesCount) // Receive some blocks. - s.chain.(*testChain).blockheight = 2123 + s.chain.(*fakechain.FakeChain).Blockheight = 2123 // Minimum chunk has priority. checkPingRespond(t, 5, 5000, 2124) @@ -392,7 +393,7 @@ func TestBlock(t *testing.T) { s, shutdown := startTestServer(t) defer shutdown() - atomic2.StoreUint32(&s.chain.(*testChain).blockheight, 12344) + atomic2.StoreUint32(&s.chain.(*fakechain.FakeChain).Blockheight, 12344) require.Equal(t, uint32(12344), s.chain.BlockHeight()) b := block.New(netmode.UnitTestNet, false) @@ -405,7 +406,7 @@ func TestConsensus(t *testing.T) { s, shutdown := startTestServer(t) defer shutdown() - atomic2.StoreUint32(&s.chain.(*testChain).blockheight, 4) + atomic2.StoreUint32(&s.chain.(*fakechain.FakeChain).Blockheight, 4) p := newLocalPeer(t, s) p.handshaked = true @@ -417,11 +418,11 @@ func TestConsensus(t *testing.T) { return NewMessage(CMDExtensible, pl) } - s.chain.(*testChain).verifyWitnessF = func() error { return errors.New("invalid") } + s.chain.(*fakechain.FakeChain).VerifyWitnessF = func() error { return errors.New("invalid") } msg := newConsensusMessage(0, s.chain.BlockHeight()+1) require.Error(t, s.handleMessage(p, msg)) - s.chain.(*testChain).verifyWitnessF = func() error { return nil } + s.chain.(*fakechain.FakeChain).VerifyWitnessF = func() error { return nil } require.NoError(t, s.handleMessage(p, msg)) require.Contains(t, s.consensus.(*fakeConsensus).payloads, msg.Payload.(*payload.Extensible)) @@ -471,7 +472,7 @@ func TestTransaction(t *testing.T) { }) t.Run("bad", func(t *testing.T) { tx := newDummyTx() - s.chain.(*testChain).poolTx = func(*transaction.Transaction) error { return core.ErrInsufficientFunds } + s.chain.(*fakechain.FakeChain).PoolTxF = func(*transaction.Transaction) error { return core.ErrInsufficientFunds } s.testHandleMessage(t, nil, CMDTX, tx) for _, ftx := range s.consensus.(*fakeConsensus).txs { require.NotEqual(t, ftx, tx) @@ -505,19 +506,19 @@ func (s *Server) testHandleGetData(t *testing.T, invType payload.InventoryType, func TestGetData(t *testing.T) { s, shutdown := startTestServer(t) defer shutdown() - s.chain.(*testChain).utilityTokenBalance = big.NewInt(1000000) + s.chain.(*fakechain.FakeChain).UtilityTokenBalance = big.NewInt(1000000) t.Run("block", func(t *testing.T) { b := newDummyBlock(2, 0) hs := []util.Uint256{random.Uint256(), b.Hash(), random.Uint256()} - s.chain.(*testChain).putBlock(b) + s.chain.(*fakechain.FakeChain).PutBlock(b) notFound := []util.Uint256{hs[0], hs[2]} s.testHandleGetData(t, payload.BlockType, hs, notFound, b) }) t.Run("transaction", func(t *testing.T) { tx := newDummyTx() hs := []util.Uint256{random.Uint256(), tx.Hash(), random.Uint256()} - s.chain.(*testChain).putTx(tx) + s.chain.(*fakechain.FakeChain).PutTx(tx) notFound := []util.Uint256{hs[0], hs[2]} s.testHandleGetData(t, payload.TXType, hs, notFound, tx) }) @@ -567,7 +568,7 @@ func initGetBlocksTest(t *testing.T) (*Server, func(), []*block.Block) { var blocks []*block.Block for i := uint32(12); i <= 15; i++ { b := newDummyBlock(i, 3) - s.chain.(*testChain).putBlock(b) + s.chain.(*fakechain.FakeChain).PutBlock(b) blocks = append(blocks, b) } return s, shutdown, blocks @@ -633,7 +634,7 @@ func TestGetBlockByIndex(t *testing.T) { s.testHandleMessage(t, p, CMDGetBlockByIndex, &payload.GetBlockByIndex{IndexStart: blocks[0].Index, Count: -1}) }) t.Run("-1, last header", func(t *testing.T) { - s.chain.(*testChain).putHeader(newDummyBlock(16, 2)) + s.chain.(*fakechain.FakeChain).PutHeader(newDummyBlock(16, 2)) actual = nil expected = blocks s.testHandleMessage(t, p, CMDGetBlockByIndex, &payload.GetBlockByIndex{IndexStart: blocks[0].Index, Count: -1}) @@ -683,7 +684,7 @@ func TestGetHeaders(t *testing.T) { func TestInv(t *testing.T) { s, shutdown := startTestServer(t) defer shutdown() - s.chain.(*testChain).utilityTokenBalance = big.NewInt(10000000) + s.chain.(*fakechain.FakeChain).UtilityTokenBalance = big.NewInt(10000000) var actual []util.Uint256 p := newLocalPeer(t, s) @@ -696,7 +697,7 @@ func TestInv(t *testing.T) { t.Run("blocks", func(t *testing.T) { b := newDummyBlock(10, 3) - s.chain.(*testChain).putBlock(b) + s.chain.(*fakechain.FakeChain).PutBlock(b) hs := []util.Uint256{random.Uint256(), b.Hash(), random.Uint256()} s.testHandleMessage(t, p, CMDInv, &payload.Inventory{ Type: payload.BlockType, @@ -706,7 +707,7 @@ func TestInv(t *testing.T) { }) t.Run("transaction", func(t *testing.T) { tx := newDummyTx() - s.chain.(*testChain).putTx(tx) + s.chain.(*fakechain.FakeChain).PutTx(tx) hs := []util.Uint256{random.Uint256(), tx.Hash(), random.Uint256()} s.testHandleMessage(t, p, CMDInv, &payload.Inventory{ Type: payload.TXType, @@ -716,8 +717,8 @@ func TestInv(t *testing.T) { }) t.Run("extensible", func(t *testing.T) { ep := payload.NewExtensible(netmode.UnitTestNet) - s.chain.(*testChain).verifyWitnessF = func() error { return nil } - ep.ValidBlockEnd = s.chain.(*testChain).BlockHeight() + 1 + s.chain.(*fakechain.FakeChain).VerifyWitnessF = func() error { return nil } + ep.ValidBlockEnd = s.chain.(*fakechain.FakeChain).BlockHeight() + 1 ok, err := s.extensiblePool.Add(ep) require.NoError(t, err) require.True(t, ok) @@ -865,7 +866,7 @@ func TestMemPool(t *testing.T) { } } - bc := s.chain.(*testChain) + bc := s.chain.(*fakechain.FakeChain) expected := make([]util.Uint256, 4) for i := range expected { tx := newDummyTx() @@ -878,27 +879,27 @@ func TestMemPool(t *testing.T) { } func TestVerifyNotaryRequest(t *testing.T) { - bc := newTestChain() - bc.maxVerificationGAS = 10 - bc.notaryContractScriptHash = util.Uint160{1, 2, 3} + bc := fakechain.NewFakeChain() + bc.MaxVerificationGAS = 10 + bc.NotaryContractScriptHash = util.Uint160{1, 2, 3} newNotaryRequest := func() *payload.P2PNotaryRequest { return &payload.P2PNotaryRequest{ MainTransaction: &transaction.Transaction{Script: []byte{0, 1, 2}}, FallbackTransaction: &transaction.Transaction{ ValidUntilBlock: 321, - Signers: []transaction.Signer{{Account: bc.notaryContractScriptHash}, {Account: random.Uint160()}}, + Signers: []transaction.Signer{{Account: bc.NotaryContractScriptHash}, {Account: random.Uint160()}}, }, Witness: transaction.Witness{}, } } t.Run("bad payload witness", func(t *testing.T) { - bc.verifyWitnessF = func() error { return errors.New("bad witness") } + bc.VerifyWitnessF = func() error { return errors.New("bad witness") } require.Error(t, verifyNotaryRequest(bc, nil, newNotaryRequest())) }) t.Run("bad fallback sender", func(t *testing.T) { - bc.verifyWitnessF = func() error { return nil } + bc.VerifyWitnessF = func() error { return nil } r := newNotaryRequest() r.FallbackTransaction.Signers[0] = transaction.Signer{Account: util.Uint160{7, 8, 9}} require.Error(t, verifyNotaryRequest(bc, nil, r)) @@ -906,13 +907,13 @@ func TestVerifyNotaryRequest(t *testing.T) { t.Run("expired deposit", func(t *testing.T) { r := newNotaryRequest() - bc.notaryDepositExpiration = r.FallbackTransaction.ValidUntilBlock + bc.NotaryDepositExpiration = r.FallbackTransaction.ValidUntilBlock require.Error(t, verifyNotaryRequest(bc, nil, r)) }) t.Run("good", func(t *testing.T) { r := newNotaryRequest() - bc.notaryDepositExpiration = r.FallbackTransaction.ValidUntilBlock + 1 + bc.NotaryDepositExpiration = r.FallbackTransaction.ValidUntilBlock + 1 require.NoError(t, verifyNotaryRequest(bc, nil, r)) }) }