github.com/iotexproject/iotex-core@v1.14.1-rc1/e2etest/bigint_test.go (about)

     1  // Copyright (c) 2019 IoTeX Foundation
     2  // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
     3  // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
     4  // This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
     5  
     6  package e2etest
     7  
     8  import (
     9  	"context"
    10  	"math/big"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/iotexproject/go-pkgs/crypto"
    15  	"github.com/stretchr/testify/require"
    16  
    17  	"github.com/iotexproject/iotex-address/address"
    18  
    19  	"github.com/iotexproject/iotex-core/action"
    20  	"github.com/iotexproject/iotex-core/action/protocol"
    21  	"github.com/iotexproject/iotex-core/action/protocol/account"
    22  	accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util"
    23  	"github.com/iotexproject/iotex-core/action/protocol/execution"
    24  	"github.com/iotexproject/iotex-core/action/protocol/rewarding"
    25  	"github.com/iotexproject/iotex-core/action/protocol/rolldpos"
    26  	"github.com/iotexproject/iotex-core/actpool"
    27  	"github.com/iotexproject/iotex-core/blockchain"
    28  	"github.com/iotexproject/iotex-core/blockchain/block"
    29  	"github.com/iotexproject/iotex-core/blockchain/blockdao"
    30  	"github.com/iotexproject/iotex-core/blockchain/filedao"
    31  	"github.com/iotexproject/iotex-core/blockchain/genesis"
    32  	"github.com/iotexproject/iotex-core/config"
    33  	"github.com/iotexproject/iotex-core/db"
    34  	"github.com/iotexproject/iotex-core/state/factory"
    35  	"github.com/iotexproject/iotex-core/testutil"
    36  )
    37  
    38  const (
    39  	_executor       = "io1mflp9m6hcgm2qcghchsdqj3z3eccrnekx9p0ms"
    40  	_recipient      = "io1emxf8zzqckhgjde6dqd97ts0y3q496gm3fdrl6"
    41  	_executorPriKey = "cfa6ef757dee2e50351620dca002d32b9c090cfda55fb81f37f1d26b273743f1"
    42  )
    43  
    44  func fakeGetBlockTime(uint64) (time.Time, error) { return time.Time{}, nil }
    45  
    46  func TestTransfer_Negative(t *testing.T) {
    47  	r := require.New(t)
    48  	ctx := context.Background()
    49  	bc, sf, ap := prepareBlockchain(ctx, _executor, r)
    50  	defer r.NoError(bc.Stop(ctx))
    51  	ctx = genesis.WithGenesisContext(ctx, bc.Genesis())
    52  	addr, err := address.FromString(_executor)
    53  	r.NoError(err)
    54  	stateBeforeTransfer, err := accountutil.AccountState(ctx, sf, addr)
    55  	r.NoError(err)
    56  	blk, err := prepareTransfer(bc, sf, ap, r)
    57  	r.NoError(err)
    58  	r.Equal(1, len(blk.Actions))
    59  	r.NoError(bc.ValidateBlock(blk))
    60  	state, err := accountutil.AccountState(ctx, sf, addr)
    61  	r.NoError(err)
    62  	r.Equal(0, state.Balance.Cmp(stateBeforeTransfer.Balance))
    63  }
    64  
    65  func TestAction_Negative(t *testing.T) {
    66  	r := require.New(t)
    67  	ctx := context.Background()
    68  	bc, sf, ap := prepareBlockchain(ctx, _executor, r)
    69  	defer r.NoError(bc.Stop(ctx))
    70  	addr, err := address.FromString(_executor)
    71  	r.NoError(err)
    72  	ctx = genesis.WithGenesisContext(ctx, bc.Genesis())
    73  	stateBeforeTransfer, err := accountutil.AccountState(ctx, sf, addr)
    74  	r.NoError(err)
    75  	blk, err := prepareAction(bc, sf, ap, r)
    76  	r.NoError(err)
    77  	r.NotNil(blk)
    78  	r.Equal(1, len(blk.Actions))
    79  	r.NoError(bc.ValidateBlock(blk))
    80  	state, err := accountutil.AccountState(ctx, sf, addr)
    81  	r.NoError(err)
    82  	r.Equal(0, state.Balance.Cmp(stateBeforeTransfer.Balance))
    83  }
    84  
    85  func prepareBlockchain(ctx context.Context, _executor string, r *require.Assertions) (blockchain.Blockchain, factory.Factory, actpool.ActPool) {
    86  	cfg := config.Default
    87  	cfg.Chain.EnableAsyncIndexWrite = false
    88  	cfg.Genesis.EnableGravityChainVoting = false
    89  	cfg.Genesis.InitBalanceMap[_executor] = "1000000000000000000000000000"
    90  	registry := protocol.NewRegistry()
    91  	acc := account.NewProtocol(rewarding.DepositGas)
    92  	r.NoError(acc.Register(registry))
    93  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
    94  	r.NoError(rp.Register(registry))
    95  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
    96  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
    97  	r.NoError(err)
    98  	genericValidator := protocol.NewGenericValidator(sf, accountutil.AccountState)
    99  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   100  	r.NoError(err)
   101  	ap.AddActionEnvelopeValidators(genericValidator)
   102  	store, err := filedao.NewFileDAOInMemForTest()
   103  	r.NoError(err)
   104  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
   105  	bc := blockchain.NewBlockchain(
   106  		cfg.Chain,
   107  		cfg.Genesis,
   108  		dao,
   109  		factory.NewMinter(sf, ap),
   110  		blockchain.BlockValidatorOption(block.NewValidator(
   111  			sf,
   112  			genericValidator,
   113  		)),
   114  	)
   115  	r.NotNil(bc)
   116  	reward := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   117  	r.NoError(reward.Register(registry))
   118  
   119  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   120  	r.NoError(ep.Register(registry))
   121  	r.NoError(bc.Start(ctx))
   122  	ctx = genesis.WithGenesisContext(ctx, cfg.Genesis)
   123  	r.NoError(sf.Start(ctx))
   124  	return bc, sf, ap
   125  }
   126  
   127  func prepareTransfer(bc blockchain.Blockchain, sf factory.Factory, ap actpool.ActPool, r *require.Assertions) (*block.Block, error) {
   128  	exec, err := action.NewTransfer(1, big.NewInt(-10000), _recipient, nil, uint64(1000000), big.NewInt(9000000000000))
   129  	r.NoError(err)
   130  	builder := &action.EnvelopeBuilder{}
   131  	elp := builder.SetAction(exec).
   132  		SetNonce(exec.Nonce()).
   133  		SetGasLimit(exec.GasLimit()).
   134  		SetGasPrice(exec.GasPrice()).
   135  		Build()
   136  	return prepare(bc, sf, ap, elp, r)
   137  }
   138  
   139  func prepareAction(bc blockchain.Blockchain, sf factory.Factory, ap actpool.ActPool, r *require.Assertions) (*block.Block, error) {
   140  	exec, err := action.NewExecution(action.EmptyAddress, 1, big.NewInt(-100), uint64(1000000), big.NewInt(9000000000000), []byte{})
   141  	r.NoError(err)
   142  	builder := &action.EnvelopeBuilder{}
   143  	elp := builder.SetAction(exec).
   144  		SetNonce(exec.Nonce()).
   145  		SetGasLimit(exec.GasLimit()).
   146  		SetGasPrice(exec.GasPrice()).
   147  		Build()
   148  	return prepare(bc, sf, ap, elp, r)
   149  }
   150  
   151  func prepare(bc blockchain.Blockchain, sf factory.Factory, ap actpool.ActPool, elp action.Envelope, r *require.Assertions) (*block.Block, error) {
   152  	priKey, err := crypto.HexStringToPrivateKey(_executorPriKey)
   153  	r.NoError(err)
   154  	selp, err := action.Sign(elp, priKey)
   155  	r.NoError(err)
   156  	r.Error(ap.Add(context.Background(), selp))
   157  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
   158  	r.NoError(err)
   159  	// when validate/commit a blk, the workingset and receipts of blk should be nil
   160  	blk.Receipts = nil
   161  	return blk, nil
   162  }