github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/integrity/integrity_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 integrity
     7  
     8  import (
     9  	"context"
    10  	"encoding/hex"
    11  	"fmt"
    12  	"math/big"
    13  	"sync/atomic"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/ethereum/go-ethereum/crypto"
    18  	"github.com/golang/mock/gomock"
    19  	iotexcrypto "github.com/iotexproject/go-pkgs/crypto"
    20  	"github.com/pkg/errors"
    21  	"github.com/stretchr/testify/require"
    22  
    23  	"github.com/iotexproject/go-pkgs/hash"
    24  	"github.com/iotexproject/iotex-address/address"
    25  	"github.com/iotexproject/iotex-proto/golang/iotextypes"
    26  
    27  	"github.com/iotexproject/iotex-core/action"
    28  	"github.com/iotexproject/iotex-core/action/protocol"
    29  	"github.com/iotexproject/iotex-core/action/protocol/account"
    30  	accountutil "github.com/iotexproject/iotex-core/action/protocol/account/util"
    31  	"github.com/iotexproject/iotex-core/action/protocol/execution"
    32  	"github.com/iotexproject/iotex-core/action/protocol/execution/evm"
    33  	"github.com/iotexproject/iotex-core/action/protocol/poll"
    34  	"github.com/iotexproject/iotex-core/action/protocol/rewarding"
    35  	"github.com/iotexproject/iotex-core/action/protocol/rolldpos"
    36  	"github.com/iotexproject/iotex-core/action/protocol/vote/candidatesutil"
    37  	"github.com/iotexproject/iotex-core/actpool"
    38  	"github.com/iotexproject/iotex-core/blockchain"
    39  	"github.com/iotexproject/iotex-core/blockchain/block"
    40  	"github.com/iotexproject/iotex-core/blockchain/blockdao"
    41  	"github.com/iotexproject/iotex-core/blockchain/filedao"
    42  	"github.com/iotexproject/iotex-core/blockchain/genesis"
    43  	"github.com/iotexproject/iotex-core/blockindex"
    44  	"github.com/iotexproject/iotex-core/config"
    45  	"github.com/iotexproject/iotex-core/db"
    46  	"github.com/iotexproject/iotex-core/db/trie/mptrie"
    47  	"github.com/iotexproject/iotex-core/pkg/unit"
    48  	"github.com/iotexproject/iotex-core/state"
    49  	"github.com/iotexproject/iotex-core/state/factory"
    50  	"github.com/iotexproject/iotex-core/test/identityset"
    51  	"github.com/iotexproject/iotex-core/test/mock/mock_blockcreationsubscriber"
    52  	"github.com/iotexproject/iotex-core/testutil"
    53  )
    54  
    55  var (
    56  	_deployHash      hash.Hash256                                                                           // in block 1
    57  	_setHash         hash.Hash256                                                                           // in block 2
    58  	_shrHash         hash.Hash256                                                                           // in block 3
    59  	_shlHash         hash.Hash256                                                                           // in block 4
    60  	_sarHash         hash.Hash256                                                                           // in block 5
    61  	_extHash         hash.Hash256                                                                           // in block 6
    62  	_crt2Hash        hash.Hash256                                                                           // in block 7
    63  	_storeHash       hash.Hash256                                                                           // in block 8
    64  	_store2Hash      hash.Hash256                                                                           // in block 9
    65  	_setTopic, _     = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f40") // in block 2
    66  	_getTopic, _     = hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001") // in block 2
    67  	_shrTopic, _     = hex.DecodeString("00fe00000000000000000000000000000000000000000000000000000000001f") // in block 3
    68  	_shlTopic, _     = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f00") // in block 4
    69  	_sarTopic, _     = hex.DecodeString("fffe00000000000000000000000000000000000000000000000000000000001f") // in block 5
    70  	_extTopic, _     = hex.DecodeString("4a98ce81a2fd5177f0f42b49cb25b01b720f9ce8019f3937f63b789766c938e2") // in block 6
    71  	_crt2Topic, _    = hex.DecodeString("0000000000000000000000001895e6033cd1081f18e0bd23a4501d9376028523") // in block 7
    72  	_preGrPreStore   *big.Int
    73  	_preGrPostStore  *big.Int
    74  	_postGrPostStore *big.Int
    75  )
    76  
    77  func fakeGetBlockTime(height uint64) (time.Time, error) {
    78  	return time.Time{}, nil
    79  }
    80  
    81  func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.BlockDAO, sf factory.Factory, ap actpool.ActPool) error {
    82  	// Add block 1
    83  	priKey0 := identityset.PrivateKey(27)
    84  	ex1, err := action.SignedExecution(action.EmptyAddress, priKey0, 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), _constantinopleOpCodeContract)
    85  	if err != nil {
    86  		return err
    87  	}
    88  	_deployHash, err = ex1.Hash()
    89  	if err != nil {
    90  		return err
    91  	}
    92  	if err := ap.Add(context.Background(), ex1); err != nil {
    93  		return err
    94  	}
    95  	blockTime := time.Unix(1546329600, 0)
    96  	blk, err := bc.MintNewBlock(blockTime)
    97  	if err != nil {
    98  		return err
    99  	}
   100  	if err := bc.CommitBlock(blk); err != nil {
   101  		return err
   102  	}
   103  
   104  	// get deployed contract address
   105  	var contract string
   106  	if dao != nil {
   107  		r, err := receiptByActionHash(dao, 1, _deployHash)
   108  		if err != nil {
   109  			return err
   110  		}
   111  		contract = r.ContractAddress
   112  	}
   113  
   114  	addOneBlock := func(contract string, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) (hash.Hash256, error) {
   115  		ex1, err := action.SignedExecution(contract, priKey0, nonce, amount, gasLimit, gasPrice, data)
   116  		if err != nil {
   117  			return hash.ZeroHash256, err
   118  		}
   119  		blockTime = blockTime.Add(time.Second)
   120  		if err := ap.Add(context.Background(), ex1); err != nil {
   121  			return hash.ZeroHash256, err
   122  		}
   123  		blk, err = bc.MintNewBlock(blockTime)
   124  		if err != nil {
   125  			return hash.ZeroHash256, err
   126  		}
   127  		if err := bc.CommitBlock(blk); err != nil {
   128  			return hash.ZeroHash256, err
   129  		}
   130  		ex1Hash, err := ex1.Hash()
   131  		if err != nil {
   132  			return hash.ZeroHash256, err
   133  		}
   134  		return ex1Hash, nil
   135  	}
   136  
   137  	var (
   138  		zero     = big.NewInt(0)
   139  		gasLimit = testutil.TestGasLimit * 5
   140  		gasPrice = big.NewInt(testutil.TestGasPriceInt64)
   141  	)
   142  
   143  	// Add block 2
   144  	// call set() to set storedData = 0xfe...1f40
   145  	funcSig := hash.Hash256b([]byte("set(uint256)"))
   146  	data := append(funcSig[:4], _setTopic...)
   147  	_setHash, err = addOneBlock(contract, 2, zero, gasLimit, gasPrice, data)
   148  	if err != nil {
   149  		return err
   150  	}
   151  
   152  	// Add block 3
   153  	// call shright() to test SHR opcode, storedData => 0x00fe...1f
   154  	funcSig = hash.Hash256b([]byte("shright()"))
   155  	_shrHash, err = addOneBlock(contract, 3, zero, gasLimit, gasPrice, funcSig[:4])
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	// Add block 4
   161  	// call shleft() to test SHL opcode, storedData => 0xfe...1f00
   162  	funcSig = hash.Hash256b([]byte("shleft()"))
   163  	_shlHash, err = addOneBlock(contract, 4, zero, gasLimit, gasPrice, funcSig[:4])
   164  	if err != nil {
   165  		return err
   166  	}
   167  
   168  	// Add block 5
   169  	// call saright() to test SAR opcode, storedData => 0xfffe...1f
   170  	funcSig = hash.Hash256b([]byte("saright()"))
   171  	_sarHash, err = addOneBlock(contract, 5, zero, gasLimit, gasPrice, funcSig[:4])
   172  	if err != nil {
   173  		return err
   174  	}
   175  
   176  	// Add block 6
   177  	// call getCodeHash() to test EXTCODEHASH opcode
   178  	funcSig = hash.Hash256b([]byte("getCodeHash(address)"))
   179  	addr, _ := address.FromString(contract)
   180  	ethaddr := hash.BytesToHash256(addr.Bytes())
   181  	data = append(funcSig[:4], ethaddr[:]...)
   182  	_extHash, err = addOneBlock(contract, 6, zero, gasLimit, gasPrice, data)
   183  	if err != nil {
   184  		return err
   185  	}
   186  
   187  	// Add block 7
   188  	// call create2() to test CREATE2 opcode
   189  	funcSig = hash.Hash256b([]byte("create2()"))
   190  	_crt2Hash, err = addOneBlock(contract, 7, zero, gasLimit, gasPrice, funcSig[:4])
   191  	if err != nil {
   192  		return err
   193  	}
   194  
   195  	// Add block 8
   196  	// test store out of gas
   197  	var (
   198  		caller     = &state.Account{}
   199  		callerAddr = hash.BytesToHash160(identityset.Address(27).Bytes())
   200  	)
   201  	_, err = sf.State(caller, protocol.LegacyKeyOption(callerAddr))
   202  	if err != nil {
   203  		return err
   204  	}
   205  	_preGrPreStore = new(big.Int).Set(caller.Balance)
   206  	_storeHash, err = addOneBlock(action.EmptyAddress, 8, unit.ConvertIotxToRau(10000), 3000000, big.NewInt(unit.Qev), _codeStoreOutOfGasContract)
   207  	if err != nil {
   208  		return err
   209  	}
   210  
   211  	if dao != nil {
   212  		r, err := receiptByActionHash(dao, 8, _storeHash)
   213  		if err != nil {
   214  			return err
   215  		}
   216  		if r.Status != uint64(iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas) {
   217  			return blockchain.ErrBalance
   218  		}
   219  	}
   220  
   221  	// Add block 9
   222  	// test store out of gas
   223  	_, err = sf.State(caller, protocol.LegacyKeyOption(callerAddr))
   224  	if err != nil {
   225  		return err
   226  	}
   227  	_preGrPostStore = new(big.Int).Set(caller.Balance)
   228  	_store2Hash, err = addOneBlock(action.EmptyAddress, 9, unit.ConvertIotxToRau(10000), 3000000, big.NewInt(unit.Qev), _codeStoreOutOfGasContract)
   229  	if err != nil {
   230  		return err
   231  	}
   232  
   233  	if dao != nil {
   234  		r, err := receiptByActionHash(dao, 9, _store2Hash)
   235  		if err != nil {
   236  			return err
   237  		}
   238  		if r.Status != uint64(iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas) {
   239  			return blockchain.ErrBalance
   240  		}
   241  	}
   242  
   243  	_, err = sf.State(caller, protocol.LegacyKeyOption(callerAddr))
   244  	if err != nil {
   245  		return err
   246  	}
   247  	_postGrPostStore = new(big.Int).Set(caller.Balance)
   248  	return nil
   249  }
   250  
   251  func addTestingTsfBlocks(cfg config.Config, bc blockchain.Blockchain, dao blockdao.BlockDAO, ap actpool.ActPool) error {
   252  	ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
   253  	addOneTsf := func(recipientAddr string, senderPriKey iotexcrypto.PrivateKey, nonce uint64, amount *big.Int, payload []byte, gasLimit uint64, gasPrice *big.Int) error {
   254  		tx, err := action.SignedTransfer(recipientAddr, senderPriKey, nonce, amount, payload, gasLimit, gasPrice)
   255  		if err != nil {
   256  			return err
   257  		}
   258  		if err := ap.Add(ctx, tx); err != nil {
   259  			return err
   260  		}
   261  		return nil
   262  	}
   263  	addOneExec := func(contractAddr string, executorPriKey iotexcrypto.PrivateKey, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) error {
   264  		tx, err := action.SignedExecution(contractAddr, executorPriKey, nonce, amount, gasLimit, gasPrice, data)
   265  		if err != nil {
   266  			return err
   267  		}
   268  		if err := ap.Add(ctx, tx); err != nil {
   269  			return err
   270  		}
   271  		return nil
   272  	}
   273  	// Add block 1
   274  	addr0 := identityset.Address(27).String()
   275  	if err := addOneTsf(addr0, identityset.PrivateKey(0), 1, big.NewInt(90000000), nil, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   276  		return err
   277  	}
   278  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
   279  	if err != nil {
   280  		return err
   281  	}
   282  	if err := bc.CommitBlock(blk); err != nil {
   283  		return err
   284  	}
   285  	ap.Reset()
   286  
   287  	priKey0 := identityset.PrivateKey(27)
   288  	addr1 := identityset.Address(28).String()
   289  	priKey1 := identityset.PrivateKey(28)
   290  	addr2 := identityset.Address(29).String()
   291  	priKey2 := identityset.PrivateKey(29)
   292  	addr3 := identityset.Address(30).String()
   293  	priKey3 := identityset.PrivateKey(30)
   294  	addr4 := identityset.Address(31).String()
   295  	priKey4 := identityset.PrivateKey(31)
   296  	addr5 := identityset.Address(32).String()
   297  	priKey5 := identityset.PrivateKey(32)
   298  	addr6 := identityset.Address(33).String()
   299  	// Add block 2
   300  	// test --> A, B, C, D, E, F
   301  	if err := addOneTsf(addr1, priKey0, 1, big.NewInt(20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   302  		return err
   303  	}
   304  	if err := addOneTsf(addr2, priKey0, 2, big.NewInt(30), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   305  		return err
   306  	}
   307  	if err := addOneTsf(addr3, priKey0, 3, big.NewInt(50), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   308  		return err
   309  	}
   310  	if err := addOneTsf(addr4, priKey0, 4, big.NewInt(70), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   311  		return err
   312  	}
   313  	if err := addOneTsf(addr5, priKey0, 5, big.NewInt(110), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   314  		return err
   315  	}
   316  	if err := addOneTsf(addr6, priKey0, 6, big.NewInt(50<<20), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   317  		return err
   318  	}
   319  	// deploy simple smart contract
   320  	data, _ := hex.DecodeString("608060405234801561001057600080fd5b50610233806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680635bec9e671461005c57806360fe47b114610073578063c2bc2efc146100a0575b600080fd5b34801561006857600080fd5b506100716100f7565b005b34801561007f57600080fd5b5061009e60048036038101908080359060200190929190505050610143565b005b3480156100ac57600080fd5b506100e1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061017a565b6040518082815260200191505060405180910390f35b5b6001156101155760008081548092919060010191905055506100f8565b7f8bfaa460932ccf8751604dd60efa3eafa220ec358fccb32ef703f91c509bc3ea60405160405180910390a1565b80600081905550807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156101b757600080fd5b6000548273ffffffffffffffffffffffffffffffffffffffff167fbde7a70c2261170a87678200113c8e12f82f63d0a1d1cfa45681cbac328e87e360405160405180910390a360005490509190505600a165627a7a723058203198d0390613dab2dff2fa053c1865e802618d628429b01ab05b8458afc347eb0029")
   321  	ex1, err := action.SignedExecution(action.EmptyAddress, priKey2, 1, big.NewInt(0), 200000, big.NewInt(testutil.TestGasPriceInt64), data)
   322  	if err != nil {
   323  		return err
   324  	}
   325  	if err := ap.Add(ctx, ex1); err != nil {
   326  		return err
   327  	}
   328  	_deployHash, err = ex1.Hash()
   329  	if err != nil {
   330  		return err
   331  	}
   332  	blk, err = bc.MintNewBlock(testutil.TimestampNow())
   333  	if err != nil {
   334  		return err
   335  	}
   336  	if err := bc.CommitBlock(blk); err != nil {
   337  		return err
   338  	}
   339  	ap.Reset()
   340  
   341  	// get deployed contract address
   342  	var contract string
   343  	_, gateway := cfg.Plugins[config.GatewayPlugin]
   344  	if gateway && !cfg.Chain.EnableAsyncIndexWrite {
   345  		r, err := receiptByActionHash(dao, 2, _deployHash)
   346  		if err != nil {
   347  			return err
   348  		}
   349  		contract = r.ContractAddress
   350  	}
   351  
   352  	// Add block 3
   353  	// Charlie --> A, B, D, E, test
   354  	if err := addOneTsf(addr1, priKey3, 1, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   355  		return err
   356  	}
   357  	if err := addOneTsf(addr2, priKey3, 2, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   358  		return err
   359  	}
   360  	if err := addOneTsf(addr4, priKey3, 3, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   361  		return err
   362  	}
   363  	if err := addOneTsf(addr5, priKey3, 4, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   364  		return err
   365  	}
   366  	if err := addOneTsf(addr0, priKey3, 5, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   367  		return err
   368  	}
   369  	// call set() to set storedData = 0x1f40
   370  	data, _ = hex.DecodeString("60fe47b1")
   371  	data = append(data, _setTopic...)
   372  	ex1, err = action.SignedExecution(contract, priKey2, 2, big.NewInt(0), testutil.TestGasLimit*5, big.NewInt(testutil.TestGasPriceInt64), data)
   373  	if err != nil {
   374  		return err
   375  	}
   376  	_setHash, err = ex1.Hash()
   377  	if err != nil {
   378  		return err
   379  	}
   380  	if err := ap.Add(context.Background(), ex1); err != nil {
   381  		return err
   382  	}
   383  	blk, err = bc.MintNewBlock(testutil.TimestampNow())
   384  	if err != nil {
   385  		return err
   386  	}
   387  	if err := bc.CommitBlock(blk); err != nil {
   388  		return err
   389  	}
   390  	ap.Reset()
   391  
   392  	// Add block 4
   393  	// Delta --> B, E, F, test
   394  	if err := addOneTsf(addr2, priKey4, 1, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   395  		return err
   396  	}
   397  	if err := addOneTsf(addr5, priKey4, 2, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   398  		return err
   399  	}
   400  	if err := addOneTsf(addr6, priKey4, 3, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   401  		return err
   402  	}
   403  	if err := addOneTsf(addr0, priKey4, 4, big.NewInt(1), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   404  		return err
   405  	}
   406  	data, _ = hex.DecodeString("c2bc2efc")
   407  	data = append(data, _getTopic...)
   408  	ex1, err = action.SignedExecution(contract, priKey2, 3, big.NewInt(0), testutil.TestGasLimit*5, big.NewInt(testutil.TestGasPriceInt64), data)
   409  	if err != nil {
   410  		return err
   411  	}
   412  	_sarHash, err = ex1.Hash()
   413  	if err != nil {
   414  		return err
   415  	}
   416  	if err := ap.Add(context.Background(), ex1); err != nil {
   417  		return err
   418  	}
   419  	blk, err = bc.MintNewBlock(testutil.TimestampNow())
   420  	if err != nil {
   421  		return err
   422  	}
   423  	if err := bc.CommitBlock(blk); err != nil {
   424  		return err
   425  	}
   426  
   427  	// Add block 5
   428  	// Delta --> A, B, C, D, F, test
   429  	if err := addOneTsf(addr1, priKey5, 1, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   430  		return err
   431  	}
   432  	if err := addOneTsf(addr2, priKey5, 2, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   433  		return err
   434  	}
   435  	if err := addOneTsf(addr3, priKey5, 3, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   436  		return err
   437  	}
   438  	if err := addOneTsf(addr4, priKey5, 4, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   439  		return err
   440  	}
   441  	if err := addOneTsf(addr6, priKey5, 5, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   442  		return err
   443  	}
   444  	if err := addOneTsf(addr0, priKey5, 6, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   445  		return err
   446  	}
   447  	if err := addOneTsf(addr3, priKey3, 6, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   448  		return err
   449  	}
   450  	if err := addOneTsf(addr1, priKey1, 1, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64)); err != nil {
   451  		return err
   452  	}
   453  	// call set() to set storedData = 0x1f40
   454  	data, _ = hex.DecodeString("60fe47b1")
   455  	data = append(data, _setTopic...)
   456  	if err := addOneExec(contract, priKey2, 4, big.NewInt(0), testutil.TestGasLimit*5, big.NewInt(testutil.TestGasPriceInt64), data); err != nil {
   457  		return err
   458  	}
   459  	data, _ = hex.DecodeString("c2bc2efc")
   460  	data = append(data, _getTopic...)
   461  	if err := addOneExec(contract, priKey2, 5, big.NewInt(0), testutil.TestGasLimit*5, big.NewInt(testutil.TestGasPriceInt64), data); err != nil {
   462  		return err
   463  	}
   464  	blk, err = bc.MintNewBlock(testutil.TimestampNow())
   465  	if err != nil {
   466  		return err
   467  	}
   468  	return bc.CommitBlock(blk)
   469  }
   470  
   471  func TestCreateBlockchain(t *testing.T) {
   472  	require := require.New(t)
   473  	ctx := context.Background()
   474  
   475  	cfg := config.Default
   476  	// disable account-based testing
   477  	cfg.Chain.TrieDBPath = ""
   478  	cfg.Genesis.EnableGravityChainVoting = false
   479  	cfg.ActPool.MinGasPriceStr = "0"
   480  	// create chain
   481  	registry := protocol.NewRegistry()
   482  	acc := account.NewProtocol(rewarding.DepositGas)
   483  	require.NoError(acc.Register(registry))
   484  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   485  	require.NoError(rp.Register(registry))
   486  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   487  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
   488  	require.NoError(err)
   489  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   490  	require.NoError(err)
   491  	store, err := filedao.NewFileDAOInMemForTest()
   492  	require.NoError(err)
   493  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
   494  	bc := blockchain.NewBlockchain(
   495  		cfg.Chain,
   496  		cfg.Genesis,
   497  		dao,
   498  		factory.NewMinter(sf, ap),
   499  		blockchain.BlockValidatorOption(block.NewValidator(
   500  			sf,
   501  			protocol.NewGenericValidator(sf, accountutil.AccountState),
   502  		)),
   503  	)
   504  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   505  	require.NoError(ep.Register(registry))
   506  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   507  	require.NoError(rewardingProtocol.Register(registry))
   508  	require.NoError(bc.Start(ctx))
   509  	require.NotNil(bc)
   510  	height := bc.TipHeight()
   511  	require.Equal(0, int(height))
   512  	defer func() {
   513  		require.NoError(bc.Stop(ctx))
   514  	}()
   515  
   516  	// add 4 sample blocks
   517  	require.NoError(addTestingTsfBlocks(cfg, bc, nil, ap))
   518  	height = bc.TipHeight()
   519  	require.Equal(5, int(height))
   520  }
   521  
   522  func TestGetBlockHash(t *testing.T) {
   523  	require := require.New(t)
   524  	ctx := context.Background()
   525  
   526  	cfg := config.Default
   527  	// disable account-based testing
   528  	cfg.Chain.TrieDBPath = ""
   529  	cfg.Genesis.EnableGravityChainVoting = false
   530  	cfg.Genesis.HawaiiBlockHeight = 4
   531  	cfg.Genesis.MidwayBlockHeight = 9
   532  	cfg.ActPool.MinGasPriceStr = "0"
   533  	genesis.SetGenesisTimestamp(cfg.Genesis.Timestamp)
   534  	block.LoadGenesisHash(&genesis.Default)
   535  	// create chain
   536  	registry := protocol.NewRegistry()
   537  	acc := account.NewProtocol(rewarding.DepositGas)
   538  	require.NoError(acc.Register(registry))
   539  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   540  	require.NoError(rp.Register(registry))
   541  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   542  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
   543  	require.NoError(err)
   544  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   545  	require.NoError(err)
   546  	store, err := filedao.NewFileDAOInMemForTest()
   547  	require.NoError(err)
   548  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
   549  	bc := blockchain.NewBlockchain(
   550  		cfg.Chain,
   551  		cfg.Genesis,
   552  		dao,
   553  		factory.NewMinter(sf, ap),
   554  		blockchain.BlockValidatorOption(block.NewValidator(
   555  			sf,
   556  			protocol.NewGenericValidator(sf, accountutil.AccountState),
   557  		)),
   558  	)
   559  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   560  	require.NoError(ep.Register(registry))
   561  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   562  	require.NoError(rewardingProtocol.Register(registry))
   563  	require.NoError(bc.Start(ctx))
   564  	require.NotNil(bc)
   565  	height := bc.TipHeight()
   566  	require.Equal(0, int(height))
   567  	defer func() {
   568  		require.NoError(bc.Stop(ctx))
   569  	}()
   570  
   571  	addTestingGetBlockHash(t, cfg.Genesis, bc, dao, ap)
   572  }
   573  
   574  func addTestingGetBlockHash(t *testing.T, g genesis.Genesis, bc blockchain.Blockchain, dao blockdao.BlockDAO, ap actpool.ActPool) {
   575  	require := require.New(t)
   576  	priKey0 := identityset.PrivateKey(27)
   577  
   578  	// deploy simple smart contract
   579  	/*
   580  		pragma solidity <6.0 >=0.4.24;
   581  
   582  		contract Test {
   583  		    event GetBlockhash(bytes32 indexed hash);
   584  
   585  		    function getBlockHash(uint256 blockNumber) public  returns (bytes32) {
   586  		       bytes32 h = blockhash(blockNumber);
   587  		        emit GetBlockhash(h);
   588  		        return h;
   589  		    }
   590  		}
   591  	*/
   592  	ctx := genesis.WithGenesisContext(context.Background(), g)
   593  	data, _ := hex.DecodeString("6080604052348015600f57600080fd5b5060de8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ee82ac5e14602d575b600080fd5b605660048036036020811015604157600080fd5b8101908080359060200190929190505050606c565b6040518082815260200191505060405180910390f35b60008082409050807f2d93f7749862d33969fb261757410b48065a1bc86a56da5c47820bd063e2338260405160405180910390a28091505091905056fea265627a7a723158200a258cd08ea99ee11aa68c78b6d2bf7ea912615a1e64a81b90a2abca2dd59cfa64736f6c634300050c0032")
   594  
   595  	ex1, err := action.SignedExecution(action.EmptyAddress, priKey0, 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), data)
   596  	require.NoError(err)
   597  	require.NoError(ap.Add(ctx, ex1))
   598  	_deployHash, err = ex1.Hash()
   599  	require.NoError(err)
   600  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
   601  	require.NoError(err)
   602  	require.NoError(bc.CommitBlock(blk))
   603  
   604  	ap.Reset()
   605  	blockTime := time.Unix(1546329600, 0)
   606  	// get deployed contract address
   607  	var contract string
   608  	if dao != nil {
   609  		r, err := receiptByActionHash(dao, 1, _deployHash)
   610  		require.NoError(err)
   611  		contract = r.ContractAddress
   612  	}
   613  	addOneBlock := func(contract string, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) (hash.Hash256, error) {
   614  		ex1, err := action.SignedExecution(contract, priKey0, nonce, amount, gasLimit, gasPrice, data)
   615  		if err != nil {
   616  			return hash.ZeroHash256, err
   617  		}
   618  		blockTime = blockTime.Add(time.Second)
   619  		if err := ap.Add(ctx, ex1); err != nil {
   620  			return hash.ZeroHash256, err
   621  		}
   622  		blk, err = bc.MintNewBlock(blockTime)
   623  		if err != nil {
   624  			return hash.ZeroHash256, err
   625  		}
   626  		if err := bc.CommitBlock(blk); err != nil {
   627  			return hash.ZeroHash256, err
   628  		}
   629  		ex1Hash, err := ex1.Hash()
   630  		if err != nil {
   631  			return hash.ZeroHash256, err
   632  		}
   633  		return ex1Hash, nil
   634  	}
   635  
   636  	getBlockHashCallData := func(x int64) []byte {
   637  		funcSig := hash.Hash256b([]byte("getBlockHash(uint256)"))
   638  		// convert block number to uint256 (32-bytes)
   639  		blockNumber := hash.BytesToHash256(big.NewInt(x).Bytes())
   640  		return append(funcSig[:4], blockNumber[:]...)
   641  	}
   642  
   643  	var (
   644  		zero     = big.NewInt(0)
   645  		nonce    = uint64(2)
   646  		gasLimit = testutil.TestGasLimit * 5
   647  		gasPrice = big.NewInt(testutil.TestGasPriceInt64)
   648  		bcHash   hash.Hash256
   649  	)
   650  	tests := []struct {
   651  		commitHeight  uint64
   652  		getHashHeight uint64
   653  	}{
   654  		{2, 0},
   655  		{3, 5},
   656  		{4, 1},
   657  		{5, 3},
   658  		{6, 0},
   659  		{7, 6},
   660  		{8, 9},
   661  		{9, 3},
   662  		{10, 9},
   663  		{11, 1},
   664  		{12, 4},
   665  		{13, 0},
   666  		{14, 100},
   667  		{15, 15},
   668  	}
   669  	for _, test := range tests {
   670  		h, err := addOneBlock(contract, nonce, zero, gasLimit, gasPrice, getBlockHashCallData(int64(test.getHashHeight)))
   671  		require.NoError(err)
   672  		r, err := receiptByActionHash(dao, test.commitHeight, h)
   673  		require.NoError(err)
   674  		if test.getHashHeight >= test.commitHeight {
   675  			bcHash = hash.ZeroHash256
   676  		} else if test.commitHeight < g.HawaiiBlockHeight {
   677  			// before hawaii it mistakenly return zero hash
   678  			// see https://github.com/iotexproject/iotex-core/commit/2585b444214f9009b6356fbaf59c992e8728fc01
   679  			bcHash = hash.ZeroHash256
   680  		} else {
   681  			var targetHeight uint64
   682  			if test.commitHeight < g.MidwayBlockHeight {
   683  				targetHeight = test.commitHeight - (test.getHashHeight + 1)
   684  			} else {
   685  				targetHeight = test.getHashHeight
   686  			}
   687  			bcHash, err = dao.GetBlockHash(targetHeight)
   688  			require.NoError(err)
   689  		}
   690  		require.Equal(r.Logs()[0].Topics[0], bcHash)
   691  		nonce++
   692  	}
   693  }
   694  
   695  func TestBlockchain_MintNewBlock(t *testing.T) {
   696  	cfg := config.Default
   697  	cfg.Genesis.BlockGasLimit = uint64(100000)
   698  	cfg.Genesis.EnableGravityChainVoting = false
   699  	cfg.ActPool.MinGasPriceStr = "0"
   700  	ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
   701  	registry := protocol.NewRegistry()
   702  	acc := account.NewProtocol(rewarding.DepositGas)
   703  	require.NoError(t, acc.Register(registry))
   704  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   705  	require.NoError(t, rp.Register(registry))
   706  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   707  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
   708  	require.NoError(t, err)
   709  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   710  	require.NoError(t, err)
   711  	store, err := filedao.NewFileDAOInMemForTest()
   712  	require.NoError(t, err)
   713  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
   714  	bc := blockchain.NewBlockchain(
   715  		cfg.Chain,
   716  		cfg.Genesis,
   717  		dao,
   718  		factory.NewMinter(sf, ap),
   719  		blockchain.BlockValidatorOption(block.NewValidator(
   720  			sf,
   721  			protocol.NewGenericValidator(sf, accountutil.AccountState),
   722  		)),
   723  	)
   724  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   725  	require.NoError(t, ep.Register(registry))
   726  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   727  	require.NoError(t, rewardingProtocol.Register(registry))
   728  	require.NoError(t, bc.Start(ctx))
   729  	defer func() {
   730  		require.NoError(t, bc.Stop(ctx))
   731  	}()
   732  
   733  	tsf, err := action.NewTransfer(
   734  		1,
   735  		big.NewInt(100000000),
   736  		identityset.Address(27).String(),
   737  		[]byte{}, uint64(100000),
   738  		big.NewInt(10),
   739  	)
   740  	require.NoError(t, err)
   741  
   742  	data, _ := hex.DecodeString("608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a7230582002faabbefbbda99b20217cf33cb8ab8100caf1542bf1f48117d72e2c59139aea0029")
   743  	execution, err := action.NewExecution(action.EmptyAddress, 2, big.NewInt(0), uint64(100000), big.NewInt(0), data)
   744  	require.NoError(t, err)
   745  
   746  	bd := &action.EnvelopeBuilder{}
   747  	elp1 := bd.SetAction(tsf).
   748  		SetNonce(1).
   749  		SetGasLimit(100000).
   750  		SetGasPrice(big.NewInt(10)).Build()
   751  	selp1, err := action.Sign(elp1, identityset.PrivateKey(0))
   752  	require.NoError(t, err)
   753  	require.NoError(t, ap.Add(ctx, selp1))
   754  	// This execution should not be included in block because block is out of gas
   755  	elp2 := bd.SetAction(execution).
   756  		SetNonce(2).
   757  		SetGasLimit(100000).
   758  		SetGasPrice(big.NewInt(10)).Build()
   759  	selp2, err := action.Sign(elp2, identityset.PrivateKey(0))
   760  	require.NoError(t, err)
   761  	require.NoError(t, ap.Add(ctx, selp2))
   762  
   763  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
   764  	require.NoError(t, err)
   765  	require.Equal(t, 2, len(blk.Actions))
   766  	require.Equal(t, 2, len(blk.Receipts))
   767  	var gasConsumed uint64
   768  	for _, receipt := range blk.Receipts {
   769  		gasConsumed += receipt.GasConsumed
   770  	}
   771  	require.True(t, gasConsumed <= cfg.Genesis.BlockGasLimit)
   772  }
   773  
   774  func TestBlockchain_MintNewBlock_PopAccount(t *testing.T) {
   775  	cfg := config.Default
   776  	cfg.Genesis.EnableGravityChainVoting = false
   777  	cfg.ActPool.MinGasPriceStr = "0"
   778  	ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
   779  	registry := protocol.NewRegistry()
   780  	acc := account.NewProtocol(rewarding.DepositGas)
   781  	require.NoError(t, acc.Register(registry))
   782  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   783  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
   784  	require.NoError(t, err)
   785  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   786  	require.NoError(t, err)
   787  	store, err := filedao.NewFileDAOInMemForTest()
   788  	require.NoError(t, err)
   789  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
   790  	bc := blockchain.NewBlockchain(
   791  		cfg.Chain,
   792  		cfg.Genesis,
   793  		dao,
   794  		factory.NewMinter(sf, ap),
   795  		blockchain.BlockValidatorOption(block.NewValidator(
   796  			sf,
   797  			protocol.NewGenericValidator(sf, accountutil.AccountState),
   798  		)),
   799  	)
   800  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   801  	require.NoError(t, rp.Register(registry))
   802  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   803  	require.NoError(t, ep.Register(registry))
   804  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   805  	require.NoError(t, rewardingProtocol.Register(registry))
   806  	require.NoError(t, bc.Start(ctx))
   807  	defer func() {
   808  		require.NoError(t, bc.Stop(ctx))
   809  	}()
   810  
   811  	priKey0 := identityset.PrivateKey(27)
   812  	addr1 := identityset.Address(28).String()
   813  	priKey3 := identityset.PrivateKey(30)
   814  	require.NoError(t, addTestingTsfBlocks(cfg, bc, nil, ap))
   815  
   816  	// test third block
   817  	bytes := []byte{}
   818  	for i := 0; i < 1000; i++ {
   819  		bytes = append(bytes, 1)
   820  	}
   821  	for i := uint64(0); i < 300; i++ {
   822  		tsf, err := action.SignedTransfer(addr1, priKey0, i+7, big.NewInt(2), bytes,
   823  			19000, big.NewInt(testutil.TestGasPriceInt64))
   824  		require.NoError(t, err)
   825  		require.NoError(t, ap.Add(ctx, tsf))
   826  	}
   827  	transfer1, err := action.SignedTransfer(addr1, priKey3, 7, big.NewInt(2),
   828  		[]byte{}, 10000, big.NewInt(testutil.TestGasPriceInt64))
   829  	require.NoError(t, err)
   830  	require.NoError(t, ap.Add(ctx, transfer1))
   831  
   832  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
   833  	require.NoError(t, err)
   834  	require.NotNil(t, blk)
   835  	require.Equal(t, 183, len(blk.Actions))
   836  	whetherInclude := false
   837  	for _, action := range blk.Actions {
   838  		transfer1Hash, err := transfer1.Hash()
   839  		require.NoError(t, err)
   840  		actionHash, err := action.Hash()
   841  		require.NoError(t, err)
   842  		if transfer1Hash == actionHash {
   843  			whetherInclude = true
   844  			break
   845  		}
   846  	}
   847  	require.True(t, whetherInclude)
   848  }
   849  
   850  type MockSubscriber struct {
   851  	counter int32
   852  }
   853  
   854  func (ms *MockSubscriber) ReceiveBlock(blk *block.Block) error {
   855  	tsfs, _ := classifyActions(blk.Actions)
   856  	atomic.AddInt32(&ms.counter, int32(len(tsfs)))
   857  	return nil
   858  }
   859  
   860  func (ms *MockSubscriber) Counter() int {
   861  	return int(atomic.LoadInt32(&ms.counter))
   862  }
   863  
   864  func createChain(cfg config.Config, inMem bool) (blockchain.Blockchain, factory.Factory, blockdao.BlockDAO, actpool.ActPool, error) {
   865  	registry := protocol.NewRegistry()
   866  	// Create a blockchain from scratch
   867  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
   868  	var (
   869  		sf  factory.Factory
   870  		dao blockdao.BlockDAO
   871  		err error
   872  	)
   873  	if inMem {
   874  		sf, err = factory.NewStateDB(factoryCfg, db.NewMemKVStore(), factory.RegistryStateDBOption(registry))
   875  	} else {
   876  		db2, err := db.CreateKVStore(cfg.DB, cfg.Chain.TrieDBPath)
   877  		if err != nil {
   878  			return nil, nil, nil, nil, err
   879  		}
   880  		sf, err = factory.NewStateDB(factoryCfg, db2, factory.RegistryStateDBOption(registry))
   881  	}
   882  	if err != nil {
   883  		return nil, nil, nil, nil, err
   884  	}
   885  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
   886  	if err != nil {
   887  		return nil, nil, nil, nil, err
   888  	}
   889  	ap.AddActionEnvelopeValidators(
   890  		protocol.NewGenericValidator(sf, accountutil.AccountState),
   891  	)
   892  	acc := account.NewProtocol(rewarding.DepositGas)
   893  	if err = acc.Register(registry); err != nil {
   894  		return nil, nil, nil, nil, err
   895  	}
   896  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
   897  	if err = rp.Register(registry); err != nil {
   898  		return nil, nil, nil, nil, err
   899  	}
   900  	// create indexer
   901  	cfg.DB.DbPath = cfg.Chain.IndexDBPath
   902  	indexer, err := blockindex.NewIndexer(db.NewBoltDB(cfg.DB), cfg.Genesis.Hash())
   903  	if err != nil {
   904  		return nil, nil, nil, nil, err
   905  	}
   906  	var store blockdao.BlockDAO
   907  	// create BlockDAO
   908  	if inMem {
   909  		store, err = filedao.NewFileDAOInMemForTest()
   910  		if err != nil {
   911  			return nil, nil, nil, nil, err
   912  		}
   913  	} else {
   914  		cfg.DB.DbPath = cfg.Chain.ChainDBPath
   915  		store, err = filedao.NewFileDAO(cfg.DB, block.NewDeserializer(cfg.Chain.EVMNetworkID))
   916  	}
   917  	if err != nil {
   918  		return nil, nil, nil, nil, err
   919  	}
   920  	dao = blockdao.NewBlockDAOWithIndexersAndCache(
   921  		store,
   922  		[]blockdao.BlockIndexer{sf, indexer},
   923  		cfg.DB.MaxCacheSize,
   924  	)
   925  	if dao == nil {
   926  		return nil, nil, nil, nil, err
   927  	}
   928  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
   929  	if err = ep.Register(registry); err != nil {
   930  		return nil, nil, nil, nil, err
   931  	}
   932  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
   933  	if err = rewardingProtocol.Register(registry); err != nil {
   934  		return nil, nil, nil, nil, err
   935  	}
   936  	return blockchain.NewBlockchain(
   937  		cfg.Chain,
   938  		cfg.Genesis,
   939  		dao,
   940  		factory.NewMinter(sf, ap),
   941  		blockchain.BlockValidatorOption(block.NewValidator(
   942  			sf,
   943  			protocol.NewGenericValidator(sf, accountutil.AccountState),
   944  		)),
   945  	), sf, dao, ap, nil
   946  }
   947  
   948  func TestConvertCleanAddress(t *testing.T) {
   949  	require := require.New(t)
   950  
   951  	cfg := config.Default
   952  	testIndexPath, err := testutil.PathOfTempFile("index")
   953  	require.NoError(err)
   954  
   955  	defer func() {
   956  		testutil.CleanupPath(testIndexPath)
   957  		// clear the gateway
   958  		delete(cfg.Plugins, config.GatewayPlugin)
   959  	}()
   960  
   961  	minGas := big.NewInt(unit.Qev)
   962  	cfg.Chain.IndexDBPath = testIndexPath
   963  	cfg.Chain.ProducerPrivKey = "a000000000000000000000000000000000000000000000000000000000000000"
   964  	cfg.Genesis.EnableGravityChainVoting = false
   965  	cfg.Plugins[config.GatewayPlugin] = true
   966  	cfg.Chain.EnableAsyncIndexWrite = false
   967  	cfg.ActPool.MinGasPriceStr = minGas.String()
   968  	cfg.Genesis.PacificBlockHeight = 2
   969  	cfg.Genesis.AleutianBlockHeight = 2
   970  	cfg.Genesis.BeringBlockHeight = 2
   971  	cfg.Genesis.CookBlockHeight = 2
   972  	cfg.Genesis.DaytonaBlockHeight = 2
   973  	cfg.Genesis.DardanellesBlockHeight = 2
   974  	cfg.Genesis.EasterBlockHeight = 2
   975  	cfg.Genesis.FbkMigrationBlockHeight = 2
   976  	cfg.Genesis.FairbankBlockHeight = 2
   977  	cfg.Genesis.GreenlandBlockHeight = 2
   978  	cfg.Genesis.HawaiiBlockHeight = 2
   979  	cfg.Genesis.IcelandBlockHeight = 2
   980  	cfg.Genesis.JutlandBlockHeight = 2
   981  	cfg.Genesis.KamchatkaBlockHeight = 2
   982  	cfg.Genesis.LordHoweBlockHeight = 2
   983  	cfg.Genesis.MidwayBlockHeight = 2
   984  	cfg.Genesis.NewfoundlandBlockHeight = 2
   985  	cfg.Genesis.OkhotskBlockHeight = 2
   986  	cfg.Genesis.PalauBlockHeight = 2
   987  	cfg.Genesis.QuebecBlockHeight = 2
   988  	cfg.Genesis.RedseaBlockHeight = 2
   989  	cfg.Genesis.SumatraBlockHeight = 2
   990  	cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
   991  
   992  	ctx := context.Background()
   993  	bc, sf, dao, ap, err := createChain(cfg, true)
   994  	require.NoError(err)
   995  	require.NoError(bc.Start(ctx))
   996  	defer func() {
   997  		require.NoError(bc.Stop(ctx))
   998  	}()
   999  
  1000  	// Add block 1
  1001  	nonce, err := ap.GetPendingNonce(identityset.Address(27).String())
  1002  	require.NoError(err)
  1003  	require.EqualValues(1, nonce)
  1004  	nonce, err = ap.GetPendingNonce(identityset.Address(25).String())
  1005  	require.NoError(err)
  1006  	require.EqualValues(1, nonce)
  1007  	priKey0 := identityset.PrivateKey(27)
  1008  	ex1, err := action.SignedExecution(action.EmptyAddress, priKey0, 1, new(big.Int), 500000, minGas, _constantinopleOpCodeContract)
  1009  	require.NoError(err)
  1010  	h, _ := ex1.Hash()
  1011  	require.NoError(ap.Add(ctx, ex1))
  1012  	tsf1, err := action.SignedTransfer(identityset.Address(25).String(), priKey0, 2, big.NewInt(10000), nil, 500000, minGas)
  1013  	require.NoError(err)
  1014  	require.NoError(ap.Add(ctx, tsf1))
  1015  	tsf2, err := action.SignedTransfer(identityset.Address(24).String(), priKey0, 3, big.NewInt(10000), nil, 500000, minGas)
  1016  	require.NoError(err)
  1017  	require.NoError(ap.Add(ctx, tsf2))
  1018  	deterministic, err := address.FromHex("3fab184622dc19b6109349b94811493bf2a45362")
  1019  	require.NoError(err)
  1020  	tsf3, err := action.SignedTransfer(deterministic.String(), priKey0, 4, big.NewInt(10000000000000000), nil, 500000, minGas)
  1021  	require.NoError(err)
  1022  	require.NoError(ap.Add(ctx, tsf3))
  1023  	blockTime := time.Unix(1546329600, 0)
  1024  	blk, err := bc.MintNewBlock(blockTime)
  1025  	require.NoError(err)
  1026  	require.EqualValues(1, blk.Height())
  1027  	require.Equal(5, len(blk.Body.Actions))
  1028  	require.NoError(bc.CommitBlock(blk))
  1029  
  1030  	// get deployed contract address
  1031  	var r *action.Receipt
  1032  	if dao != nil {
  1033  		r, err = receiptByActionHash(dao, 1, h)
  1034  		require.NoError(err)
  1035  	}
  1036  
  1037  	// verify 3 recipients remain legacy fresh accounts
  1038  	for _, v := range []struct {
  1039  		a address.Address
  1040  		b string
  1041  	}{
  1042  		{identityset.Address(24), "100000000000000000000010000"},
  1043  		{identityset.Address(25), "100000000000000000000010000"},
  1044  		{deterministic, "10000000000000000"},
  1045  	} {
  1046  		a, err := accountutil.AccountState(ctx, sf, v.a)
  1047  		require.NoError(err)
  1048  		require.True(a.IsLegacyFreshAccount())
  1049  		require.EqualValues(1, a.PendingNonce())
  1050  		require.Equal(v.b, a.Balance.String())
  1051  		// actpool returns nonce considering legacy fresh account
  1052  		nonce, err = ap.GetPendingNonce(v.a.String())
  1053  		require.NoError(err)
  1054  		require.Zero(nonce)
  1055  	}
  1056  
  1057  	// Add block 2
  1058  	t1, _ := action.NewTransfer(0, big.NewInt(100), identityset.Address(27).String(), nil, 500000, minGas)
  1059  	elp := (&action.EnvelopeBuilder{}).SetNonce(t1.Nonce()).
  1060  		SetChainID(cfg.Chain.ID).
  1061  		SetGasPrice(t1.GasPrice()).
  1062  		SetGasLimit(t1.GasLimit()).
  1063  		SetAction(t1).Build()
  1064  	tsf1, err = action.Sign(elp, identityset.PrivateKey(25))
  1065  	require.NoError(err)
  1066  	require.NoError(ap.Add(ctx, tsf1))
  1067  	t2, _ := action.NewTransfer(1, big.NewInt(200), identityset.Address(27).String(), nil, 500000, minGas)
  1068  	elp = (&action.EnvelopeBuilder{}).SetNonce(t2.Nonce()).
  1069  		SetChainID(cfg.Chain.ID).
  1070  		SetGasPrice(t2.GasPrice()).
  1071  		SetGasLimit(t2.GasLimit()).
  1072  		SetAction(t2).Build()
  1073  	tsf2, err = action.Sign(elp, identityset.PrivateKey(25))
  1074  	require.NoError(err)
  1075  	require.NoError(ap.Add(ctx, tsf2))
  1076  	// call set() to set storedData = 0xfe...1f40
  1077  	funcSig := hash.Hash256b([]byte("set(uint256)"))
  1078  	data := append(funcSig[:4], _setTopic...)
  1079  	e1, _ := action.NewExecution(r.ContractAddress, 0, new(big.Int), 500000, minGas, data)
  1080  	elp = (&action.EnvelopeBuilder{}).SetNonce(e1.Nonce()).
  1081  		SetChainID(cfg.Chain.ID).
  1082  		SetGasPrice(e1.GasPrice()).
  1083  		SetGasLimit(e1.GasLimit()).
  1084  		SetAction(e1).Build()
  1085  	ex1, err = action.Sign(elp, identityset.PrivateKey(24))
  1086  	require.NoError(err)
  1087  	require.NoError(ap.Add(ctx, ex1))
  1088  	// deterministic deployment transaction
  1089  	tx, err := action.DecodeEtherTx("0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222")
  1090  	require.NoError(err)
  1091  	require.False(tx.Protected())
  1092  	require.Nil(tx.To())
  1093  	require.Equal("100000000000", tx.GasPrice().String())
  1094  	encoding, sig, pubkey, err := action.ExtractTypeSigPubkey(tx)
  1095  	require.NoError(err)
  1096  	require.Equal(iotextypes.Encoding_ETHEREUM_UNPROTECTED, encoding)
  1097  	// convert tx to envelope
  1098  	elp, err = (&action.EnvelopeBuilder{}).SetChainID(cfg.Chain.ID).BuildExecution(tx)
  1099  	require.NoError(err)
  1100  	ex2, err := (&action.Deserializer{}).SetEvmNetworkID(cfg.Chain.EVMNetworkID).
  1101  		ActionToSealedEnvelope(&iotextypes.Action{
  1102  			Core:         elp.Proto(),
  1103  			SenderPubKey: pubkey.Bytes(),
  1104  			Signature:    sig,
  1105  			Encoding:     encoding,
  1106  		})
  1107  	require.NoError(err)
  1108  	require.True(address.Equal(ex2.SenderAddress(), deterministic))
  1109  	require.True(cfg.Genesis.IsDeployerWhitelisted(ex2.SenderAddress()))
  1110  	require.NoError(ap.Add(ctx, ex2))
  1111  	blockTime = blockTime.Add(time.Second)
  1112  	blk1, err := bc.MintNewBlock(blockTime)
  1113  	require.NoError(err)
  1114  	require.EqualValues(2, blk1.Height())
  1115  	require.Equal(5, len(blk1.Body.Actions))
  1116  	require.NoError(bc.CommitBlock(blk1))
  1117  
  1118  	// 3 legacy fresh accounts are converted to zero-nonce account
  1119  	for _, v := range []struct {
  1120  		a     address.Address
  1121  		nonce uint64
  1122  		b     string
  1123  	}{
  1124  		{identityset.Address(24), 1, "99999999962880000000010000"},
  1125  		{identityset.Address(25), 2, "99999999980000000000009700"},
  1126  		{deterministic, 1, "6786100000000000"},
  1127  	} {
  1128  		a, err := accountutil.AccountState(ctx, sf, v.a)
  1129  		require.NoError(err)
  1130  		require.EqualValues(1, a.AccountType())
  1131  		require.Equal(v.nonce, a.PendingNonce())
  1132  		require.Equal(v.b, a.Balance.String())
  1133  	}
  1134  
  1135  	// verify contract execution
  1136  	h, err = ex1.Hash()
  1137  	require.NoError(err)
  1138  	r, err = receiptByActionHash(dao, 2, h)
  1139  	require.NoError(err)
  1140  	require.EqualValues(iotextypes.ReceiptStatus_Success, r.Status)
  1141  	require.EqualValues(2, r.BlockHeight)
  1142  	require.Equal(h, r.ActionHash)
  1143  	require.EqualValues(37120, r.GasConsumed)
  1144  	require.Empty(r.ContractAddress)
  1145  
  1146  	// verify deterministic deployment transaction
  1147  	h, err = ex2.Hash()
  1148  	require.NoError(err)
  1149  	require.Equal("eddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26", hex.EncodeToString(h[:]))
  1150  	r, err = receiptByActionHash(dao, 2, h)
  1151  	require.NoError(err)
  1152  	require.EqualValues(iotextypes.ReceiptStatus_Success, r.Status)
  1153  	require.EqualValues(2, r.BlockHeight)
  1154  	require.Equal(h, r.ActionHash)
  1155  	require.EqualValues(32139, r.GasConsumed)
  1156  	require.Equal("io1fevmgjz8kdu40pvgjgx20ralymqtf9tv3mdu7f", r.ContractAddress)
  1157  	tl, err := dao.TransactionLogs(2)
  1158  	require.NoError(err)
  1159  	require.Equal(4, len(tl.Logs))
  1160  
  1161  	// commit 2 blocks to a new chain
  1162  	testTriePath2, err := testutil.PathOfTempFile("trie")
  1163  	require.NoError(err)
  1164  	testDBPath2, err := testutil.PathOfTempFile("db")
  1165  	require.NoError(err)
  1166  	testIndexPath2, err := testutil.PathOfTempFile("index")
  1167  	require.NoError(err)
  1168  
  1169  	defer func() {
  1170  		testutil.CleanupPath(testTriePath2)
  1171  		testutil.CleanupPath(testDBPath2)
  1172  		testutil.CleanupPath(testIndexPath2)
  1173  		// clear the gateway
  1174  		delete(cfg.Plugins, config.GatewayPlugin)
  1175  	}()
  1176  
  1177  	cfg.Chain.TrieDBPath = testTriePath2
  1178  	cfg.Chain.ChainDBPath = testDBPath2
  1179  	cfg.Chain.IndexDBPath = testIndexPath2
  1180  	bc2, sf2, dao2, _, err := createChain(cfg, false)
  1181  	require.NoError(err)
  1182  	require.NoError(bc2.Start(ctx))
  1183  	defer func() {
  1184  		require.NoError(bc2.Stop(ctx))
  1185  	}()
  1186  	require.NoError(bc2.CommitBlock(blk))
  1187  	require.NoError(bc2.CommitBlock(blk1))
  1188  
  1189  	// 3 legacy fresh accounts are converted to zero-nonce account
  1190  	for _, v := range []struct {
  1191  		a     address.Address
  1192  		nonce uint64
  1193  		b     string
  1194  	}{
  1195  		{identityset.Address(24), 1, "99999999962880000000010000"},
  1196  		{identityset.Address(25), 2, "99999999980000000000009700"},
  1197  		{deterministic, 1, "6786100000000000"},
  1198  	} {
  1199  		a, err := accountutil.AccountState(ctx, sf2, v.a)
  1200  		require.NoError(err)
  1201  		require.EqualValues(1, a.AccountType())
  1202  		require.EqualValues(v.nonce, a.PendingNonce())
  1203  		require.Equal(v.b, a.Balance.String())
  1204  	}
  1205  
  1206  	// verify deterministic deployment transaction
  1207  	r, err = receiptByActionHash(dao2, 2, h)
  1208  	require.NoError(err)
  1209  	require.EqualValues(iotextypes.ReceiptStatus_Success, r.Status)
  1210  	require.EqualValues(2, r.BlockHeight)
  1211  	require.Equal(h, r.ActionHash)
  1212  	require.EqualValues(32139, r.GasConsumed)
  1213  	require.Equal("io1fevmgjz8kdu40pvgjgx20ralymqtf9tv3mdu7f", r.ContractAddress)
  1214  	tl, err = dao2.TransactionLogs(2)
  1215  	require.NoError(err)
  1216  	require.Equal(4, len(tl.Logs))
  1217  }
  1218  
  1219  func TestConstantinople(t *testing.T) {
  1220  	require := require.New(t)
  1221  	testValidateBlockchain := func(cfg config.Config, t *testing.T) {
  1222  		ctx := context.Background()
  1223  
  1224  		registry := protocol.NewRegistry()
  1225  		// Create a blockchain from scratch
  1226  		factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1227  		db2, err := db.CreateKVStore(cfg.DB, cfg.Chain.TrieDBPath)
  1228  		require.NoError(err)
  1229  		sf, err := factory.NewFactory(factoryCfg, db2, factory.RegistryOption(registry))
  1230  		require.NoError(err)
  1231  		ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1232  		require.NoError(err)
  1233  		acc := account.NewProtocol(rewarding.DepositGas)
  1234  		require.NoError(acc.Register(registry))
  1235  		rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
  1236  		require.NoError(rp.Register(registry))
  1237  		// create indexer
  1238  		cfg.DB.DbPath = cfg.Chain.IndexDBPath
  1239  		indexer, err := blockindex.NewIndexer(db.NewBoltDB(cfg.DB), cfg.Genesis.Hash())
  1240  		require.NoError(err)
  1241  		// create BlockDAO
  1242  		cfg.DB.DbPath = cfg.Chain.ChainDBPath
  1243  		store, err := filedao.NewFileDAO(cfg.DB, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  1244  		require.NoError(err)
  1245  		dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf, indexer}, cfg.DB.MaxCacheSize)
  1246  		require.NotNil(dao)
  1247  		bc := blockchain.NewBlockchain(
  1248  			cfg.Chain,
  1249  			cfg.Genesis,
  1250  			dao,
  1251  			factory.NewMinter(sf, ap),
  1252  			blockchain.BlockValidatorOption(block.NewValidator(
  1253  				sf,
  1254  				protocol.NewGenericValidator(sf, accountutil.AccountState),
  1255  			)),
  1256  		)
  1257  		ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
  1258  		require.NoError(ep.Register(registry))
  1259  		rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
  1260  		require.NoError(rewardingProtocol.Register(registry))
  1261  		require.NoError(bc.Start(ctx))
  1262  		defer func() {
  1263  			require.NoError(bc.Stop(ctx))
  1264  		}()
  1265  
  1266  		require.NoError(addTestingConstantinopleBlocks(bc, dao, sf, ap))
  1267  
  1268  		// reason to use hard-coded hash value here:
  1269  		// this test TestConstantinople() is added when we upgrade our EVM to enable Constantinople
  1270  		// at that time, the test is run with both EVM version (Byzantium vs. Constantinople), and it generates the
  1271  		// same exact block hash, so these values stood as gatekeeper for backward-compatibility
  1272  		hashTopic := []struct {
  1273  			height  uint64
  1274  			h       hash.Hash256
  1275  			blkHash string
  1276  			topic   []byte
  1277  		}{
  1278  			{
  1279  				1,
  1280  				_deployHash,
  1281  				"2861aecf2b3f91822de00c9f42ca44276e386ac693df363770783bfc133346c3",
  1282  				nil,
  1283  			},
  1284  			{
  1285  				2,
  1286  				_setHash,
  1287  				"cb0f7895c1fa4f179c0c109835b160d9d1852fce526e12c6b443e86257cadb48",
  1288  				_setTopic,
  1289  			},
  1290  			{
  1291  				3,
  1292  				_shrHash,
  1293  				"c1337e26e157426dd0af058ed37e329d25dd3e34ed606994a6776b59f988f458",
  1294  				_shrTopic,
  1295  			},
  1296  			{
  1297  				4,
  1298  				_shlHash,
  1299  				"cf5c2050a261fa7eca45f31a184c6cd1dc737c7fc3088a0983f659b08985521c",
  1300  				_shlTopic,
  1301  			},
  1302  			{
  1303  				5,
  1304  				_sarHash,
  1305  				"5d76bd9e4be3a60c00761fd141da6bd9c07ab73f472f537845b65679095b0570",
  1306  				_sarTopic,
  1307  			},
  1308  			{
  1309  				6,
  1310  				_extHash,
  1311  				"c5fd9f372b89265f2423737a6d7b680e9759a4a715b22b04ccf875460c310015",
  1312  				_extTopic,
  1313  			},
  1314  			{
  1315  				7,
  1316  				_crt2Hash,
  1317  				"53632287a97e4e118302f2d9b54b3f97f62d3533286c4d4eb955627b3602d3b0",
  1318  				_crt2Topic,
  1319  			},
  1320  		}
  1321  
  1322  		// test getReceipt
  1323  		for _, v := range hashTopic {
  1324  			ai, err := indexer.GetActionIndex(v.h[:])
  1325  			require.NoError(err)
  1326  			require.Equal(v.height, ai.BlockHeight())
  1327  			r, err := receiptByActionHash(dao, v.height, v.h)
  1328  			require.NoError(err)
  1329  			require.NotNil(r)
  1330  			require.Equal(uint64(1), r.Status)
  1331  			require.Equal(v.h, r.ActionHash)
  1332  			require.Equal(v.height, r.BlockHeight)
  1333  			if v.height == 1 {
  1334  				require.Equal("io1va03q4lcr608dr3nltwm64sfcz05czjuycsqgn", r.ContractAddress)
  1335  			} else {
  1336  				require.Empty(r.ContractAddress)
  1337  			}
  1338  			blk, err := dao.GetBlockByHeight(v.height)
  1339  			require.NoError(err)
  1340  			a, _, err := blk.ActionByHash(v.h)
  1341  			require.NoError(err)
  1342  			require.NotNil(a)
  1343  			aHash, err := a.Hash()
  1344  			require.NoError(err)
  1345  			require.Equal(v.h, aHash)
  1346  
  1347  			blkHash, err := dao.GetBlockHash(v.height)
  1348  			require.NoError(err)
  1349  			require.Equal(v.blkHash, hex.EncodeToString(blkHash[:]))
  1350  
  1351  			if v.topic != nil {
  1352  				funcSig := hash.Hash256b([]byte("Set(uint256)"))
  1353  				blk, err := dao.GetBlockByHeight(v.height)
  1354  				require.NoError(err)
  1355  				f := blk.Header.LogsBloomfilter()
  1356  				require.NotNil(f)
  1357  				require.True(f.Exist(funcSig[:]))
  1358  				require.True(f.Exist(v.topic))
  1359  			}
  1360  		}
  1361  
  1362  		storeOutGasTests := []struct {
  1363  			height      uint64
  1364  			actHash     hash.Hash256
  1365  			status      iotextypes.ReceiptStatus
  1366  			preBalance  *big.Int
  1367  			postBalance *big.Int
  1368  		}{
  1369  			{
  1370  				8, _storeHash, iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas, _preGrPreStore, _preGrPostStore,
  1371  			},
  1372  			{
  1373  				9, _store2Hash, iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas, _preGrPostStore, _postGrPostStore,
  1374  			},
  1375  		}
  1376  		caller := identityset.Address(27)
  1377  		for _, v := range storeOutGasTests {
  1378  			r, err := receiptByActionHash(dao, v.height, v.actHash)
  1379  			require.NoError(err)
  1380  			require.EqualValues(v.status, r.Status)
  1381  
  1382  			// verify transaction log
  1383  			bLog, err := dao.TransactionLogs(v.height)
  1384  			require.NoError(err)
  1385  			tLog := bLog.Logs[0]
  1386  			// first transaction log is gas fee
  1387  			tx := tLog.Transactions[0]
  1388  			require.Equal(tx.Sender, caller.String())
  1389  			require.Equal(tx.Recipient, address.RewardingPoolAddr)
  1390  			require.Equal(iotextypes.TransactionLogType_GAS_FEE, tx.Type)
  1391  			gasFee, ok := new(big.Int).SetString(tx.Amount, 10)
  1392  			require.True(ok)
  1393  			postBalance := new(big.Int).Sub(v.preBalance, gasFee)
  1394  
  1395  			if !cfg.Genesis.IsGreenland(v.height) {
  1396  				// pre-Greenland contains a tx with status = ReceiptStatus_ErrCodeStoreOutOfGas
  1397  				// due to a bug the transfer is not reverted
  1398  				require.Equal(2, len(tLog.Transactions))
  1399  				// 2nd log is in-contract-transfer
  1400  				tx = tLog.Transactions[1]
  1401  				require.Equal(tx.Sender, caller.String())
  1402  				require.Equal(iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER, tx.Type)
  1403  				tsfAmount, ok := new(big.Int).SetString(tx.Amount, 10)
  1404  				require.True(ok)
  1405  				postBalance.Sub(postBalance, tsfAmount)
  1406  				// post = pre - gasFee - in_contract_transfer
  1407  				require.Equal(v.postBalance, postBalance)
  1408  			} else {
  1409  				// post-Greenland fixed that bug, the transfer is reverted so it only contains the gas fee
  1410  				require.Equal(1, len(tLog.Transactions))
  1411  				// post = pre - gasFee (transfer is reverted)
  1412  				require.Equal(v.postBalance, postBalance)
  1413  			}
  1414  		}
  1415  
  1416  		// test getActions
  1417  		addr27 := hash.BytesToHash160(caller.Bytes())
  1418  		total, err := indexer.GetActionCountByAddress(addr27)
  1419  		require.NoError(err)
  1420  		require.EqualValues(len(hashTopic)+len(storeOutGasTests), total)
  1421  		actions, err := indexer.GetActionsByAddress(addr27, 0, total)
  1422  		require.NoError(err)
  1423  		require.EqualValues(total, len(actions))
  1424  		for i := range hashTopic {
  1425  			require.Equal(hashTopic[i].h[:], actions[i])
  1426  		}
  1427  		for i := range storeOutGasTests {
  1428  			require.Equal(storeOutGasTests[i].actHash[:], actions[i+len(hashTopic)])
  1429  		}
  1430  	}
  1431  
  1432  	cfg := config.Default
  1433  	testTriePath, err := testutil.PathOfTempFile("trie")
  1434  	require.NoError(err)
  1435  	testDBPath, err := testutil.PathOfTempFile("db")
  1436  	require.NoError(err)
  1437  	testIndexPath, err := testutil.PathOfTempFile("index")
  1438  	require.NoError(err)
  1439  
  1440  	defer func() {
  1441  		testutil.CleanupPath(testTriePath)
  1442  		testutil.CleanupPath(testDBPath)
  1443  		testutil.CleanupPath(testIndexPath)
  1444  		// clear the gateway
  1445  		delete(cfg.Plugins, config.GatewayPlugin)
  1446  	}()
  1447  
  1448  	cfg.Chain.TrieDBPath = testTriePath
  1449  	cfg.Chain.ChainDBPath = testDBPath
  1450  	cfg.Chain.IndexDBPath = testIndexPath
  1451  	cfg.Chain.ProducerPrivKey = "a000000000000000000000000000000000000000000000000000000000000000"
  1452  	cfg.Genesis.EnableGravityChainVoting = false
  1453  	cfg.Plugins[config.GatewayPlugin] = true
  1454  	cfg.Chain.EnableAsyncIndexWrite = false
  1455  	cfg.ActPool.MinGasPriceStr = "0"
  1456  	cfg.Genesis.AleutianBlockHeight = 2
  1457  	cfg.Genesis.BeringBlockHeight = 8
  1458  	cfg.Genesis.GreenlandBlockHeight = 9
  1459  	cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
  1460  
  1461  	t.Run("test Constantinople contract", func(t *testing.T) {
  1462  		testValidateBlockchain(cfg, t)
  1463  	})
  1464  }
  1465  
  1466  func TestLoadBlockchainfromDB(t *testing.T) {
  1467  	require := require.New(t)
  1468  	testValidateBlockchain := func(cfg config.Config, t *testing.T) {
  1469  		ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
  1470  
  1471  		registry := protocol.NewRegistry()
  1472  		// Create a blockchain from scratch
  1473  		factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1474  		db2, err := db.CreateKVStore(cfg.DB, cfg.Chain.TrieDBPath)
  1475  		require.NoError(err)
  1476  		sf, err := factory.NewFactory(factoryCfg, db2, factory.RegistryOption(registry))
  1477  		require.NoError(err)
  1478  		ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1479  		require.NoError(err)
  1480  		acc := account.NewProtocol(rewarding.DepositGas)
  1481  		require.NoError(acc.Register(registry))
  1482  		rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
  1483  		require.NoError(rp.Register(registry))
  1484  		var indexer blockindex.Indexer
  1485  		indexers := []blockdao.BlockIndexer{sf}
  1486  		if _, gateway := cfg.Plugins[config.GatewayPlugin]; gateway && !cfg.Chain.EnableAsyncIndexWrite {
  1487  			// create indexer
  1488  			cfg.DB.DbPath = cfg.Chain.IndexDBPath
  1489  			indexer, err = blockindex.NewIndexer(db.NewBoltDB(cfg.DB), cfg.Genesis.Hash())
  1490  			require.NoError(err)
  1491  			indexers = append(indexers, indexer)
  1492  		}
  1493  		cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
  1494  		// create BlockDAO
  1495  		cfg.DB.DbPath = cfg.Chain.ChainDBPath
  1496  		store, err := filedao.NewFileDAO(cfg.DB, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  1497  		require.NoError(err)
  1498  		dao := blockdao.NewBlockDAOWithIndexersAndCache(store, indexers, cfg.DB.MaxCacheSize)
  1499  		require.NotNil(dao)
  1500  		bc := blockchain.NewBlockchain(
  1501  			cfg.Chain,
  1502  			cfg.Genesis,
  1503  			dao,
  1504  			factory.NewMinter(sf, ap),
  1505  			blockchain.BlockValidatorOption(block.NewValidator(
  1506  				sf,
  1507  				protocol.NewGenericValidator(sf, accountutil.AccountState),
  1508  			)),
  1509  		)
  1510  		ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
  1511  		require.NoError(ep.Register(registry))
  1512  		require.NoError(bc.Start(ctx))
  1513  
  1514  		ms := &MockSubscriber{counter: 0}
  1515  		require.NoError(bc.AddSubscriber(ms))
  1516  		require.Equal(0, ms.Counter())
  1517  
  1518  		height := bc.TipHeight()
  1519  		fmt.Printf("Open blockchain pass, height = %d\n", height)
  1520  		require.NoError(addTestingTsfBlocks(cfg, bc, dao, ap))
  1521  		//make sure pubsub is completed
  1522  		err = testutil.WaitUntil(200*time.Millisecond, 3*time.Second, func() (bool, error) {
  1523  			return 24 == ms.Counter(), nil
  1524  		})
  1525  		require.NoError(err)
  1526  		require.NoError(bc.Stop(ctx))
  1527  
  1528  		// Load a blockchain from DB
  1529  		bc = blockchain.NewBlockchain(
  1530  			cfg.Chain,
  1531  			cfg.Genesis,
  1532  			dao,
  1533  			factory.NewMinter(sf, ap),
  1534  			blockchain.BlockValidatorOption(block.NewValidator(
  1535  				sf,
  1536  				protocol.NewGenericValidator(sf, accountutil.AccountState),
  1537  			)),
  1538  		)
  1539  		require.NoError(bc.Start(ctx))
  1540  		defer func() {
  1541  			require.NoError(bc.Stop(ctx))
  1542  		}()
  1543  
  1544  		// verify block header hash
  1545  		for i := uint64(1); i <= 5; i++ {
  1546  			hash, err := dao.GetBlockHash(i)
  1547  			require.NoError(err)
  1548  			height, err = dao.GetBlockHeight(hash)
  1549  			require.NoError(err)
  1550  			require.Equal(i, height)
  1551  			header, err := bc.BlockHeaderByHeight(height)
  1552  			require.NoError(err)
  1553  			require.Equal(height, header.Height())
  1554  
  1555  			// bloomfilter only exists after aleutian height
  1556  			require.Equal(height >= cfg.Genesis.AleutianBlockHeight, header.LogsBloomfilter() != nil)
  1557  		}
  1558  
  1559  		empblk, err := dao.GetBlock(hash.ZeroHash256)
  1560  		require.Nil(empblk)
  1561  		require.Error(err)
  1562  
  1563  		header, err := bc.BlockHeaderByHeight(60000)
  1564  		require.Nil(header)
  1565  		require.Error(err)
  1566  
  1567  		// add wrong blocks
  1568  		h := bc.TipHeight()
  1569  		blkhash := bc.TipHash()
  1570  		header, err = bc.BlockHeaderByHeight(h)
  1571  		require.NoError(err)
  1572  		require.Equal(blkhash, header.HashBlock())
  1573  		fmt.Printf("Current tip = %d hash = %x\n", h, blkhash)
  1574  
  1575  		// add block with wrong height
  1576  		selp, err := action.SignedTransfer(identityset.Address(29).String(), identityset.PrivateKey(27), 1, big.NewInt(50), nil, genesis.Default.ActionGasLimit, big.NewInt(0))
  1577  		require.NoError(err)
  1578  
  1579  		nblk, err := block.NewTestingBuilder().
  1580  			SetHeight(h + 2).
  1581  			SetPrevBlockHash(blkhash).
  1582  			SetTimeStamp(testutil.TimestampNow()).
  1583  			AddActions(selp).SignAndBuild(identityset.PrivateKey(29))
  1584  		require.NoError(err)
  1585  
  1586  		require.Error(bc.ValidateBlock(&nblk))
  1587  		fmt.Printf("Cannot validate block %d: %v\n", header.Height(), err)
  1588  
  1589  		// add block with zero prev hash
  1590  		selp2, err := action.SignedTransfer(identityset.Address(29).String(), identityset.PrivateKey(27), 1, big.NewInt(50), nil, genesis.Default.ActionGasLimit, big.NewInt(0))
  1591  		require.NoError(err)
  1592  
  1593  		nblk, err = block.NewTestingBuilder().
  1594  			SetHeight(h + 1).
  1595  			SetPrevBlockHash(hash.ZeroHash256).
  1596  			SetTimeStamp(testutil.TimestampNow()).
  1597  			AddActions(selp2).SignAndBuild(identityset.PrivateKey(29))
  1598  		require.NoError(err)
  1599  		err = bc.ValidateBlock(&nblk)
  1600  		require.Error(err)
  1601  		fmt.Printf("Cannot validate block %d: %v\n", header.Height(), err)
  1602  
  1603  		// add existing block again will have no effect
  1604  		blk, err := dao.GetBlockByHeight(3)
  1605  		require.NotNil(blk)
  1606  		require.NoError(err)
  1607  		require.NoError(bc.CommitBlock(blk))
  1608  		fmt.Printf("Cannot add block 3 again: %v\n", err)
  1609  
  1610  		// invalid address returns error
  1611  		_, err = address.FromString("")
  1612  		require.Contains(err.Error(), "address length = 0, expecting 41")
  1613  
  1614  		// valid but unused address should return empty account
  1615  		addr, err := address.FromString("io1066kus4vlyvk0ljql39fzwqw0k22h7j8wmef3n")
  1616  		require.NoError(err)
  1617  		act, err := accountutil.AccountState(ctx, sf, addr)
  1618  		require.NoError(err)
  1619  		require.Equal(uint64(1), act.PendingNonce())
  1620  		require.Equal(big.NewInt(0), act.Balance)
  1621  
  1622  		_, gateway := cfg.Plugins[config.GatewayPlugin]
  1623  		if gateway && !cfg.Chain.EnableAsyncIndexWrite {
  1624  			// verify deployed contract
  1625  			ai, err := indexer.GetActionIndex(_deployHash[:])
  1626  			require.NoError(err)
  1627  			r, err := receiptByActionHash(dao, ai.BlockHeight(), _deployHash)
  1628  			require.NoError(err)
  1629  			require.NotNil(r)
  1630  			require.Equal(uint64(1), r.Status)
  1631  			require.Equal(uint64(2), r.BlockHeight)
  1632  
  1633  			// 2 topics in block 3 calling set()
  1634  			funcSig := hash.Hash256b([]byte("Set(uint256)"))
  1635  			blk, err := dao.GetBlockByHeight(3)
  1636  			require.NoError(err)
  1637  			f := blk.Header.LogsBloomfilter()
  1638  			require.NotNil(f)
  1639  			require.True(f.Exist(funcSig[:]))
  1640  			require.True(f.Exist(_setTopic))
  1641  			r, err = receiptByActionHash(dao, 3, _setHash)
  1642  			require.NoError(err)
  1643  			require.EqualValues(1, r.Status)
  1644  			require.EqualValues(3, r.BlockHeight)
  1645  			require.Empty(r.ContractAddress)
  1646  
  1647  			// 3 topics in block 4 calling get()
  1648  			funcSig = hash.Hash256b([]byte("Get(address,uint256)"))
  1649  			blk, err = dao.GetBlockByHeight(4)
  1650  			require.NoError(err)
  1651  			f = blk.Header.LogsBloomfilter()
  1652  			require.NotNil(f)
  1653  			require.True(f.Exist(funcSig[:]))
  1654  			require.True(f.Exist(_setTopic))
  1655  			require.True(f.Exist(_getTopic))
  1656  			r, err = receiptByActionHash(dao, 4, _sarHash)
  1657  			require.NoError(err)
  1658  			require.EqualValues(1, r.Status)
  1659  			require.EqualValues(4, r.BlockHeight)
  1660  			require.Empty(r.ContractAddress)
  1661  
  1662  			// txIndex/logIndex corrected in block 5
  1663  			blk, err = dao.GetBlockByHeight(5)
  1664  			require.NoError(err)
  1665  			verifyTxLogIndex(require, dao, blk, 10, 2)
  1666  
  1667  			// verify genesis block index
  1668  			bi, err := indexer.GetBlockIndex(0)
  1669  			require.NoError(err)
  1670  			require.Equal(cfg.Genesis.Hash(), hash.BytesToHash256(bi.Hash()))
  1671  			require.EqualValues(0, bi.NumAction())
  1672  			require.Equal(big.NewInt(0), bi.TsfAmount())
  1673  
  1674  			for h := uint64(1); h <= 5; h++ {
  1675  				// verify getting number of actions
  1676  				blk, err = dao.GetBlockByHeight(h)
  1677  				require.NoError(err)
  1678  				blkIndex, err := indexer.GetBlockIndex(h)
  1679  				require.NoError(err)
  1680  				require.EqualValues(blkIndex.NumAction(), len(blk.Actions))
  1681  
  1682  				// verify getting transfer amount
  1683  				tsfs, _ := classifyActions(blk.Actions)
  1684  				tsfa := big.NewInt(0)
  1685  				for _, tsf := range tsfs {
  1686  					tsfa.Add(tsfa, tsf.Amount())
  1687  				}
  1688  				require.Equal(blkIndex.TsfAmount(), tsfa)
  1689  			}
  1690  		}
  1691  	}
  1692  
  1693  	testTriePath, err := testutil.PathOfTempFile("trie")
  1694  	require.NoError(err)
  1695  	testDBPath, err := testutil.PathOfTempFile("db")
  1696  	require.NoError(err)
  1697  	testIndexPath, err := testutil.PathOfTempFile("index")
  1698  	require.NoError(err)
  1699  
  1700  	defer func() {
  1701  		testutil.CleanupPath(testTriePath)
  1702  		testutil.CleanupPath(testDBPath)
  1703  		testutil.CleanupPath(testIndexPath)
  1704  	}()
  1705  
  1706  	cfg := config.Default
  1707  	cfg.Chain.TrieDBPath = testTriePath
  1708  	cfg.Chain.ChainDBPath = testDBPath
  1709  	cfg.Chain.IndexDBPath = testIndexPath
  1710  	cfg.Genesis.EnableGravityChainVoting = false
  1711  	cfg.ActPool.MinGasPriceStr = "0"
  1712  	genesis.SetGenesisTimestamp(cfg.Genesis.Timestamp)
  1713  	block.LoadGenesisHash(&genesis.Default)
  1714  
  1715  	t.Run("load blockchain from DB w/o explorer", func(t *testing.T) {
  1716  		testValidateBlockchain(cfg, t)
  1717  	})
  1718  
  1719  	testTriePath2, err := testutil.PathOfTempFile("trie")
  1720  	require.NoError(err)
  1721  	testDBPath2, err := testutil.PathOfTempFile("db")
  1722  	require.NoError(err)
  1723  	testIndexPath2, err := testutil.PathOfTempFile("index")
  1724  	require.NoError(err)
  1725  
  1726  	defer func() {
  1727  		testutil.CleanupPath(testTriePath2)
  1728  		testutil.CleanupPath(testDBPath2)
  1729  		testutil.CleanupPath(testIndexPath2)
  1730  		// clear the gateway
  1731  		delete(cfg.Plugins, config.GatewayPlugin)
  1732  	}()
  1733  
  1734  	cfg.Plugins[config.GatewayPlugin] = true
  1735  	cfg.Chain.TrieDBPath = testTriePath2
  1736  	cfg.Chain.ChainDBPath = testDBPath2
  1737  	cfg.Chain.IndexDBPath = testIndexPath2
  1738  	// test using sm2 signature
  1739  	cfg.Chain.SignatureScheme = []string{blockchain.SigP256sm2}
  1740  	cfg.Chain.ProducerPrivKey = "308193020100301306072a8648ce3d020106082a811ccf5501822d0479307702010104202d57ec7da578b98dad465997748ed02af0c69092ad809598073e5a2356c20492a00a06082a811ccf5501822da14403420004223356f0c6f40822ade24d47b0cd10e9285402cbc8a5028a8eec9efba44b8dfe1a7e8bc44953e557b32ec17039fb8018a58d48c8ffa54933fac8030c9a169bf6"
  1741  	cfg.Chain.EnableAsyncIndexWrite = false
  1742  	cfg.Genesis.AleutianBlockHeight = 3
  1743  	cfg.Genesis.MidwayBlockHeight = 5
  1744  
  1745  	t.Run("load blockchain from DB", func(t *testing.T) {
  1746  		testValidateBlockchain(cfg, t)
  1747  	})
  1748  }
  1749  
  1750  // verify the block contains all tx/log indices up to txIndex and logIndex
  1751  func verifyTxLogIndex(r *require.Assertions, dao blockdao.BlockDAO, blk *block.Block, txIndex int, logIndex uint32) {
  1752  	r.Equal(txIndex, len(blk.Actions))
  1753  	receipts, err := dao.GetReceipts(blk.Height())
  1754  	r.NoError(err)
  1755  	r.Equal(txIndex, len(receipts))
  1756  
  1757  	logs := make(map[uint32]bool)
  1758  	for i := uint32(0); i < logIndex; i++ {
  1759  		logs[i] = true
  1760  	}
  1761  	for i, v := range receipts {
  1762  		r.EqualValues(1, v.Status)
  1763  		r.EqualValues(i, v.TxIndex)
  1764  		h, err := blk.Actions[i].Hash()
  1765  		r.NoError(err)
  1766  		r.Equal(h, v.ActionHash)
  1767  		// verify log index
  1768  		for _, l := range v.Logs() {
  1769  			r.Equal(h, l.ActionHash)
  1770  			r.EqualValues(i, l.TxIndex)
  1771  			r.True(logs[l.Index])
  1772  			delete(logs, l.Index)
  1773  		}
  1774  	}
  1775  	r.Zero(len(logs))
  1776  }
  1777  
  1778  func TestBlockchainInitialCandidate(t *testing.T) {
  1779  	require := require.New(t)
  1780  
  1781  	testTriePath, err := testutil.PathOfTempFile("trie")
  1782  	require.NoError(err)
  1783  	testDBPath, err := testutil.PathOfTempFile("db")
  1784  	require.NoError(err)
  1785  	testIndexPath, err := testutil.PathOfTempFile("index")
  1786  	require.NoError(err)
  1787  
  1788  	cfg := config.Default
  1789  	cfg.Chain.TrieDBPath = testTriePath
  1790  	cfg.Chain.ChainDBPath = testDBPath
  1791  	cfg.Chain.IndexDBPath = testIndexPath
  1792  	cfg.Consensus.Scheme = config.RollDPoSScheme
  1793  	registry := protocol.NewRegistry()
  1794  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1795  	db2, err := db.CreateKVStore(cfg.DB, cfg.Chain.TrieDBPath)
  1796  	require.NoError(err)
  1797  	sf, err := factory.NewFactory(factoryCfg, db2, factory.RegistryOption(registry))
  1798  	require.NoError(err)
  1799  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1800  	require.NoError(err)
  1801  	accountProtocol := account.NewProtocol(rewarding.DepositGas)
  1802  	require.NoError(accountProtocol.Register(registry))
  1803  	dbcfg := cfg.DB
  1804  	dbcfg.DbPath = cfg.Chain.ChainDBPath
  1805  	store, err := filedao.NewFileDAO(dbcfg, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  1806  	require.NoError(err)
  1807  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, dbcfg.MaxCacheSize)
  1808  	bc := blockchain.NewBlockchain(
  1809  		cfg.Chain,
  1810  		cfg.Genesis,
  1811  		dao,
  1812  		factory.NewMinter(sf, ap),
  1813  		blockchain.BlockValidatorOption(sf),
  1814  	)
  1815  	rolldposProtocol := rolldpos.NewProtocol(
  1816  		genesis.Default.NumCandidateDelegates,
  1817  		genesis.Default.NumDelegates,
  1818  		genesis.Default.NumSubEpochs,
  1819  	)
  1820  	require.NoError(rolldposProtocol.Register(registry))
  1821  	rewardingProtocol := rewarding.NewProtocol(cfg.Genesis.Rewarding)
  1822  	require.NoError(rewardingProtocol.Register(registry))
  1823  	pollProtocol := poll.NewLifeLongDelegatesProtocol(cfg.Genesis.Delegates)
  1824  	require.NoError(pollProtocol.Register(registry))
  1825  
  1826  	require.NoError(bc.Start(context.Background()))
  1827  	defer func() {
  1828  		require.NoError(bc.Stop(context.Background()))
  1829  		testutil.CleanupPath(testTriePath)
  1830  		testutil.CleanupPath(testDBPath)
  1831  		testutil.CleanupPath(testIndexPath)
  1832  	}()
  1833  	candidate, _, err := candidatesutil.CandidatesFromDB(sf, 1, true, false)
  1834  	require.NoError(err)
  1835  	require.Equal(24, len(candidate))
  1836  }
  1837  
  1838  func TestBlockchain_AccountState(t *testing.T) {
  1839  	require := require.New(t)
  1840  
  1841  	cfg := config.Default
  1842  	ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
  1843  	registry := protocol.NewRegistry()
  1844  	acc := account.NewProtocol(rewarding.DepositGas)
  1845  	require.NoError(acc.Register(registry))
  1846  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1847  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  1848  	require.NoError(err)
  1849  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1850  	require.NoError(err)
  1851  	store, err := filedao.NewFileDAOInMemForTest()
  1852  	require.NoError(err)
  1853  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
  1854  	bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
  1855  	require.NoError(bc.Start(ctx))
  1856  	require.NotNil(bc)
  1857  	defer func() {
  1858  		require.NoError(bc.Stop(ctx))
  1859  	}()
  1860  	s, err := accountutil.AccountState(ctx, sf, identityset.Address(0))
  1861  	require.NoError(err)
  1862  	require.Equal(uint64(1), s.PendingNonce())
  1863  	require.Equal(unit.ConvertIotxToRau(100000000), s.Balance)
  1864  	require.Zero(s.Root)
  1865  	require.Nil(s.CodeHash)
  1866  }
  1867  
  1868  func TestNewAccountAction(t *testing.T) {
  1869  	require := require.New(t)
  1870  
  1871  	cfg := config.Default
  1872  	cfg.Genesis.OkhotskBlockHeight = 1
  1873  	ctx := genesis.WithGenesisContext(context.Background(), cfg.Genesis)
  1874  	registry := protocol.NewRegistry()
  1875  	acc := account.NewProtocol(rewarding.DepositGas)
  1876  	require.NoError(acc.Register(registry))
  1877  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1878  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  1879  	require.NoError(err)
  1880  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1881  	require.NoError(err)
  1882  	store, err := filedao.NewFileDAOInMemForTest()
  1883  	require.NoError(err)
  1884  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
  1885  	bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
  1886  	require.NoError(bc.Start(ctx))
  1887  	require.NotNil(bc)
  1888  	defer func() {
  1889  		require.NoError(bc.Stop(ctx))
  1890  	}()
  1891  
  1892  	// create a new address, transfer 4 IOTX
  1893  	newSk, err := iotexcrypto.HexStringToPrivateKey("55499c1b09f687488af9e4ee9e2bd53c7c8c3ddc69d4d9345a04b13030cffabe")
  1894  	require.NoError(err)
  1895  	newAddr := newSk.PublicKey().Address()
  1896  	tx, err := action.SignedTransfer(newAddr.String(), identityset.PrivateKey(0), 1, big.NewInt(4*unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
  1897  	require.NoError(err)
  1898  	require.NoError(ap.Add(ctx, tx))
  1899  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  1900  	require.NoError(err)
  1901  	require.NoError(bc.CommitBlock(blk))
  1902  	ap.Reset()
  1903  
  1904  	// initiate transfer from new address
  1905  	tx, err = action.SignedTransfer(identityset.Address(0).String(), newSk, 0, big.NewInt(unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
  1906  	require.NoError(err)
  1907  	require.NoError(ap.Add(ctx, tx))
  1908  	tx1, err := action.SignedTransfer(identityset.Address(1).String(), newSk, 1, big.NewInt(unit.Iotx), nil, testutil.TestGasLimit, testutil.TestGasPrice)
  1909  	require.NoError(err)
  1910  	require.NoError(ap.Add(ctx, tx1))
  1911  	blk1, err := bc.MintNewBlock(testutil.TimestampNow())
  1912  	require.NoError(err)
  1913  	require.NoError(bc.CommitBlock(blk1))
  1914  	ap.Reset()
  1915  
  1916  	// commit 2 blocks into a new chain
  1917  	for _, validateNonce := range []bool{false, true} {
  1918  		if validateNonce {
  1919  			cfg.Genesis.PalauBlockHeight = 2
  1920  		} else {
  1921  			cfg.Genesis.PalauBlockHeight = 20
  1922  		}
  1923  		ctx = genesis.WithGenesisContext(context.Background(), cfg.Genesis)
  1924  		factoryCfg = factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1925  		sf1, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  1926  		require.NoError(err)
  1927  		store, err := filedao.NewFileDAOInMemForTest()
  1928  		require.NoError(err)
  1929  		dao1 := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf1}, cfg.DB.MaxCacheSize)
  1930  		bc1 := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao1, factory.NewMinter(sf1, ap))
  1931  		require.NoError(bc1.Start(ctx))
  1932  		require.NotNil(bc1)
  1933  		defer func() {
  1934  			require.NoError(bc1.Stop(ctx))
  1935  		}()
  1936  		require.NoError(bc1.CommitBlock(blk))
  1937  		err = bc1.CommitBlock(blk1)
  1938  		if validateNonce {
  1939  			require.NoError(err)
  1940  		} else {
  1941  			require.Equal(action.ErrNonceTooHigh, errors.Cause(err))
  1942  		}
  1943  
  1944  		// verify new addr
  1945  		s, err := accountutil.AccountState(ctx, sf1, newAddr)
  1946  		require.NoError(err)
  1947  		if validateNonce {
  1948  			require.EqualValues(2, s.PendingNonce())
  1949  			require.Equal(big.NewInt(2*unit.Iotx), s.Balance)
  1950  		} else {
  1951  			require.Zero(s.PendingNonce())
  1952  			require.Equal(big.NewInt(4*unit.Iotx), s.Balance)
  1953  		}
  1954  		require.Zero(s.Root)
  1955  		require.Nil(s.CodeHash)
  1956  	}
  1957  }
  1958  
  1959  func TestBlocks(t *testing.T) {
  1960  	// This test is used for committing block verify benchmark purpose
  1961  	t.Skip()
  1962  	require := require.New(t)
  1963  	cfg := config.Default
  1964  
  1965  	testTriePath, err := testutil.PathOfTempFile("trie")
  1966  	require.NoError(err)
  1967  	testDBPath, err := testutil.PathOfTempFile("db")
  1968  	require.NoError(err)
  1969  	testIndexPath, err := testutil.PathOfTempFile("index")
  1970  	require.NoError(err)
  1971  
  1972  	a := identityset.Address(28).String()
  1973  	priKeyA := identityset.PrivateKey(28)
  1974  	c := identityset.Address(29).String()
  1975  
  1976  	cfg.Chain.TrieDBPath = testTriePath
  1977  	cfg.Chain.ChainDBPath = testDBPath
  1978  	cfg.Chain.IndexDBPath = testIndexPath
  1979  	cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
  1980  	cfg.Genesis.InitBalanceMap[a] = "100000"
  1981  	cfg.Genesis.InitBalanceMap[c] = "100000"
  1982  
  1983  	registry := protocol.NewRegistry()
  1984  	acc := account.NewProtocol(rewarding.DepositGas)
  1985  	require.NoError(acc.Register(registry))
  1986  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  1987  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  1988  	require.NoError(err)
  1989  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  1990  	require.NoError(err)
  1991  	dbcfg := cfg.DB
  1992  	dbcfg.DbPath = cfg.Chain.ChainDBPath
  1993  	store, err := filedao.NewFileDAO(dbcfg, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  1994  	require.NoError(err)
  1995  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, dbcfg.MaxCacheSize)
  1996  
  1997  	// Create a blockchain from scratch
  1998  	bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
  1999  	require.NoError(bc.Start(context.Background()))
  2000  	defer func() {
  2001  		require.NoError(bc.Stop(context.Background()))
  2002  		testutil.CleanupPath(testTriePath)
  2003  		testutil.CleanupPath(testDBPath)
  2004  		testutil.CleanupPath(testIndexPath)
  2005  	}()
  2006  
  2007  	gasLimit := testutil.TestGasLimit
  2008  	ctx := protocol.WithBlockCtx(context.Background(),
  2009  		protocol.BlockCtx{
  2010  			Producer: identityset.Address(27),
  2011  			GasLimit: gasLimit,
  2012  		})
  2013  	ctx = genesis.WithGenesisContext(ctx, cfg.Genesis)
  2014  
  2015  	for i := 0; i < 10; i++ {
  2016  		actionMap := make(map[string][]*action.SealedEnvelope)
  2017  		actionMap[a] = []*action.SealedEnvelope{}
  2018  		for i := 0; i < 1000; i++ {
  2019  			tsf, err := action.SignedTransfer(c, priKeyA, 1, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2020  			require.NoError(err)
  2021  			require.NoError(ap.Add(context.Background(), tsf))
  2022  		}
  2023  		blk, _ := bc.MintNewBlock(testutil.TimestampNow())
  2024  		require.NoError(bc.CommitBlock(blk))
  2025  	}
  2026  }
  2027  
  2028  func TestActions(t *testing.T) {
  2029  	// This test is used for block verify benchmark purpose
  2030  	t.Skip()
  2031  	require := require.New(t)
  2032  	cfg := config.Default
  2033  
  2034  	registry := protocol.NewRegistry()
  2035  	acc := account.NewProtocol(rewarding.DepositGas)
  2036  	require.NoError(acc.Register(registry))
  2037  
  2038  	ctx := genesis.WithGenesisContext(
  2039  		protocol.WithRegistry(context.Background(), registry),
  2040  		cfg.Genesis,
  2041  	)
  2042  
  2043  	testTriePath, err := testutil.PathOfTempFile("trie")
  2044  	require.NoError(err)
  2045  	testDBPath, err := testutil.PathOfTempFile("db")
  2046  	require.NoError(err)
  2047  	testIndexPath, err := testutil.PathOfTempFile("index")
  2048  	require.NoError(err)
  2049  
  2050  	a := identityset.Address(28).String()
  2051  	priKeyA := identityset.PrivateKey(28)
  2052  	c := identityset.Address(29).String()
  2053  
  2054  	cfg.Chain.TrieDBPath = testTriePath
  2055  	cfg.Chain.ChainDBPath = testDBPath
  2056  	cfg.Chain.IndexDBPath = testIndexPath
  2057  	cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
  2058  	cfg.Genesis.InitBalanceMap[a] = "100000"
  2059  	cfg.Genesis.InitBalanceMap[c] = "100000"
  2060  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  2061  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  2062  	require.NoError(err)
  2063  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  2064  	require.NoError(err)
  2065  	dbcfg := cfg.DB
  2066  	dbcfg.DbPath = cfg.Chain.ChainDBPath
  2067  	store, err := filedao.NewFileDAO(dbcfg, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  2068  	require.NoError(err)
  2069  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, dbcfg.MaxCacheSize)
  2070  	// Create a blockchain from scratch
  2071  	bc := blockchain.NewBlockchain(
  2072  		cfg.Chain,
  2073  		cfg.Genesis,
  2074  		dao,
  2075  		factory.NewMinter(sf, ap),
  2076  		blockchain.BlockValidatorOption(block.NewValidator(
  2077  			sf,
  2078  			protocol.NewGenericValidator(sf, accountutil.AccountState),
  2079  		)),
  2080  	)
  2081  	require.NoError(bc.Start(context.Background()))
  2082  	defer func() {
  2083  		require.NoError(bc.Stop(context.Background()))
  2084  		testutil.CleanupPath(testTriePath)
  2085  		testutil.CleanupPath(testDBPath)
  2086  		testutil.CleanupPath(testIndexPath)
  2087  	}()
  2088  
  2089  	gasLimit := testutil.TestGasLimit
  2090  	ctx = protocol.WithBlockCtx(context.Background(),
  2091  		protocol.BlockCtx{
  2092  			Producer: identityset.Address(27),
  2093  			GasLimit: gasLimit,
  2094  		})
  2095  	ctx = genesis.WithGenesisContext(ctx, cfg.Genesis)
  2096  
  2097  	for i := 0; i < 5000; i++ {
  2098  		tsf, err := action.SignedTransfer(c, priKeyA, 1, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2099  		require.NoError(err)
  2100  		require.NoError(ap.Add(context.Background(), tsf))
  2101  
  2102  		tsf2, err := action.SignedTransfer(a, priKeyA, 1, big.NewInt(2), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2103  		require.NoError(err)
  2104  		require.NoError(ap.Add(context.Background(), tsf2))
  2105  	}
  2106  	blk, _ := bc.MintNewBlock(testutil.TimestampNow())
  2107  	ctx = protocol.WithBlockchainCtx(
  2108  		ctx,
  2109  		protocol.BlockchainCtx{
  2110  			Tip: protocol.TipInfo{
  2111  				Height: 0,
  2112  				Hash:   blk.PrevHash(),
  2113  			},
  2114  		},
  2115  	)
  2116  	require.NoError(bc.ValidateBlock(blk))
  2117  }
  2118  
  2119  func TestBlockchain_AddRemoveSubscriber(t *testing.T) {
  2120  	req := require.New(t)
  2121  	cfg := config.Default
  2122  	cfg.Genesis.BlockGasLimit = uint64(100000)
  2123  	cfg.Genesis.EnableGravityChainVoting = false
  2124  	// create chain
  2125  	registry := protocol.NewRegistry()
  2126  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  2127  	sf, err := factory.NewFactory(factoryCfg, db.NewMemKVStore(), factory.RegistryOption(registry))
  2128  	req.NoError(err)
  2129  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  2130  	req.NoError(err)
  2131  	store, err := filedao.NewFileDAOInMemForTest()
  2132  	req.NoError(err)
  2133  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, []blockdao.BlockIndexer{sf}, cfg.DB.MaxCacheSize)
  2134  	bc := blockchain.NewBlockchain(cfg.Chain, cfg.Genesis, dao, factory.NewMinter(sf, ap))
  2135  	// mock
  2136  	ctrl := gomock.NewController(t)
  2137  	mb := mock_blockcreationsubscriber.NewMockBlockCreationSubscriber(ctrl)
  2138  	req.Error(bc.RemoveSubscriber(mb))
  2139  	req.NoError(bc.AddSubscriber(mb))
  2140  	req.EqualError(bc.AddSubscriber(nil), "subscriber could not be nil")
  2141  	req.NoError(bc.RemoveSubscriber(mb))
  2142  	req.EqualError(bc.RemoveSubscriber(nil), "cannot find subscription")
  2143  }
  2144  
  2145  func TestHistoryForAccount(t *testing.T) {
  2146  	testHistoryForAccount(t, false)
  2147  	testHistoryForAccount(t, true)
  2148  }
  2149  
  2150  func testHistoryForAccount(t *testing.T, statetx bool) {
  2151  	require := require.New(t)
  2152  	bc, sf, _, _, ap := newChain(t, statetx)
  2153  	a := identityset.Address(28)
  2154  	priKeyA := identityset.PrivateKey(28)
  2155  	b := identityset.Address(29)
  2156  	ctx := genesis.WithGenesisContext(context.Background(), bc.Genesis())
  2157  
  2158  	// check the original balance a and b before transfer
  2159  	AccountA, err := accountutil.AccountState(ctx, sf, a)
  2160  	require.NoError(err)
  2161  	AccountB, err := accountutil.AccountState(ctx, sf, b)
  2162  	require.NoError(err)
  2163  	require.Equal(big.NewInt(100), AccountA.Balance)
  2164  	require.Equal(big.NewInt(100), AccountB.Balance)
  2165  
  2166  	// make a transfer from a to b
  2167  	actionMap := make(map[string][]*action.SealedEnvelope)
  2168  	actionMap[a.String()] = []*action.SealedEnvelope{}
  2169  	tsf, err := action.SignedTransfer(b.String(), priKeyA, 1, big.NewInt(10), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2170  	require.NoError(err)
  2171  	require.NoError(ap.Add(context.Background(), tsf))
  2172  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  2173  	require.NoError(err)
  2174  	require.NoError(bc.ValidateBlock(blk))
  2175  	require.NoError(bc.CommitBlock(blk))
  2176  
  2177  	// check balances after transfer
  2178  	AccountA, err = accountutil.AccountState(ctx, sf, a)
  2179  	require.NoError(err)
  2180  	AccountB, err = accountutil.AccountState(ctx, sf, b)
  2181  	require.NoError(err)
  2182  	require.Equal(big.NewInt(90), AccountA.Balance)
  2183  	require.Equal(big.NewInt(110), AccountB.Balance)
  2184  
  2185  	// check history account's balance
  2186  	if statetx {
  2187  		_, err = accountutil.AccountState(ctx, factory.NewHistoryStateReader(sf, bc.TipHeight()-1), a)
  2188  		require.Equal(factory.ErrNotSupported, errors.Cause(err))
  2189  		_, err = accountutil.AccountState(ctx, factory.NewHistoryStateReader(sf, bc.TipHeight()-1), b)
  2190  		require.Equal(factory.ErrNotSupported, errors.Cause(err))
  2191  	} else {
  2192  		AccountA, err = accountutil.AccountState(ctx, factory.NewHistoryStateReader(sf, bc.TipHeight()-1), a)
  2193  		require.NoError(err)
  2194  		AccountB, err = accountutil.AccountState(ctx, factory.NewHistoryStateReader(sf, bc.TipHeight()-1), b)
  2195  		require.NoError(err)
  2196  		require.Equal(big.NewInt(100), AccountA.Balance)
  2197  		require.Equal(big.NewInt(100), AccountB.Balance)
  2198  	}
  2199  }
  2200  
  2201  func TestHistoryForContract(t *testing.T) {
  2202  	testHistoryForContract(t, false)
  2203  	testHistoryForContract(t, true)
  2204  }
  2205  
  2206  func testHistoryForContract(t *testing.T, statetx bool) {
  2207  	require := require.New(t)
  2208  	bc, sf, _, dao, ap := newChain(t, statetx)
  2209  	ctx := genesis.WithGenesisContext(context.Background(), bc.Genesis())
  2210  	genesisAccount := identityset.Address(27).String()
  2211  	// deploy and get contract address
  2212  	contract := deployXrc20(bc, dao, ap, t)
  2213  
  2214  	contractAddr, err := address.FromString(contract)
  2215  	require.NoError(err)
  2216  	account, err := accountutil.AccountState(ctx, sf, contractAddr)
  2217  	require.NoError(err)
  2218  	// check the original balance
  2219  	balance := BalanceOfContract(contract, genesisAccount, sf, t, account.Root)
  2220  	expect, ok := new(big.Int).SetString("2000000000000000000000000000", 10)
  2221  	require.True(ok)
  2222  	require.Equal(expect, balance)
  2223  	// make a transfer for contract
  2224  	makeTransfer(contract, bc, ap, t)
  2225  	account, err = accountutil.AccountState(ctx, sf, contractAddr)
  2226  	require.NoError(err)
  2227  	// check the balance after transfer
  2228  	balance = BalanceOfContract(contract, genesisAccount, sf, t, account.Root)
  2229  	expect, ok = new(big.Int).SetString("1999999999999999999999999999", 10)
  2230  	require.True(ok)
  2231  	require.Equal(expect, balance)
  2232  
  2233  	// check the the original balance again
  2234  	if statetx {
  2235  		_, err = accountutil.AccountState(ctx, factory.NewHistoryStateReader(sf, bc.TipHeight()-1), contractAddr)
  2236  		require.True(errors.Cause(err) == factory.ErrNotSupported)
  2237  	} else {
  2238  		sr := factory.NewHistoryStateReader(sf, bc.TipHeight()-1)
  2239  		account, err = accountutil.AccountState(ctx, sr, contractAddr)
  2240  		require.NoError(err)
  2241  		balance = BalanceOfContract(contract, genesisAccount, sr, t, account.Root)
  2242  		expect, ok = new(big.Int).SetString("2000000000000000000000000000", 10)
  2243  		require.True(ok)
  2244  		require.Equal(expect, balance)
  2245  	}
  2246  }
  2247  
  2248  func deployXrc20(bc blockchain.Blockchain, dao blockdao.BlockDAO, ap actpool.ActPool, t *testing.T) string {
  2249  	require := require.New(t)
  2250  	genesisPriKey := identityset.PrivateKey(27)
  2251  	// deploy a xrc20 contract with balance 2000000000000000000000000000
  2252  	data, err := hex.DecodeString("60806040526002805460ff1916601217905534801561001d57600080fd5b506040516107cd3803806107cd83398101604090815281516020808401518385015160025460ff16600a0a84026003819055336000908152600485529586205590850180519395909491019261007592850190610092565b508051610089906001906020840190610092565b5050505061012d565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100d357805160ff1916838001178555610100565b82800160010185558215610100579182015b828111156101005782518255916020019190600101906100e5565b5061010c929150610110565b5090565b61012a91905b8082111561010c5760008155600101610116565b90565b6106918061013c6000396000f3006080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b3578063095ea7b31461013d57806318160ddd1461017557806323b872dd1461019c578063313ce567146101c657806342966c68146101f1578063670d14b21461020957806370a082311461022a57806395d89b411461024b578063a9059cbb14610260578063dd62ed3e14610286575b600080fd5b3480156100bf57600080fd5b506100c86102ad565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101025781810151838201526020016100ea565b50505050905090810190601f16801561012f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014957600080fd5b50610161600160a060020a036004351660243561033b565b604080519115158252519081900360200190f35b34801561018157600080fd5b5061018a610368565b60408051918252519081900360200190f35b3480156101a857600080fd5b50610161600160a060020a036004358116906024351660443561036e565b3480156101d257600080fd5b506101db6103dd565b6040805160ff9092168252519081900360200190f35b3480156101fd57600080fd5b506101616004356103e6565b34801561021557600080fd5b506100c8600160a060020a036004351661045e565b34801561023657600080fd5b5061018a600160a060020a03600435166104c6565b34801561025757600080fd5b506100c86104d8565b34801561026c57600080fd5b50610284600160a060020a0360043516602435610532565b005b34801561029257600080fd5b5061018a600160a060020a0360043581169060243516610541565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103335780601f1061030857610100808354040283529160200191610333565b820191906000526020600020905b81548152906001019060200180831161031657829003601f168201915b505050505081565b336000908152600560209081526040808320600160a060020a039590951683529390529190912055600190565b60035481565b600160a060020a038316600090815260056020908152604080832033845290915281205482111561039e57600080fd5b600160a060020a03841660009081526005602090815260408083203384529091529020805483900390556103d384848461055e565b5060019392505050565b60025460ff1681565b3360009081526004602052604081205482111561040257600080fd5b3360008181526004602090815260409182902080548690039055600380548690039055815185815291517fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca59281900390910190a2506001919050565b60066020908152600091825260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156103335780601f1061030857610100808354040283529160200191610333565b60046020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103335780601f1061030857610100808354040283529160200191610333565b61053d33838361055e565b5050565b600560209081526000928352604080842090915290825290205481565b6000600160a060020a038316151561057557600080fd5b600160a060020a03841660009081526004602052604090205482111561059a57600080fd5b600160a060020a038316600090815260046020526040902054828101116105c057600080fd5b50600160a060020a038083166000818152600460209081526040808320805495891680855282852080548981039091559486905281548801909155815187815291519390950194927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600160a060020a0380841660009081526004602052604080822054928716825290205401811461065f57fe5b505050505600a165627a7a723058207c03ad12a18902cfe387e684509d310abd583d862c11e3ee80c116af8b49ec5c00290000000000000000000000000000000000000000000000000000000077359400000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004696f7478000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004696f747800000000000000000000000000000000000000000000000000000000")
  2253  	require.NoError(err)
  2254  	execution, err := action.NewExecution(action.EmptyAddress, 3, big.NewInt(0), 1000000, big.NewInt(testutil.TestGasPriceInt64), data)
  2255  	require.NoError(err)
  2256  	bd := &action.EnvelopeBuilder{}
  2257  	elp := bd.SetAction(execution).
  2258  		SetNonce(3).
  2259  		SetGasLimit(1000000).
  2260  		SetGasPrice(big.NewInt(testutil.TestGasPriceInt64)).Build()
  2261  	selp, err := action.Sign(elp, genesisPriKey)
  2262  	require.NoError(err)
  2263  
  2264  	require.NoError(ap.Add(context.Background(), selp))
  2265  
  2266  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  2267  	require.NoError(err)
  2268  	require.NoError(bc.CommitBlock(blk))
  2269  	selpHash, err := selp.Hash()
  2270  	require.NoError(err)
  2271  	r, err := receiptByActionHash(dao, blk.Height(), selpHash)
  2272  	require.NoError(err)
  2273  	return r.ContractAddress
  2274  }
  2275  
  2276  func BalanceOfContract(contract, genesisAccount string, sr protocol.StateReader, t *testing.T, root hash.Hash256) *big.Int {
  2277  	require := require.New(t)
  2278  	addr, err := address.FromString(contract)
  2279  	require.NoError(err)
  2280  	addrHash := hash.BytesToHash160(addr.Bytes())
  2281  	dbForTrie := protocol.NewKVStoreForTrieWithStateReader(evm.ContractKVNameSpace, sr)
  2282  	options := []mptrie.Option{
  2283  		mptrie.KVStoreOption(dbForTrie),
  2284  		mptrie.KeyLengthOption(len(hash.Hash256{})),
  2285  		mptrie.HashFuncOption(func(data []byte) []byte {
  2286  			h := hash.Hash256b(append(addrHash[:], data...))
  2287  			return h[:]
  2288  		}),
  2289  	}
  2290  	options = append(options, mptrie.RootHashOption(root[:]))
  2291  	tr, err := mptrie.New(options...)
  2292  	require.NoError(err)
  2293  	require.NoError(tr.Start(context.Background()))
  2294  	defer tr.Stop(context.Background())
  2295  	// get producer's xrc20 balance
  2296  	addr, err = address.FromString(genesisAccount)
  2297  	require.NoError(err)
  2298  	addrHash = hash.BytesToHash160(addr.Bytes())
  2299  	checkData := "000000000000000000000000" + hex.EncodeToString(addrHash[:]) + "0000000000000000000000000000000000000000000000000000000000000004"
  2300  	hb, err := hex.DecodeString(checkData)
  2301  	require.NoError(err)
  2302  	out2 := crypto.Keccak256(hb)
  2303  	ret, err := tr.Get(out2[:])
  2304  	require.NoError(err)
  2305  	return big.NewInt(0).SetBytes(ret)
  2306  }
  2307  
  2308  func newChain(t *testing.T, stateTX bool) (blockchain.Blockchain, factory.Factory, db.KVStore, blockdao.BlockDAO, actpool.ActPool) {
  2309  	require := require.New(t)
  2310  	cfg := config.Default
  2311  
  2312  	testTriePath, err := testutil.PathOfTempFile("trie")
  2313  	require.NoError(err)
  2314  	testDBPath, err := testutil.PathOfTempFile("db")
  2315  	require.NoError(err)
  2316  	testIndexPath, err := testutil.PathOfTempFile("index")
  2317  	require.NoError(err)
  2318  	defer func() {
  2319  		testutil.CleanupPath(testTriePath)
  2320  		testutil.CleanupPath(testDBPath)
  2321  		testutil.CleanupPath(testIndexPath)
  2322  	}()
  2323  
  2324  	cfg.Chain.TrieDBPath = testTriePath
  2325  	cfg.Chain.ChainDBPath = testDBPath
  2326  	cfg.Chain.IndexDBPath = testIndexPath
  2327  	cfg.Chain.EnableArchiveMode = true
  2328  	cfg.Consensus.Scheme = config.RollDPoSScheme
  2329  	cfg.Genesis.BlockGasLimit = uint64(1000000)
  2330  	cfg.ActPool.MinGasPriceStr = "0"
  2331  	cfg.Genesis.EnableGravityChainVoting = false
  2332  	registry := protocol.NewRegistry()
  2333  	var sf factory.Factory
  2334  	kv := db.NewMemKVStore()
  2335  	factoryCfg := factory.GenerateConfig(cfg.Chain, cfg.Genesis)
  2336  	if stateTX {
  2337  		sf, err = factory.NewStateDB(factoryCfg, kv, factory.RegistryStateDBOption(registry))
  2338  		require.NoError(err)
  2339  	} else {
  2340  		sf, err = factory.NewFactory(factoryCfg, kv, factory.RegistryOption(registry))
  2341  		require.NoError(err)
  2342  	}
  2343  	ap, err := actpool.NewActPool(cfg.Genesis, sf, cfg.ActPool)
  2344  	require.NoError(err)
  2345  	acc := account.NewProtocol(rewarding.DepositGas)
  2346  	require.NoError(acc.Register(registry))
  2347  	rp := rolldpos.NewProtocol(cfg.Genesis.NumCandidateDelegates, cfg.Genesis.NumDelegates, cfg.Genesis.NumSubEpochs)
  2348  	require.NoError(rp.Register(registry))
  2349  	var indexer blockindex.Indexer
  2350  	indexers := []blockdao.BlockIndexer{sf}
  2351  	if _, gateway := cfg.Plugins[config.GatewayPlugin]; gateway && !cfg.Chain.EnableAsyncIndexWrite {
  2352  		// create indexer
  2353  		cfg.DB.DbPath = cfg.Chain.IndexDBPath
  2354  		indexer, err = blockindex.NewIndexer(db.NewBoltDB(cfg.DB), cfg.Genesis.Hash())
  2355  		require.NoError(err)
  2356  		indexers = append(indexers, indexer)
  2357  	}
  2358  	cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
  2359  	// create BlockDAO
  2360  	cfg.DB.DbPath = cfg.Chain.ChainDBPath
  2361  	store, err := filedao.NewFileDAO(cfg.DB, block.NewDeserializer(cfg.Chain.EVMNetworkID))
  2362  	require.NoError(err)
  2363  	dao := blockdao.NewBlockDAOWithIndexersAndCache(store, indexers, cfg.DB.MaxCacheSize)
  2364  	require.NotNil(dao)
  2365  	bc := blockchain.NewBlockchain(
  2366  		cfg.Chain,
  2367  		cfg.Genesis,
  2368  		dao,
  2369  		factory.NewMinter(sf, ap),
  2370  		blockchain.BlockValidatorOption(block.NewValidator(
  2371  			sf,
  2372  			protocol.NewGenericValidator(sf, accountutil.AccountState),
  2373  		)),
  2374  	)
  2375  	require.NotNil(bc)
  2376  	ep := execution.NewProtocol(dao.GetBlockHash, rewarding.DepositGasWithSGD, nil, fakeGetBlockTime)
  2377  	require.NoError(ep.Register(registry))
  2378  	require.NoError(bc.Start(context.Background()))
  2379  
  2380  	genesisPriKey := identityset.PrivateKey(27)
  2381  	a := identityset.Address(28).String()
  2382  	b := identityset.Address(29).String()
  2383  	// make a transfer from genesisAccount to a and b,because stateTX cannot store data in height 0
  2384  	tsf, err := action.SignedTransfer(a, genesisPriKey, 1, big.NewInt(100), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2385  	require.NoError(err)
  2386  	tsf2, err := action.SignedTransfer(b, genesisPriKey, 2, big.NewInt(100), []byte{}, testutil.TestGasLimit, big.NewInt(testutil.TestGasPriceInt64))
  2387  	require.NoError(err)
  2388  	require.NoError(ap.Add(context.Background(), tsf))
  2389  	require.NoError(ap.Add(context.Background(), tsf2))
  2390  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  2391  	require.NoError(err)
  2392  	require.NoError(bc.CommitBlock(blk))
  2393  	return bc, sf, kv, dao, ap
  2394  }
  2395  
  2396  func makeTransfer(contract string, bc blockchain.Blockchain, ap actpool.ActPool, t *testing.T) *block.Block {
  2397  	require := require.New(t)
  2398  	genesisPriKey := identityset.PrivateKey(27)
  2399  	// make a transfer for contract,transfer 1 to io16eur00s9gdvak4ujhpuk9a45x24n60jgecgxzz
  2400  	bytecode, err := hex.DecodeString("a9059cbb0000000000000000000000004867c4bada9553216bf296c4c64e9ff0749206490000000000000000000000000000000000000000000000000000000000000001")
  2401  	require.NoError(err)
  2402  	execution, err := action.NewExecution(contract, 4, big.NewInt(0), 1000000, big.NewInt(testutil.TestGasPriceInt64), bytecode)
  2403  	require.NoError(err)
  2404  	bd := &action.EnvelopeBuilder{}
  2405  	elp := bd.SetAction(execution).
  2406  		SetNonce(4).
  2407  		SetGasLimit(1000000).
  2408  		SetGasPrice(big.NewInt(testutil.TestGasPriceInt64)).Build()
  2409  	selp, err := action.Sign(elp, genesisPriKey)
  2410  	require.NoError(err)
  2411  	require.NoError(ap.Add(context.Background(), selp))
  2412  	blk, err := bc.MintNewBlock(testutil.TimestampNow())
  2413  	require.NoError(err)
  2414  	require.NoError(bc.CommitBlock(blk))
  2415  	return blk
  2416  }
  2417  
  2418  // classifyActions classfies actions
  2419  func classifyActions(actions []*action.SealedEnvelope) ([]*action.Transfer, []*action.Execution) {
  2420  	tsfs := make([]*action.Transfer, 0)
  2421  	exes := make([]*action.Execution, 0)
  2422  	for _, elp := range actions {
  2423  		act := elp.Action()
  2424  		switch act := act.(type) {
  2425  		case *action.Transfer:
  2426  			tsfs = append(tsfs, act)
  2427  		case *action.Execution:
  2428  			exes = append(exes, act)
  2429  		}
  2430  	}
  2431  	return tsfs, exes
  2432  }
  2433  
  2434  func receiptByActionHash(dao blockdao.BlockDAO, height uint64, h hash.Hash256) (*action.Receipt, error) {
  2435  	receipts, err := dao.GetReceipts(height)
  2436  	if err != nil {
  2437  		return nil, err
  2438  	}
  2439  	for _, receipt := range receipts {
  2440  		if receipt.ActionHash == h {
  2441  			return receipt, nil
  2442  		}
  2443  	}
  2444  	return nil, errors.Errorf("failed to find receipt for %x", h)
  2445  }
  2446  
  2447  // TODO: add func TestValidateBlock()