forked from TrueCloudLab/neoneo-go
cda1c75db3
They're misleading now that we have variable number of committee members/validators. The standby list can be seen in the configuration and the appropriate numbers can be received from it also.
514 lines
16 KiB
Go
514 lines
16 KiB
Go
package fakechain
|
|
|
|
import (
|
|
"errors"
|
|
"math"
|
|
"math/big"
|
|
"sync/atomic"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
|
"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/mpt"
|
|
"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/hash"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
"github.com/nspcc-dev/neo-go/pkg/rpc/response/result/subscriptions"
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
uatomic "go.uber.org/atomic"
|
|
)
|
|
|
|
// 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() (int64, error)
|
|
MaxVerificationGAS int64
|
|
NotaryContractScriptHash util.Uint160
|
|
NotaryDepositExpiration uint32
|
|
PostBlock []func(func(*transaction.Transaction, *mempool.Pool, bool) bool, *mempool.Pool, *block.Block)
|
|
UtilityTokenBalance *big.Int
|
|
}
|
|
|
|
// FakeStateSync implements StateSync interface.
|
|
type FakeStateSync struct {
|
|
IsActiveFlag uatomic.Bool
|
|
IsInitializedFlag uatomic.Bool
|
|
RequestHeaders uatomic.Bool
|
|
InitFunc func(h uint32) error
|
|
TraverseFunc func(root util.Uint256, process func(node mpt.Node, nodeBytes []byte) bool) error
|
|
AddMPTNodesFunc func(nodes [][]byte) error
|
|
}
|
|
|
|
// NewFakeChain returns new FakeChain structure.
|
|
func NewFakeChain() *FakeChain {
|
|
return NewFakeChainWithCustomCfg(nil)
|
|
}
|
|
|
|
// NewFakeChainWithCustomCfg returns new FakeChain structure with specified protocol configuration.
|
|
func NewFakeChainWithCustomCfg(protocolCfg func(c *config.ProtocolConfiguration)) *FakeChain {
|
|
cfg := config.ProtocolConfiguration{Magic: netmode.UnitTestNet, P2PNotaryRequestPayloadPoolSize: 10}
|
|
if protocolCfg != nil {
|
|
protocolCfg(&cfg)
|
|
}
|
|
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: cfg,
|
|
}
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
|
|
// InitVerificationContext initializes context for witness check.
|
|
func (chain *FakeChain) InitVerificationContext(ic *interop.Context, hash util.Uint160, witness *transaction.Witness) error {
|
|
panic("TODO")
|
|
}
|
|
|
|
// IsExtensibleAllowed implements Blockchainer interface.
|
|
func (*FakeChain) IsExtensibleAllowed(uint160 util.Uint160) bool {
|
|
return true
|
|
}
|
|
|
|
// GetNatives implements blockchainer.Blockchainer interface.
|
|
func (*FakeChain) GetNatives() []state.NativeContract {
|
|
panic("TODO")
|
|
}
|
|
|
|
// 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")
|
|
}
|
|
|
|
// GetBaseExecFee implements Policer interface.
|
|
func (chain *FakeChain) GetBaseExecFee() int64 {
|
|
return interop.DefaultBaseExecFee
|
|
}
|
|
|
|
// GetStoragePrice implements Policer interface.
|
|
func (chain *FakeChain) GetStoragePrice() int64 {
|
|
return native.DefaultStoragePrice
|
|
}
|
|
|
|
// 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(t *transaction.Transaction, data interface{}) error) error {
|
|
return chain.poolTxWithData(t, data, mp)
|
|
}
|
|
|
|
// RegisterPostBlock implements Blockchainer interface.
|
|
func (chain *FakeChain) RegisterPostBlock(f func(func(*transaction.Transaction, *mempool.Pool, bool) bool, *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
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// 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 {
|
|
if n < 0 || n > math.MaxUint32 {
|
|
return 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")
|
|
}
|
|
|
|
// GetNEP17Contracts implements Blockchainer interface.
|
|
func (chain *FakeChain) GetNEP11Contracts() []util.Uint160 {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetNEP17Contracts implements Blockchainer interface.
|
|
func (chain *FakeChain) GetNEP17Contracts() []util.Uint160 {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetNEP17LastUpdated implements Blockchainer interface.
|
|
func (chain *FakeChain) GetTokenLastUpdated(acc util.Uint160) (map[int32]uint32, error) {
|
|
panic("TODO")
|
|
}
|
|
|
|
// ForEachNEP17Transfer implements Blockchainer interface.
|
|
func (chain *FakeChain) ForEachNEP11Transfer(util.Uint160, uint64, func(*state.NEP11Transfer) (bool, error)) error {
|
|
panic("TODO")
|
|
}
|
|
|
|
// ForEachNEP17Transfer implements Blockchainer interface.
|
|
func (chain *FakeChain) ForEachNEP17Transfer(util.Uint160, uint64, func(*state.NEP17Transfer) (bool, error)) error {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetValidators implements Blockchainer interface.
|
|
func (chain *FakeChain) GetValidators() ([]*keys.PublicKey, error) {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetEnrollments implements Blockchainer interface.
|
|
func (chain *FakeChain) GetEnrollments() ([]state.Validator, error) {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetStateModule implements Blockchainer interface.
|
|
func (chain *FakeChain) GetStateModule() blockchainer.StateRoot {
|
|
return nil
|
|
}
|
|
|
|
// 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) *interop.Context {
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetStorageItems implements Blockchainer interface.
|
|
func (chain *FakeChain) GetStorageItems(id int32) ([]state.StorageItemWithKey, 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<- *subscriptions.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, hash.Hashable, *transaction.Witness, int64) (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<- *subscriptions.NotificationEvent) {
|
|
panic("TODO")
|
|
}
|
|
|
|
// UnsubscribeFromTransactions implements Blockchainer interface.
|
|
func (chain *FakeChain) UnsubscribeFromTransactions(ch chan<- *transaction.Transaction) {
|
|
panic("TODO")
|
|
}
|
|
|
|
// AddBlock implements StateSync interface.
|
|
func (s *FakeStateSync) AddBlock(block *block.Block) error {
|
|
panic("TODO")
|
|
}
|
|
|
|
// AddHeaders implements StateSync interface.
|
|
func (s *FakeStateSync) AddHeaders(...*block.Header) error {
|
|
panic("TODO")
|
|
}
|
|
|
|
// AddMPTNodes implements StateSync interface.
|
|
func (s *FakeStateSync) AddMPTNodes(nodes [][]byte) error {
|
|
if s.AddMPTNodesFunc != nil {
|
|
return s.AddMPTNodesFunc(nodes)
|
|
}
|
|
panic("TODO")
|
|
}
|
|
|
|
// BlockHeight implements StateSync interface.
|
|
func (s *FakeStateSync) BlockHeight() uint32 {
|
|
return 0
|
|
}
|
|
|
|
// IsActive implements StateSync interface.
|
|
func (s *FakeStateSync) IsActive() bool { return s.IsActiveFlag.Load() }
|
|
|
|
// IsInitialized implements StateSync interface.
|
|
func (s *FakeStateSync) IsInitialized() bool {
|
|
return s.IsInitializedFlag.Load()
|
|
}
|
|
|
|
// Init implements StateSync interface.
|
|
func (s *FakeStateSync) Init(currChainHeight uint32) error {
|
|
if s.InitFunc != nil {
|
|
return s.InitFunc(currChainHeight)
|
|
}
|
|
panic("TODO")
|
|
}
|
|
|
|
// NeedHeaders implements StateSync interface.
|
|
func (s *FakeStateSync) NeedHeaders() bool { return s.RequestHeaders.Load() }
|
|
|
|
// NeedMPTNodes implements StateSync interface.
|
|
func (s *FakeStateSync) NeedMPTNodes() bool {
|
|
panic("TODO")
|
|
}
|
|
|
|
// Traverse implements StateSync interface.
|
|
func (s *FakeStateSync) Traverse(root util.Uint256, process func(node mpt.Node, nodeBytes []byte) bool) error {
|
|
if s.TraverseFunc != nil {
|
|
return s.TraverseFunc(root, process)
|
|
}
|
|
panic("TODO")
|
|
}
|
|
|
|
// GetUnknownMPTNodesBatch implements StateSync interface.
|
|
func (s *FakeStateSync) GetUnknownMPTNodesBatch(limit int) []util.Uint256 {
|
|
panic("TODO")
|
|
}
|