github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/engine_inner_test.go (about)

     1  package nvm
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/nebulasio/go-nebulas/account"
    11  	"github.com/nebulasio/go-nebulas/consensus/dpos"
    12  	"github.com/nebulasio/go-nebulas/core"
    13  	"github.com/nebulasio/go-nebulas/crypto/keystore"
    14  	"github.com/nebulasio/go-nebulas/util"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  type deployTx struct {
    19  	value    int64
    20  	gasLimit int64
    21  	contract contract
    22  }
    23  
    24  type contract struct {
    25  	contractPath string
    26  	sourceType   string
    27  	initArgs     string
    28  }
    29  
    30  type call struct {
    31  	function   string
    32  	args       string
    33  	exceptArgs []string //[congractA,B,C, AccountA, B]
    34  }
    35  
    36  type SysEvent struct {
    37  	Hash    string `json:"hash"`
    38  	Status  int    `json:"status"`
    39  	GasUsed string `json:"gas_used"`
    40  	Err     string `json:"error"`
    41  	Result  string `json:"execute_result"`
    42  }
    43  type InnerEvent struct {
    44  	From  string `json:"from"`
    45  	To    string `json:"to"`
    46  	Value int    `json:"value"`
    47  	Error string `json:"error"`
    48  }
    49  
    50  func mockNeb(t *testing.T) core.Neblet {
    51  	am, err := account.NewManager(nil)
    52  	assert.Nil(t, err)
    53  	consensus := dpos.NewDpos()
    54  	nvm := NewNebulasVM()
    55  	neb := core.NewMockNeb(am, consensus, nvm)
    56  	return neb
    57  }
    58  
    59  func generateRandom(t *testing.T, neb core.Neblet, block *core.Block) {
    60  	ancestorHash, parentSeed, err := neb.BlockChain().GetInputForVRFSigner(block.ParentHash(), block.Height())
    61  	assert.Nil(t, err)
    62  
    63  	proposer := block.WorldState().ConsensusRoot().Proposer
    64  	miner, err := core.AddressParseFromBytes(proposer)
    65  	assert.Nil(t, err)
    66  
    67  	// generate VRF hash,proof
    68  	vrfSeed, vrfProof, err := neb.AccountManager().GenerateRandomSeed(miner, ancestorHash, parentSeed)
    69  	assert.Nil(t, err)
    70  	block.SetRandomSeed(vrfSeed, vrfProof)
    71  }
    72  
    73  func unlockAccount(t *testing.T, neb core.Neblet) []*core.Address {
    74  	manager := neb.AccountManager()
    75  	dynasty := neb.Genesis().Consensus.Dpos.Dynasty
    76  	addrs := []*core.Address{}
    77  	for _, v := range dynasty {
    78  		addr, err := core.AddressParse(v)
    79  		assert.Nil(t, err)
    80  		assert.Nil(t, manager.Unlock(addr, []byte("passphrase"), keystore.YearUnlockDuration))
    81  		addrs = append(addrs, addr)
    82  	}
    83  	//a, _ := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE")
    84  	//assert.Nil(t, manager.Unlock(a, []byte("passphrase"), keystore.YearUnlockDuration))
    85  	//b, _ := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s")
    86  	//assert.Nil(t, manager.Unlock(b, []byte("passphrase"), keystore.YearUnlockDuration))
    87  	//c, _ := core.AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so")
    88  	//assert.Nil(t, manager.Unlock(c, []byte("passphrase"), keystore.YearUnlockDuration))
    89  	//d, _ := core.AddressParse("n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf")
    90  	//assert.Nil(t, manager.Unlock(d, []byte("passphrase"), keystore.YearUnlockDuration))
    91  	return addrs
    92  }
    93  
    94  func mintBlock(t *testing.T, neb core.Neblet, txs []*core.Transaction) {
    95  	mintBlockWithDuration(t, neb, txs, int64(1))
    96  }
    97  
    98  func mintBlockWithDuration(t *testing.T, neb core.Neblet, txs []*core.Transaction, duration int64) {
    99  	tail := neb.BlockChain().TailBlock()
   100  	manager := neb.AccountManager()
   101  	elapsedSecond := dpos.BlockIntervalInMs / dpos.SecondInMs
   102  	consensusState, err := tail.WorldState().NextConsensusState(elapsedSecond)
   103  	assert.Nil(t, err)
   104  
   105  	coinbase, err := core.AddressParse(neb.Config().Chain.Coinbase)
   106  	assert.Nil(t, err)
   107  	block, err := core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail)
   108  	assert.Nil(t, err)
   109  	block.WorldState().SetConsensusState(consensusState)
   110  	block.SetTimestamp(consensusState.TimeStamp())
   111  	generateRandom(t, neb, block)
   112  
   113  	for _, tx := range txs {
   114  		assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx))
   115  	}
   116  
   117  	block.CollectTransactions((time.Now().Unix() + duration) * dpos.SecondInMs)
   118  	assert.Nil(t, block.Seal())
   119  	err = manager.SignBlock(block.Miner(), block)
   120  	assert.Nil(t, err)
   121  	assert.Nil(t, neb.BlockChain().BlockPool().Push(block))
   122  	assert.Equal(t, block.Hash(), neb.BlockChain().TailBlock().Hash())
   123  }
   124  
   125  //block->a empty coinbase c . block->b deploy and accout is a and coinbase is c . block->c run js
   126  func TestInnerTransactions(t *testing.T) {
   127  	tests := []struct {
   128  		name  string
   129  		txs   []deployTx
   130  		calls []call
   131  	}{
   132  		{
   133  			"inner transaction",
   134  			[]deployTx{{
   135  				0, 200000,
   136  				contract{
   137  					"./test/inner_call_tests/test_inner_transaction.js",
   138  					"js",
   139  					"",
   140  				},
   141  			},
   142  				{
   143  					0, 200000,
   144  					contract{
   145  						"./test/inner_call_tests/bank_vault_inner_contract.js",
   146  						"js",
   147  						"",
   148  					},
   149  				},
   150  				{
   151  					0, 200000,
   152  					contract{
   153  						"./test/inner_call_tests/bank_vault_final_contract.js",
   154  						"js",
   155  						"",
   156  					},
   157  				},
   158  			},
   159  			[]call{
   160  				call{
   161  					"save",
   162  					"[1]",
   163  					[]string{"1", "3", "2", "4999999999999833225999994"},
   164  				},
   165  			},
   166  		},
   167  	}
   168  
   169  	core.NebCompatibility = core.NewCompatibilityLocal()
   170  	neb := mockNeb(t)
   171  	manager := neb.AccountManager()
   172  
   173  	addrs := unlockAccount(t, neb)
   174  
   175  	// mint height 2, inner contracts >= 3
   176  	mintBlock(t, neb, nil)
   177  
   178  	tt := tests[0]
   179  	for _, call := range tt.calls {
   180  
   181  		txs := []*core.Transaction{}
   182  		contracts := []*core.Address{}
   183  		for k, tx := range tt.txs {
   184  			data, err := ioutil.ReadFile(tx.contract.contractPath)
   185  			assert.Nil(t, err, "contract path read error")
   186  			source := string(data)
   187  			sourceType := "js"
   188  			argsDeploy := ""
   189  			deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   190  			payloadDeploy, _ := deploy.ToBytes()
   191  
   192  			value, _ := util.NewUint128FromInt(tx.value)
   193  			gasLimit, _ := util.NewUint128FromInt(tx.gasLimit)
   194  			from := addrs[0]
   195  			txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   196  			assert.Nil(t, err)
   197  			assert.Nil(t, manager.SignTransaction(from, txDeploy))
   198  			txs = append(txs, txDeploy)
   199  
   200  			contractAddr, err := txDeploy.GenerateContractAddress()
   201  			assert.Nil(t, err)
   202  			contracts = append(contracts, contractAddr)
   203  		}
   204  		//package contract txs
   205  		mintBlock(t, neb, txs)
   206  
   207  		for _, v := range contracts {
   208  			_, err := neb.BlockChain().TailBlock().CheckContract(v)
   209  			assert.Nil(t, err)
   210  		}
   211  
   212  		contractB := contracts[1]
   213  		contractC := contracts[2]
   214  		callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", contractB.String(), contractC.String()))
   215  		payloadCall, _ := callPayload.ToBytes()
   216  		value, _ := util.NewUint128FromInt(6)
   217  		gasLimit, _ := util.NewUint128FromInt(200000)
   218  		from := neb.BlockChain().TailBlock().Transactions()[0].From()
   219  		proxyContractAddress := contracts[0]
   220  		txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   221  			uint64(len(contracts)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   222  		assert.Nil(t, err)
   223  		assert.Nil(t, manager.SignTransaction(txCall.From(), txCall))
   224  
   225  		// package call tx
   226  		mintBlock(t, neb, []*core.Transaction{txCall})
   227  
   228  		tail := neb.BlockChain().TailBlock()
   229  		events, err := tail.FetchEvents(txCall.Hash())
   230  		assert.Nil(t, err)
   231  		for _, event := range events {
   232  			t.Logf("call tpoic: %s, data:%s", event.Topic, event.Data)
   233  		}
   234  		contractAddrA := contracts[0]
   235  		accountAAcc, err := tail.GetAccount(contractAddrA.Bytes())
   236  		assert.Nil(t, err)
   237  		fmt.Printf("account :%v\n", accountAAcc)
   238  		assert.Equal(t, call.exceptArgs[0], accountAAcc.Balance().String())
   239  
   240  		contractAddrB := contracts[1]
   241  		accountBAcc, err := tail.GetAccount(contractAddrB.Bytes())
   242  		assert.Nil(t, err)
   243  		fmt.Printf("accountB :%v\n", accountBAcc)
   244  		assert.Equal(t, call.exceptArgs[1], accountBAcc.Balance().String())
   245  
   246  		contractAddrC := contracts[2]
   247  		accountAccC, err := tail.GetAccount(contractAddrC.Bytes())
   248  		assert.Nil(t, err)
   249  		fmt.Printf("accountC :%v\n", accountAccC)
   250  		assert.Equal(t, call.exceptArgs[2], accountAccC.Balance().String())
   251  
   252  		aUser, err := tail.GetAccount(from.Bytes())
   253  		assert.Equal(t, call.exceptArgs[3], aUser.Balance().String())
   254  		fmt.Printf("from:%v\n", aUser)
   255  
   256  	}
   257  }
   258  
   259  func TestInnerTransactionsInMulitithCoroutine(t *testing.T) {
   260  	core.NebCompatibility = core.NewCompatibilityLocal()
   261  	core.PackedParallelNum = 2
   262  	tests := []struct {
   263  		name       string
   264  		txs        []deployTx
   265  		calls      []call
   266  		paralleNum uint32
   267  	}{
   268  		{
   269  			"inner transaction",
   270  			[]deployTx{
   271  				{
   272  					0, 200000,
   273  					contract{
   274  						"./test/inner_call_tests/test_inner_transaction.js",
   275  						"js",
   276  						"",
   277  					},
   278  				},
   279  				{
   280  					0, 200000,
   281  					contract{
   282  						"./test/inner_call_tests/bank_vault_inner_contract.js",
   283  						"js",
   284  						"",
   285  					},
   286  				},
   287  				{
   288  					0, 200000,
   289  					contract{
   290  						"./test/inner_call_tests/bank_vault_final_contract.js",
   291  						"js",
   292  						"",
   293  					},
   294  				},
   295  			},
   296  			[]call{
   297  				call{
   298  					"save",
   299  					"[1]",
   300  					[]string{"1", "3", "2", "4999999999999833224999994", "5000004280820166775000000"},
   301  				},
   302  			},
   303  			4,
   304  		},
   305  	}
   306  	neb := mockNeb(t)
   307  	manager := neb.AccountManager()
   308  
   309  	addrs := unlockAccount(t, neb)
   310  
   311  	// mint height 2, inner contracts >= 3
   312  	mintBlock(t, neb, nil)
   313  
   314  	tt := tests[0]
   315  	for _, call := range tt.calls {
   316  
   317  		txs := []*core.Transaction{}
   318  		var contractsAddr [][]string
   319  		// var nonce uint64
   320  		// t.Run(tt.name, func(t *testing.T) {
   321  		for i := uint32(0); i < tt.paralleNum; i++ {
   322  			// contractsAddr[i] = []
   323  			var tmp []string
   324  			nonce := uint64(0)
   325  			for _, v := range tt.txs {
   326  				data, err := ioutil.ReadFile(v.contract.contractPath)
   327  				assert.Nil(t, err, "contract path read error")
   328  				source := string(data)
   329  				sourceType := "js"
   330  				argsDeploy := ""
   331  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   332  				payloadDeploy, _ := deploy.ToBytes()
   333  
   334  				value, _ := util.NewUint128FromInt(v.value)
   335  				gasLimit, _ := util.NewUint128FromInt(v.gasLimit)
   336  				// nonce := uint32(k+1)*(i+1) + 1
   337  				nonce++
   338  				idx := int(i) % len(addrs)
   339  				from := addrs[idx]
   340  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, nonce, core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   341  				assert.Nil(t, err)
   342  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
   343  				txs = append(txs, txDeploy)
   344  
   345  				contractAddr, err := txDeploy.GenerateContractAddress()
   346  				assert.Nil(t, err)
   347  				fmt.Printf("index;%v", i)
   348  				// if contractsAddr[i] = nil {
   349  				// 	contractsAddr[i] = ""
   350  				// }
   351  				// contractsAddr[i] = append(contractsAddr[i], contractAddr.String())
   352  				tmp = append(tmp, contractAddr.String())
   353  				// contractsAddr[i]
   354  			}
   355  			contractsAddr = append(contractsAddr, tmp)
   356  		}
   357  		// })
   358  
   359  		// mint block for contracts
   360  		mintBlock(t, neb, txs)
   361  
   362  		txCalls := []*core.Transaction{}
   363  		for i := uint32(0); i < tt.paralleNum; i++ {
   364  
   365  			calleeContract := contractsAddr[i][1]
   366  			calleeContractAddr, _ := core.AddressParse(calleeContract)
   367  			_, err := neb.BlockChain().TailBlock().CheckContract(calleeContractAddr)
   368  			assert.Nil(t, err)
   369  			callToContract := contractsAddr[i][2]
   370  			callToContractAddr, _ := core.AddressParse(callToContract)
   371  			_, err = neb.BlockChain().TailBlock().CheckContract(callToContractAddr)
   372  			assert.Nil(t, err)
   373  			callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract))
   374  			payloadCall, _ := callPayload.ToBytes()
   375  			value, _ := util.NewUint128FromInt(6)
   376  			gasLimit, _ := util.NewUint128FromInt(200000)
   377  
   378  			proxyContractAddress, err := core.AddressParse(contractsAddr[i][0])
   379  			idx := int(i) % len(addrs)
   380  			from := addrs[idx]
   381  			account, err := neb.BlockChain().TailBlock().GetAccount(from.Bytes())
   382  			assert.Nil(t, err)
   383  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   384  				account.Nonce()+1, core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   385  			assert.Nil(t, err)
   386  			assert.Nil(t, manager.SignTransaction(from, txCall))
   387  			// fmt.Printf("++tx:%v\n", txCall.JSONString())
   388  			txCalls = append(txCalls, txCall)
   389  			// txCalls[i] = txCall
   390  		}
   391  
   392  		mintBlock(t, neb, txCalls)
   393  
   394  		// check
   395  		tail := neb.BlockChain().TailBlock()
   396  		for i := uint32(0); i < tt.paralleNum; i++ {
   397  			fmt.Printf("xxxxxxxxxxxx i:%v", i)
   398  			events, err := tail.FetchEvents(txCalls[i].Hash())
   399  			assert.Nil(t, err)
   400  			for _, event := range events {
   401  
   402  				fmt.Println("==============", event.Data)
   403  			}
   404  			contractAddrA, err := core.AddressParse(contractsAddr[i][0])
   405  			accountAAcc, err := tail.GetAccount(contractAddrA.Bytes())
   406  			assert.Nil(t, err)
   407  			fmt.Printf("account :%v\n", accountAAcc)
   408  			assert.Equal(t, call.exceptArgs[0], accountAAcc.Balance().String())
   409  
   410  			contractAddrB, err := core.AddressParse(contractsAddr[i][1])
   411  			accountBAcc, err := tail.GetAccount(contractAddrB.Bytes())
   412  			assert.Nil(t, err)
   413  			fmt.Printf("accountB :%v\n", accountBAcc)
   414  			assert.Equal(t, call.exceptArgs[1], accountBAcc.Balance().String())
   415  
   416  			contractAddrC, err := core.AddressParse(contractsAddr[i][2])
   417  			accountAccC, err := tail.GetAccount(contractAddrC.Bytes())
   418  			assert.Nil(t, err)
   419  			fmt.Printf("accountC :%v\n", accountAccC)
   420  			assert.Equal(t, call.exceptArgs[2], accountAccC.Balance().String())
   421  
   422  			aUser, err := tail.GetAccount(addrs[0].Bytes())
   423  			// assert.Equal(t, call.exceptArgs[3], aUser.Balance().String())
   424  			fmt.Printf("a:%v\n", aUser)
   425  			cUser, err := tail.GetAccount(addrs[2].Bytes())
   426  			fmt.Printf("c:%v\n", cUser)
   427  			// assert.Equal(t, call.exceptArgs[4], cUser.Balance().String())
   428  
   429  			// cUser, err := tail.GetAccount(c.Bytes())
   430  			// fmt.Printf("c:%v\n", cUser)
   431  
   432  			// dUser, err := tail.GetAccount(d.Bytes())
   433  			// fmt.Printf("d:%v\n", dUser)
   434  			// assert.Equal(t, txEvent.Status, 1)
   435  		}
   436  
   437  	}
   438  }
   439  
   440  func TestInnerTransactionsMaxMulit(t *testing.T) {
   441  	core.NebCompatibility = core.NewCompatibilityLocal()
   442  	tests := []struct {
   443  		name                   string
   444  		contracts              []contract
   445  		call                   call
   446  		innerExpectedErr       string
   447  		contractExpectedErr    string
   448  		contractExpectedResult string
   449  	}{
   450  		{
   451  			"deploy test_require_module.js",
   452  			[]contract{
   453  				contract{
   454  					"./test/inner_call_tests/test_inner_transaction.js",
   455  					"js",
   456  					"",
   457  				},
   458  				contract{
   459  					"./test/inner_call_tests/bank_vault_inner_contract.js",
   460  					"js",
   461  					"",
   462  				},
   463  				contract{
   464  					"./test/inner_call_tests/bank_vault_final_contract.js",
   465  					"js",
   466  					"",
   467  				},
   468  			},
   469  			call{
   470  				"saveToLoop",
   471  				"[1]",
   472  				[]string{""},
   473  			},
   474  			"multi execution failed",
   475  			"Call: Inner Contract: out of limit nvm count",
   476  			"Inner Contract: out of limit nvm count",
   477  		},
   478  	}
   479  
   480  	neb := mockNeb(t)
   481  	manager, err := account.NewManager(neb)
   482  	assert.Nil(t, err)
   483  
   484  	addrs := unlockAccount(t, neb)
   485  	from := addrs[0]
   486  
   487  	// mint height 2, inner contracts >= 3
   488  	mintBlock(t, neb, nil)
   489  
   490  	for _, tt := range tests {
   491  
   492  		txs := []*core.Transaction{}
   493  		contractsAddr := []string{}
   494  		// t.Run(tt.name, func(t *testing.T) {
   495  		for k, v := range tt.contracts {
   496  			data, err := ioutil.ReadFile(v.contractPath)
   497  			assert.Nil(t, err, "contract path read error")
   498  			source := string(data)
   499  			sourceType := "js"
   500  			argsDeploy := ""
   501  			deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   502  			payloadDeploy, _ := deploy.ToBytes()
   503  
   504  			value, _ := util.NewUint128FromInt(0)
   505  			gasLimit, _ := util.NewUint128FromInt(200000)
   506  			txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   507  			assert.Nil(t, err)
   508  			assert.Nil(t, manager.SignTransaction(from, txDeploy))
   509  			txs = append(txs, txDeploy)
   510  
   511  			contractAddr, err := txDeploy.GenerateContractAddress()
   512  			assert.Nil(t, err)
   513  			contractsAddr = append(contractsAddr, contractAddr.String())
   514  		}
   515  		// })
   516  
   517  		// mint for contract deploy
   518  		mintBlock(t, neb, txs)
   519  
   520  		for _, v := range contractsAddr {
   521  			contract, err := core.AddressParse(v)
   522  			assert.Nil(t, err)
   523  			_, err = neb.BlockChain().TailBlock().CheckContract(contract)
   524  			assert.Nil(t, err)
   525  		}
   526  
   527  		calleeContract := contractsAddr[0]
   528  		callToContract := contractsAddr[2]
   529  		callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract))
   530  		payloadCall, _ := callPayload.ToBytes()
   531  
   532  		value, _ := util.NewUint128FromInt(6)
   533  		gasLimit, _ := util.NewUint128FromInt(2000000)
   534  
   535  		proxyContractAddress, err := core.AddressParse(contractsAddr[0])
   536  		txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   537  			uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   538  		assert.Nil(t, err)
   539  		assert.Nil(t, manager.SignTransaction(from, txCall))
   540  
   541  		// mint for inner call
   542  		mintBlock(t, neb, []*core.Transaction{txCall})
   543  
   544  		// check
   545  		tail := neb.BlockChain().TailBlock()
   546  
   547  		events, err := tail.FetchEvents(txCall.Hash())
   548  		assert.Nil(t, err)
   549  		for _, event := range events {
   550  			fmt.Printf("topic:%v--event:%v\n", event.Topic, event.Data)
   551  			if event.Topic == "chain.transactionResult" {
   552  				var jEvent SysEvent
   553  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
   554  					assert.Equal(t, tt.contractExpectedErr, jEvent.Err)
   555  					assert.Equal(t, tt.contractExpectedResult, jEvent.Result)
   556  				}
   557  			} else {
   558  				var jEvent InnerEvent
   559  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
   560  					assert.Equal(t, tt.innerExpectedErr, jEvent.Error)
   561  				}
   562  			}
   563  
   564  		}
   565  
   566  	}
   567  }
   568  
   569  // optimized
   570  func TestInnerTransactionsGasLimit(t *testing.T) {
   571  	core.NebCompatibility = core.NewCompatibilityLocal()
   572  	tests := []struct {
   573  		name              string
   574  		contracts         []contract
   575  		call              call
   576  		expectedErr       string
   577  		gasArr            []int
   578  		gasExpectedErr    []string
   579  		gasExpectedResult []string
   580  	}{
   581  		{
   582  			"deploy test_require_module.js",
   583  			[]contract{
   584  				contract{
   585  					"./test/inner_call_tests/test_inner_transaction.js",
   586  					"js",
   587  					"",
   588  				},
   589  				contract{
   590  					"./test/inner_call_tests/bank_vault_inner_contract.js",
   591  					"js",
   592  					"",
   593  				},
   594  				contract{
   595  					"./test/inner_call_tests/bank_vault_final_contract.js",
   596  					"js",
   597  					"",
   598  				},
   599  			},
   600  			call{
   601  				"save",
   602  				"[1]",
   603  				[]string{""},
   604  			},
   605  			"multi execution failed",
   606  			//96093 “”	"\"\""
   607  			//95269	insufficient gas "null"	B+C执行完毕,代码回到A执行失败
   608  			//95105	insufficient gas "null"
   609  			//95092	insufficient gas	"\"\""	C刚好最后一句代码gas limit
   610  			//94710	insufficient gas "null"
   611  			//94697	insufficient gas "null"
   612  			//57249	insufficient gas "null"
   613  			//57248 insufficient gas "null"
   614  			//53000	insufficient gas "null"
   615  			[]int{20175, 20174, 53000, 57248, 57249, 94697, 94710, 95092, 95105, 95269, 96093},
   616  			// []int{53000},
   617  			//95093->95105, 94698->94710
   618  			//96093 “”	"\"\""
   619  			//95269	insufficient gas "null"	B+C执行完毕,代码回到A执行失败
   620  			//95105 c刚好消费殆尽,代码回到B后gas不足. Call: inner transation err [insufficient gas] engine index:0
   621  			//95092	Inner Call: inner transation err [insufficient gas] engine index:1
   622  			//94710 Inner Call: inner transation err [insufficient gas] engine index:1","execute_result":"inner transation err [insufficient gas] engine index:1"
   623  			//94697 调用C的时候B消耗完毕	Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:1
   624  			//57249 Inner Call: inner transation err [insufficient gas] engine index:0
   625  			//57248 调用B的时候,A消耗完毕 Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:0
   626  			//53000 Inner Call: inner transation err [preparation inner nvm insufficient gas] engine index:0
   627  			//20174	out of gas limit 	""
   628  			//20175 insufficient gas "null"
   629  			//20000
   630  			[]string{"insufficient gas", "out of gas limit",
   631  				"insufficient gas",
   632  				"insufficient gas",
   633  				"insufficient gas",
   634  				"insufficient gas",
   635  				"insufficient gas",
   636  				"insufficient gas",
   637  				"insufficient gas",
   638  				"insufficient gas",
   639  				"",
   640  			},
   641  			[]string{"null", "", "Inner Contract: null",
   642  				"Inner Contract: null",
   643  				"Inner Contract: null",
   644  				"Inner Contract: null",
   645  				"Inner Contract: null",
   646  				"Inner Contract: \"\"",
   647  				"Inner Contract: null",
   648  				"null",
   649  				"\"\""},
   650  		},
   651  	}
   652  
   653  	neb := mockNeb(t)
   654  	manager, err := account.NewManager(neb)
   655  	assert.Nil(t, err)
   656  
   657  	addrs := unlockAccount(t, neb)
   658  	from := addrs[0]
   659  
   660  	// mint height 2, inner contracts >= 3
   661  	mintBlock(t, neb, nil)
   662  
   663  	for _, tt := range tests {
   664  
   665  		txs := []*core.Transaction{}
   666  		contractsAddr := []string{}
   667  		// t.Run(tt.name, func(t *testing.T) {
   668  		for k, v := range tt.contracts {
   669  			data, err := ioutil.ReadFile(v.contractPath)
   670  			assert.Nil(t, err, "contract path read error")
   671  			source := string(data)
   672  			sourceType := "js"
   673  			argsDeploy := ""
   674  			deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   675  			payloadDeploy, _ := deploy.ToBytes()
   676  
   677  			value, _ := util.NewUint128FromInt(0)
   678  			gasLimit, _ := util.NewUint128FromInt(200000)
   679  			txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   680  			assert.Nil(t, err)
   681  			assert.Nil(t, manager.SignTransaction(from, txDeploy))
   682  			txs = append(txs, txDeploy)
   683  
   684  			contractAddr, err := txDeploy.GenerateContractAddress()
   685  			assert.Nil(t, err)
   686  			contractsAddr = append(contractsAddr, contractAddr.String())
   687  		}
   688  		// })
   689  
   690  		// mint for contract deploy
   691  		mintBlock(t, neb, txs)
   692  
   693  		for _, v := range contractsAddr {
   694  			contract, err := core.AddressParse(v)
   695  			assert.Nil(t, err)
   696  			_, err = neb.BlockChain().TailBlock().CheckContract(contract)
   697  			assert.Nil(t, err)
   698  		}
   699  
   700  		proxyContractAddress, _ := core.AddressParse(contractsAddr[0])
   701  		calleeContract := contractsAddr[1]
   702  		callToContract := contractsAddr[2]
   703  
   704  		callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", 1]", calleeContract, callToContract))
   705  		payloadCall, _ := callPayload.ToBytes()
   706  
   707  		// call tx
   708  		for i := 0; i < len(tt.gasArr); i++ {
   709  
   710  			value, _ := util.NewUint128FromInt(6)
   711  			gasLimit, _ := util.NewUint128FromInt(int64(tt.gasArr[i]))
   712  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   713  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   714  			assert.Nil(t, err)
   715  			assert.Nil(t, manager.SignTransaction(from, txCall))
   716  
   717  			// mint for contract call
   718  			mintBlock(t, neb, []*core.Transaction{txCall})
   719  
   720  			tail := neb.BlockChain().TailBlock()
   721  			events, err := tail.WorldState().FetchEvents(txCall.Hash())
   722  			assert.Nil(t, err)
   723  			for _, tx := range tail.Transactions() {
   724  				// fmt.Println("=========>Tx", tx.Hash(), tx.GasLimit(), txCall.Hash())
   725  				assert.Equal(t, tx.Hash(), txCall.Hash())
   726  			}
   727  			for _, event := range events {
   728  				var jEvent SysEvent
   729  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
   730  					if jEvent.Hash != "" {
   731  						assert.Equal(t, tt.gasExpectedErr[i], jEvent.Err)
   732  						assert.Equal(t, tt.gasExpectedResult[i], jEvent.Result)
   733  					}
   734  				}
   735  			}
   736  
   737  		}
   738  	}
   739  }
   740  
   741  func TestInnerTransactionsMemLimit(t *testing.T) {
   742  	core.NebCompatibility = core.NewCompatibilityLocal()
   743  	tests := []struct {
   744  		name              string
   745  		contracts         []contract
   746  		call              call
   747  		expectedErr       string
   748  		memArr            []int
   749  		memExpectedErr    []string
   750  		memExpectedResult []string
   751  	}{
   752  		{
   753  			"deploy test_require_module.js",
   754  			[]contract{
   755  				contract{
   756  					"./test/inner_call_tests/test_inner_transaction.js",
   757  					"js",
   758  					"",
   759  				},
   760  				contract{
   761  					"./test/inner_call_tests/bank_vault_inner_contract.js",
   762  					"js",
   763  					"",
   764  				},
   765  				contract{
   766  					"./test/inner_call_tests/bank_vault_final_contract.js",
   767  					"js",
   768  					"",
   769  				},
   770  			},
   771  			call{
   772  				"saveMem",
   773  				"[1]",
   774  				[]string{""},
   775  			},
   776  			"multi execution failed",
   777  			[]int{5 * 1024 * 1024, 10 * 1024 * 1024, 20 * 1024 * 1024, 40 * 1024 * 1024},
   778  			// []int{40 * 1024 * 1024},
   779  			[]string{"",
   780  				"exceed memory limits",
   781  				"exceed memory limits",
   782  				"exceed memory limits"},
   783  			[]string{"\"\"",
   784  				"Inner Contract: null", "Inner Contract: null", "null",
   785  			},
   786  		},
   787  	}
   788  
   789  	neb := mockNeb(t)
   790  	manager, err := account.NewManager(neb)
   791  	assert.Nil(t, err)
   792  
   793  	addrs := unlockAccount(t, neb)
   794  	from := addrs[0]
   795  
   796  	// mint height 2, inner contracts >= 3
   797  	mintBlock(t, neb, nil)
   798  
   799  	for _, tt := range tests {
   800  		for i := 0; i < len(tt.memArr); i++ {
   801  
   802  			txs := []*core.Transaction{}
   803  			contractsAddr := []string{}
   804  			for k, v := range tt.contracts {
   805  				data, err := ioutil.ReadFile(v.contractPath)
   806  				assert.Nil(t, err, "contract path read error")
   807  				source := string(data)
   808  				sourceType := "js"
   809  				argsDeploy := ""
   810  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   811  				payloadDeploy, _ := deploy.ToBytes()
   812  
   813  				value, _ := util.NewUint128FromInt(0)
   814  				gasLimit, _ := util.NewUint128FromInt(200000)
   815  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   816  				assert.Nil(t, err)
   817  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
   818  				txs = append(txs, txDeploy)
   819  
   820  				contractAddr, err := txDeploy.GenerateContractAddress()
   821  				assert.Nil(t, err)
   822  				contractsAddr = append(contractsAddr, contractAddr.String())
   823  			}
   824  
   825  			// mint for contract deploy
   826  			mintBlock(t, neb, txs)
   827  
   828  			for _, v := range contractsAddr {
   829  				contract, err := core.AddressParse(v)
   830  				assert.Nil(t, err)
   831  				_, err = neb.BlockChain().TailBlock().CheckContract(contract)
   832  				assert.Nil(t, err)
   833  			}
   834  
   835  			calleeContract := contractsAddr[1]
   836  			callToContract := contractsAddr[2]
   837  			callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.memArr[i]))
   838  			payloadCall, _ := callPayload.ToBytes()
   839  
   840  			value, _ := util.NewUint128FromInt(6)
   841  			gasLimit, _ := util.NewUint128FromInt(5000000)
   842  			proxyContractAddress, err := core.AddressParse(contractsAddr[0])
   843  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   844  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   845  			assert.Nil(t, err)
   846  			assert.Nil(t, manager.SignTransaction(from, txCall))
   847  
   848  			// mint for contract call
   849  			mintBlock(t, neb, []*core.Transaction{txCall})
   850  
   851  			tail := neb.BlockChain().TailBlock()
   852  			events, err := tail.FetchEvents(txCall.Hash())
   853  			for _, event := range events {
   854  				fmt.Printf("mem err:%v", event.Data)
   855  				var jEvent SysEvent
   856  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
   857  					if jEvent.Hash != "" {
   858  						assert.Equal(t, tt.memExpectedErr[i], jEvent.Err)
   859  						assert.Equal(t, tt.memExpectedResult[i], jEvent.Result)
   860  					}
   861  				}
   862  
   863  			}
   864  		}
   865  	}
   866  }
   867  
   868  func TestInnerTransactionsErr(t *testing.T) {
   869  	core.NebCompatibility = core.NewCompatibilityLocal()
   870  	tests := []struct {
   871  		name            string
   872  		contracts       []contract
   873  		call            call
   874  		errFlagArr      []uint32
   875  		expectedErrArr  []string
   876  		expectedAccount [][]string
   877  	}{
   878  		{
   879  			"deploy TestInnerTransactionsErr.js",
   880  			[]contract{
   881  				contract{
   882  					"./test/inner_call_tests/test_inner_transaction.js",
   883  					"js",
   884  					"",
   885  				},
   886  				contract{
   887  					"./test/inner_call_tests/bank_vault_inner_contract.js",
   888  					"js",
   889  					"",
   890  				},
   891  				contract{
   892  					"./test/inner_call_tests/bank_vault_final_contract.js",
   893  					"js",
   894  					"",
   895  				},
   896  			},
   897  			call{
   898  				"saveErr",
   899  				"[1]",
   900  				[]string{""},
   901  			},
   902  			[]uint32{0, 1, 2, 3},
   903  			// []uint32{0},
   904  			[]string{"Call: saveErr in test_inner_transaction",
   905  				"Call: Inner Contract: saveErr in bank_vault_inner_contract",
   906  				"Call: Inner Contract: saveErr in bank_vault_contract",
   907  				"",
   908  			},
   909  			[][]string{
   910  				{"0", "0", "0", "4999999999999903290000000", "5000000000000000000000000", "5000004280820096710000000", "5000000000000000000000000"},
   911  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
   912  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
   913  				{"1", "2", "3", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
   914  			},
   915  		},
   916  	}
   917  
   918  	for _, tt := range tests {
   919  		for i := 0; i < len(tt.errFlagArr); i++ {
   920  
   921  			neb := mockNeb(t)
   922  			manager, err := account.NewManager(neb)
   923  			assert.Nil(t, err)
   924  
   925  			addrs := unlockAccount(t, neb)
   926  			from := addrs[0]
   927  
   928  			// mint height 2, inner contracts >= 3
   929  			mintBlock(t, neb, nil)
   930  
   931  			txs := []*core.Transaction{}
   932  			contractsAddr := []string{}
   933  			for k, v := range tt.contracts {
   934  				data, err := ioutil.ReadFile(v.contractPath)
   935  				assert.Nil(t, err, "contract path read error")
   936  				source := string(data)
   937  				sourceType := "js"
   938  				argsDeploy := ""
   939  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
   940  				payloadDeploy, _ := deploy.ToBytes()
   941  
   942  				value, _ := util.NewUint128FromInt(0)
   943  				gasLimit, _ := util.NewUint128FromInt(200000)
   944  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
   945  				assert.Nil(t, err)
   946  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
   947  				txs = append(txs, txDeploy)
   948  
   949  				contractAddr, err := txDeploy.GenerateContractAddress()
   950  				assert.Nil(t, err)
   951  				contractsAddr = append(contractsAddr, contractAddr.String())
   952  			}
   953  
   954  			// mint for deploy contracts
   955  			mintBlock(t, neb, txs)
   956  
   957  			for _, v := range contractsAddr {
   958  				contract, err := core.AddressParse(v)
   959  				assert.Nil(t, err)
   960  				_, err = neb.BlockChain().TailBlock().CheckContract(contract)
   961  				assert.Nil(t, err)
   962  			}
   963  
   964  			calleeContract := contractsAddr[1]
   965  			callToContract := contractsAddr[2]
   966  			callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.errFlagArr[i]))
   967  			payloadCall, _ := callPayload.ToBytes()
   968  
   969  			value, _ := util.NewUint128FromInt(6)
   970  			gasLimit, _ := util.NewUint128FromInt(1000000)
   971  			proxyContractAddress, err := core.AddressParse(contractsAddr[0])
   972  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
   973  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
   974  			assert.Nil(t, err)
   975  			assert.Nil(t, manager.SignTransaction(from, txCall))
   976  
   977  			// mint for contract call
   978  			mintBlock(t, neb, []*core.Transaction{txCall})
   979  
   980  			tail := neb.BlockChain().TailBlock()
   981  			events, err := tail.FetchEvents(txCall.Hash())
   982  			for _, event := range events {
   983  				fmt.Printf("event:%v\n", event.Data)
   984  				var jEvent SysEvent
   985  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
   986  					if jEvent.Hash != "" {
   987  						assert.Equal(t, tt.expectedErrArr[i], jEvent.Err)
   988  					}
   989  				}
   990  
   991  			}
   992  			//chech accout
   993  			contractAddrA, err := core.AddressParse(contractsAddr[0])
   994  			accountAAcc, err := tail.GetAccount(contractAddrA.Bytes())
   995  			assert.Nil(t, err)
   996  			// fmt.Printf("account :%v\n", accountAAcc)
   997  			assert.Equal(t, tt.expectedAccount[i][0], accountAAcc.Balance().String())
   998  
   999  			contractAddrB, err := core.AddressParse(contractsAddr[1])
  1000  			accountBAcc, err := tail.GetAccount(contractAddrB.Bytes())
  1001  			assert.Nil(t, err)
  1002  			// fmt.Printf("accountB :%v\n", accountBAcc)
  1003  			assert.Equal(t, tt.expectedAccount[i][1], accountBAcc.Balance().String())
  1004  
  1005  			contractAddrC, err := core.AddressParse(contractsAddr[2])
  1006  			accountAccC, err := tail.GetAccount(contractAddrC.Bytes())
  1007  			assert.Nil(t, err)
  1008  			fmt.Printf("accountC :%v\n", accountAccC)
  1009  			assert.Equal(t, tt.expectedAccount[i][2], accountAccC.Balance().String())
  1010  
  1011  			aUser, err := tail.GetAccount(addrs[0].Bytes())
  1012  			// assert.Equal(t, tt.expectedAccount[i][3], aUser.Balance().String())
  1013  			fmt.Printf("aI:%v\n", aUser)
  1014  			bUser, err := tail.GetAccount(addrs[1].Bytes())
  1015  			assert.Equal(t, tt.expectedAccount[i][4], bUser.Balance().String())
  1016  
  1017  			cUser, err := tail.GetAccount(addrs[2].Bytes())
  1018  			fmt.Printf("cI:%v\n", cUser)
  1019  			// assert.Equal(t, tt.expectedAccount[i][5], cUser.Balance().String())
  1020  
  1021  			// fmt.Printf("b:%v\n", bUser)
  1022  			// assert.Equal(t, tt.expectedAccount[i][4], cUser.Balance().String())
  1023  			dUser, err := tail.GetAccount(addrs[3].Bytes())
  1024  			assert.Equal(t, tt.expectedAccount[i][6], dUser.Balance().String())
  1025  			// fmt.Printf("d:%v\n", dUser)
  1026  			// assert.Equal(t, tt.expectedAccount[i][4], dUser.Balance().String())
  1027  		}
  1028  	}
  1029  }
  1030  
  1031  func TestInnerTransactionsValue(t *testing.T) {
  1032  	core.NebCompatibility = core.NewCompatibilityLocal()
  1033  	tests := []struct {
  1034  		name            string
  1035  		contracts       []contract
  1036  		call            call
  1037  		errValueArr     []string
  1038  		expectedErrArr  []string
  1039  		expectedAccount [][]string
  1040  	}{
  1041  		{
  1042  			"deploy TestInnerTransactionsValue",
  1043  			[]contract{
  1044  				contract{
  1045  					"./test/inner_call_tests/test_inner_transaction.js",
  1046  					"js",
  1047  					"",
  1048  				},
  1049  				contract{
  1050  					"./test/inner_call_tests/bank_vault_inner_contract.js",
  1051  					"js",
  1052  					"",
  1053  				},
  1054  				contract{
  1055  					"./test/inner_call_tests/bank_vault_final_contract.js",
  1056  					"js",
  1057  					"",
  1058  				},
  1059  			},
  1060  			call{
  1061  				"saveValue",
  1062  				"[1]",
  1063  				[]string{""},
  1064  			},
  1065  			[]string{"-1", "340282366920938463463374607431768211455", "340282366920938463463374607431768211456",
  1066  				"1.1", "NaN", "undefined", "null", "infinity", "", "\"\""},
  1067  			// []string{"0"},
  1068  			[]string{"Call: Inner Call: invalid value",
  1069  				"Call: Inner Contract: inner transfer failed",
  1070  				"Call: Inner Contract: uint128: overflow",
  1071  				"Call: Inner Call: invalid value",
  1072  				"Call: Inner Call: invalid value",
  1073  				"Call: BigNumber Error: new BigNumber() not a number: undefined",
  1074  				"Call: BigNumber Error: new BigNumber() not a number: null",
  1075  				"Call: BigNumber Error: new BigNumber() not a number: infinity",
  1076  				"",
  1077  				"invalid function of call payload",
  1078  			},
  1079  			[][]string{
  1080  				{"0", "0", "0", "4999999999999903290000000", "5000000000000000000000000", "5000004280820096710000000", "5000000000000000000000000"},
  1081  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1082  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1083  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1084  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1085  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1086  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1087  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1088  				{"6", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1089  				{"0", "0", "0", "4999999999999871253000000", "5000000000000000000000000", "5000004280820128747000000", "5000000000000000000000000"},
  1090  			},
  1091  		},
  1092  	}
  1093  	for _, tt := range tests {
  1094  		for i := 0; i < len(tt.errValueArr); i++ {
  1095  
  1096  			neb := mockNeb(t)
  1097  			manager, err := account.NewManager(neb)
  1098  			assert.Nil(t, err)
  1099  
  1100  			addrs := unlockAccount(t, neb)
  1101  			from := addrs[0]
  1102  
  1103  			// mint height 2, inner contracts >= 3
  1104  			mintBlock(t, neb, nil)
  1105  
  1106  			txs := []*core.Transaction{}
  1107  			contractsAddr := []string{}
  1108  			for k, v := range tt.contracts {
  1109  				data, err := ioutil.ReadFile(v.contractPath)
  1110  				assert.Nil(t, err, "contract path read error")
  1111  				source := string(data)
  1112  				sourceType := "js"
  1113  				argsDeploy := ""
  1114  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1115  				payloadDeploy, _ := deploy.ToBytes()
  1116  
  1117  				value, _ := util.NewUint128FromInt(0)
  1118  				gasLimit, _ := util.NewUint128FromInt(200000)
  1119  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1120  				assert.Nil(t, err)
  1121  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1122  				txs = append(txs, txDeploy)
  1123  
  1124  				contractAddr, err := txDeploy.GenerateContractAddress()
  1125  				assert.Nil(t, err)
  1126  				contractsAddr = append(contractsAddr, contractAddr.String())
  1127  			}
  1128  
  1129  			// mint block for contract deploy
  1130  			mintBlock(t, neb, txs)
  1131  
  1132  			for _, v := range contractsAddr {
  1133  				contract, err := core.AddressParse(v)
  1134  				assert.Nil(t, err)
  1135  				_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1136  				assert.Nil(t, err)
  1137  			}
  1138  
  1139  			calleeContract := contractsAddr[1]
  1140  			callToContract := contractsAddr[2]
  1141  			callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%s\"]", calleeContract, callToContract, tt.errValueArr[i]))
  1142  			payloadCall, _ := callPayload.ToBytes()
  1143  
  1144  			value, _ := util.NewUint128FromInt(6)
  1145  			gasLimit, _ := util.NewUint128FromInt(1000000)
  1146  			proxyContractAddress, err := core.AddressParse(contractsAddr[0])
  1147  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1148  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1149  			assert.Nil(t, err)
  1150  			assert.Nil(t, manager.SignTransaction(from, txCall))
  1151  
  1152  			// mint for contract call
  1153  			mintBlock(t, neb, []*core.Transaction{txCall})
  1154  
  1155  			tail := neb.BlockChain().TailBlock()
  1156  			events, err := tail.FetchEvents(txCall.Hash())
  1157  			for _, event := range events {
  1158  				fmt.Printf("event:%v\n", event.Data)
  1159  				var jEvent SysEvent
  1160  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
  1161  					if jEvent.Hash != "" {
  1162  						assert.Equal(t, tt.expectedErrArr[i], jEvent.Err)
  1163  					}
  1164  				}
  1165  
  1166  			}
  1167  			//chech accout
  1168  			contractAddrA, err := core.AddressParse(contractsAddr[0])
  1169  			accountAAcc, err := tail.GetAccount(contractAddrA.Bytes())
  1170  			assert.Nil(t, err)
  1171  			// fmt.Printf("account :%v\n", accountAAcc)
  1172  			assert.Equal(t, tt.expectedAccount[i][0], accountAAcc.Balance().String())
  1173  
  1174  			contractAddrB, err := core.AddressParse(contractsAddr[1])
  1175  			accountBAcc, err := tail.GetAccount(contractAddrB.Bytes())
  1176  			assert.Nil(t, err)
  1177  			// fmt.Printf("accountB :%v\n", accountBAcc)
  1178  			assert.Equal(t, tt.expectedAccount[i][1], accountBAcc.Balance().String())
  1179  
  1180  			contractAddrC, err := core.AddressParse(contractsAddr[2])
  1181  			accountAccC, err := tail.GetAccount(contractAddrC.Bytes())
  1182  			assert.Nil(t, err)
  1183  			fmt.Printf("accountC :%v\n", accountAccC)
  1184  			assert.Equal(t, tt.expectedAccount[i][2], accountAccC.Balance().String())
  1185  
  1186  			aUser, err := tail.GetAccount(addrs[0].Bytes())
  1187  			// assert.Equal(t, tt.expectedAccount[i][3], aUser.Balance().String())
  1188  			fmt.Printf("aI:%v\n", aUser)
  1189  			bUser, err := tail.GetAccount(addrs[1].Bytes())
  1190  			assert.Equal(t, tt.expectedAccount[i][4], bUser.Balance().String())
  1191  
  1192  			cUser, err := tail.GetAccount(addrs[2].Bytes())
  1193  			fmt.Printf("cI:%v\n", cUser)
  1194  			// assert.Equal(t, tt.expectedAccount[i][5], cUser.Balance().String())
  1195  
  1196  			// fmt.Printf("b:%v\n", bUser)
  1197  			// assert.Equal(t, tt.expectedAccount[i][4], cUser.Balance().String())
  1198  			dUser, err := tail.GetAccount(addrs[3].Bytes())
  1199  			assert.Equal(t, tt.expectedAccount[i][6], dUser.Balance().String())
  1200  			// fmt.Printf("d:%v\n", dUser)
  1201  			// assert.Equal(t, tt.expectedAccount[i][4], dUser.Balance().String())
  1202  		}
  1203  	}
  1204  }
  1205  
  1206  func TestGetContractErr(t *testing.T) {
  1207  	core.NebCompatibility = core.NewCompatibilityLocal()
  1208  	tests := []struct {
  1209  		name      string
  1210  		contracts []contract
  1211  		calls     []call
  1212  	}{
  1213  		{
  1214  			"TestGetContractErr",
  1215  			[]contract{
  1216  				contract{
  1217  					"./test/inner_call_tests/test_inner_transaction.js",
  1218  					"js",
  1219  					"",
  1220  				},
  1221  				contract{
  1222  					"./test/inner_call_tests/bank_vault_inner_contract.js",
  1223  					"js",
  1224  					"",
  1225  				},
  1226  			},
  1227  			[]call{
  1228  				call{
  1229  					"getSource",
  1230  					"[1]",
  1231  					[]string{"Call: Inner Call: no contract at this address"},
  1232  				},
  1233  			},
  1234  		},
  1235  	}
  1236  
  1237  	for _, tt := range tests {
  1238  		for i := 0; i < len(tt.calls); i++ {
  1239  
  1240  			neb := mockNeb(t)
  1241  			manager, err := account.NewManager(neb)
  1242  			assert.Nil(t, err)
  1243  
  1244  			addrs := unlockAccount(t, neb)
  1245  			from := addrs[0]
  1246  
  1247  			// mint height 2, inner contracts >= 3
  1248  			mintBlock(t, neb, nil)
  1249  
  1250  			txs := []*core.Transaction{}
  1251  			contractsAddr := []string{}
  1252  			for k, v := range tt.contracts {
  1253  				data, err := ioutil.ReadFile(v.contractPath)
  1254  				assert.Nil(t, err, "contract path read error")
  1255  				source := string(data)
  1256  				sourceType := "js"
  1257  				argsDeploy := ""
  1258  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1259  				payloadDeploy, _ := deploy.ToBytes()
  1260  
  1261  				value, _ := util.NewUint128FromInt(0)
  1262  				gasLimit, _ := util.NewUint128FromInt(200000)
  1263  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1264  				assert.Nil(t, err)
  1265  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1266  				txs = append(txs, txDeploy)
  1267  
  1268  				contractAddr, err := txDeploy.GenerateContractAddress()
  1269  				assert.Nil(t, err)
  1270  				contractsAddr = append(contractsAddr, contractAddr.String())
  1271  			}
  1272  
  1273  			// mint for contract deploy
  1274  			mintBlock(t, neb, txs)
  1275  
  1276  			for _, v := range contractsAddr {
  1277  				contract, err := core.AddressParse(v)
  1278  				assert.Nil(t, err)
  1279  				_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1280  				assert.Nil(t, err)
  1281  			}
  1282  
  1283  			calleeContract := "123456789"
  1284  			callToContract := "123456789"
  1285  			callPayload, _ := core.NewCallPayload(tt.calls[i].function, fmt.Sprintf("[\"%s\", \"%s\"]", calleeContract, callToContract))
  1286  			payloadCall, _ := callPayload.ToBytes()
  1287  
  1288  			value, _ := util.NewUint128FromInt(6)
  1289  			gasLimit, _ := util.NewUint128FromInt(1000000)
  1290  			proxyContractAddress, err := core.AddressParse(contractsAddr[0])
  1291  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1292  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1293  			assert.Nil(t, err)
  1294  			assert.Nil(t, manager.SignTransaction(from, txCall))
  1295  
  1296  			// mint for contract call
  1297  			mintBlock(t, neb, []*core.Transaction{txCall})
  1298  
  1299  			tail := neb.BlockChain().TailBlock()
  1300  			events, err := tail.FetchEvents(txCall.Hash())
  1301  			for _, event := range events {
  1302  				fmt.Printf("event:%v\n", events)
  1303  				var jEvent SysEvent
  1304  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
  1305  					if jEvent.Hash != "" {
  1306  						assert.Equal(t, tt.calls[i].exceptArgs[0], jEvent.Err)
  1307  					}
  1308  					fmt.Printf("event:%v\n", jEvent.Err)
  1309  				}
  1310  
  1311  			}
  1312  		}
  1313  	}
  1314  }
  1315  
  1316  func TestInnerTransactionsRand(t *testing.T) {
  1317  	core.NebCompatibility = core.NewCompatibilityLocal()
  1318  	tests := []struct {
  1319  		name      string
  1320  		contracts []contract
  1321  		call      call
  1322  	}{
  1323  		{
  1324  			"test TestInnerTransactionsRand",
  1325  			[]contract{
  1326  				contract{
  1327  					"./test/inner_call_tests/test_inner_transaction.js",
  1328  					"js",
  1329  					"",
  1330  				},
  1331  				contract{
  1332  					"./test/inner_call_tests/bank_vault_inner_contract.js",
  1333  					"js",
  1334  					"",
  1335  				},
  1336  				contract{
  1337  					"./test/inner_call_tests/bank_vault_final_contract.js",
  1338  					"js",
  1339  					"",
  1340  				},
  1341  			},
  1342  			call{
  1343  				"getRandom",
  1344  				"[1]",
  1345  				[]string{""},
  1346  			},
  1347  		},
  1348  	}
  1349  
  1350  	for _, tt := range tests {
  1351  		// for i := 0; i < len(tt); i++ {
  1352  
  1353  		neb := mockNeb(t)
  1354  		manager, err := account.NewManager(neb)
  1355  		assert.Nil(t, err)
  1356  
  1357  		addrs := unlockAccount(t, neb)
  1358  		from := addrs[0]
  1359  
  1360  		// mint height 2, inner contracts >= 3
  1361  		mintBlock(t, neb, nil)
  1362  
  1363  		txs := []*core.Transaction{}
  1364  		contractsAddr := []string{}
  1365  		for k, v := range tt.contracts {
  1366  			data, err := ioutil.ReadFile(v.contractPath)
  1367  			assert.Nil(t, err, "contract path read error")
  1368  			source := string(data)
  1369  			sourceType := "js"
  1370  			argsDeploy := ""
  1371  			deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1372  			payloadDeploy, _ := deploy.ToBytes()
  1373  
  1374  			value, _ := util.NewUint128FromInt(0)
  1375  			gasLimit, _ := util.NewUint128FromInt(200000)
  1376  			txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1377  			assert.Nil(t, err)
  1378  			assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1379  			txs = append(txs, txDeploy)
  1380  
  1381  			contractAddr, err := txDeploy.GenerateContractAddress()
  1382  			assert.Nil(t, err)
  1383  			contractsAddr = append(contractsAddr, contractAddr.String())
  1384  		}
  1385  
  1386  		// mint for contract deploy
  1387  		mintBlock(t, neb, txs)
  1388  
  1389  		for _, v := range contractsAddr {
  1390  			contract, err := core.AddressParse(v)
  1391  			assert.Nil(t, err)
  1392  			_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1393  			assert.Nil(t, err)
  1394  		}
  1395  
  1396  		calleeContract := contractsAddr[1]
  1397  		callToContract := contractsAddr[2]
  1398  		callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\"]", calleeContract, callToContract))
  1399  		payloadCall, _ := callPayload.ToBytes()
  1400  
  1401  		value, _ := util.NewUint128FromInt(6)
  1402  		gasLimit, _ := util.NewUint128FromInt(int64(100000))
  1403  		proxyContractAddress, err := core.AddressParse(contractsAddr[0])
  1404  		txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1405  			uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1406  		assert.Nil(t, err)
  1407  		assert.Nil(t, manager.SignTransaction(from, txCall))
  1408  
  1409  		// mint for contract call
  1410  		mintBlock(t, neb, []*core.Transaction{txCall})
  1411  
  1412  		tail := neb.BlockChain().TailBlock()
  1413  		events, err := tail.FetchEvents(txCall.Hash())
  1414  		for _, event := range events {
  1415  
  1416  			var jEvent SysEvent
  1417  			if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
  1418  				fmt.Printf("event:%v\n", event.Data)
  1419  				if jEvent.Hash != "" {
  1420  					assert.Equal(t, "", jEvent.Err)
  1421  				}
  1422  			}
  1423  
  1424  		}
  1425  		// }
  1426  	}
  1427  }
  1428  
  1429  func TestInnerTransactionsTimeOut(t *testing.T) {
  1430  	core.NebCompatibility = core.NewCompatibilityLocal()
  1431  	tests := []struct {
  1432  		name           string
  1433  		contracts      []contract
  1434  		call           call
  1435  		errFlagArr     []uint32
  1436  		expectedErrArr []string
  1437  	}{
  1438  		{
  1439  			"deploy TestInnerTransactionsErr.js",
  1440  			[]contract{
  1441  				contract{
  1442  					"./test/inner_call_tests/test_inner_transaction.js",
  1443  					"js",
  1444  					"",
  1445  				},
  1446  				contract{
  1447  					"./test/inner_call_tests/bank_vault_inner_contract.js",
  1448  					"js",
  1449  					"",
  1450  				},
  1451  				contract{
  1452  					"./test/inner_call_tests/bank_vault_final_contract.js",
  1453  					"js",
  1454  					"",
  1455  				},
  1456  			},
  1457  			call{
  1458  				"saveTimeOut",
  1459  				"[1]",
  1460  				[]string{""},
  1461  			},
  1462  			[]uint32{0, 1, 2},
  1463  			[]string{"insufficient gas",
  1464  				"insufficient gas",
  1465  				"insufficient gas"},
  1466  		},
  1467  	}
  1468  
  1469  	for _, tt := range tests {
  1470  		for i := 0; i < len(tt.errFlagArr); i++ {
  1471  
  1472  			neb := mockNeb(t)
  1473  			manager, err := account.NewManager(neb)
  1474  			assert.Nil(t, err)
  1475  
  1476  			addrs := unlockAccount(t, neb)
  1477  			from := addrs[0]
  1478  
  1479  			// mint height 2, inner contracts >= 3
  1480  			mintBlock(t, neb, nil)
  1481  
  1482  			txs := []*core.Transaction{}
  1483  			contractsAddr := []string{}
  1484  			for k, v := range tt.contracts {
  1485  				data, err := ioutil.ReadFile(v.contractPath)
  1486  				assert.Nil(t, err, "contract path read error")
  1487  				source := string(data)
  1488  				sourceType := "js"
  1489  				argsDeploy := ""
  1490  				deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1491  				payloadDeploy, _ := deploy.ToBytes()
  1492  
  1493  				value, _ := util.NewUint128FromInt(0)
  1494  				gasLimit, _ := util.NewUint128FromInt(5000000)
  1495  				txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1496  				assert.Nil(t, err)
  1497  				assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1498  				txs = append(txs, txDeploy)
  1499  
  1500  				contractAddr, err := txDeploy.GenerateContractAddress()
  1501  				assert.Nil(t, err)
  1502  				contractsAddr = append(contractsAddr, contractAddr.String())
  1503  			}
  1504  
  1505  			// mint for contract deploy
  1506  			mintBlock(t, neb, txs)
  1507  
  1508  			for _, v := range contractsAddr {
  1509  				contract, err := core.AddressParse(v)
  1510  				assert.Nil(t, err)
  1511  				_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1512  				assert.Nil(t, err)
  1513  			}
  1514  
  1515  			calleeContract := contractsAddr[1]
  1516  			callToContract := contractsAddr[2]
  1517  			callPayload, _ := core.NewCallPayload(tt.call.function, fmt.Sprintf("[\"%s\", \"%s\", \"%d\"]", calleeContract, callToContract, tt.errFlagArr[i]))
  1518  			payloadCall, _ := callPayload.ToBytes()
  1519  
  1520  			value, _ := util.NewUint128FromInt(6)
  1521  			gasLimit, _ := util.NewUint128FromInt(1000000)
  1522  			proxyContractAddress, err := core.AddressParse(contractsAddr[0])
  1523  			txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1524  				uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1525  			assert.Nil(t, err)
  1526  			assert.Nil(t, manager.SignTransaction(from, txCall))
  1527  
  1528  			// mint for contract call
  1529  			mintBlock(t, neb, []*core.Transaction{txCall})
  1530  
  1531  			tail := neb.BlockChain().TailBlock()
  1532  			events, err := tail.FetchEvents(txCall.Hash())
  1533  			for _, event := range events {
  1534  				fmt.Printf("event:%v\n", event.Data)
  1535  				var jEvent SysEvent
  1536  				if err := json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
  1537  					if jEvent.Hash != "" {
  1538  						assert.Equal(t, tt.expectedErrArr[i], jEvent.Err)
  1539  					}
  1540  				}
  1541  
  1542  			}
  1543  		}
  1544  	}
  1545  }
  1546  
  1547  func TestInnerTxInstructionCounter(t *testing.T) {
  1548  	core.NebCompatibility = core.NewCompatibilityLocal()
  1549  	tests := []struct {
  1550  		name      string
  1551  		contracts []contract
  1552  		calls     []call
  1553  	}{
  1554  		{
  1555  			"deploy contracts",
  1556  			[]contract{
  1557  				contract{
  1558  					"./test/instruction_counter_tests/inner_contract_callee.js",
  1559  					"js",
  1560  					"",
  1561  				},
  1562  				contract{
  1563  					"./test/instruction_counter_tests/inner_contract_caller.js",
  1564  					"js",
  1565  					"",
  1566  				},
  1567  			},
  1568  			[]call{
  1569  				call{
  1570  					"callWhile",
  1571  					"",
  1572  					[]string{"57296000000"}, // 57286000000  for instruction_counter.js v1.0.0
  1573  				},
  1574  			},
  1575  		},
  1576  	}
  1577  	tt := tests[0]
  1578  	for _, call := range tt.calls {
  1579  
  1580  		neb := mockNeb(t)
  1581  		manager, err := account.NewManager(neb)
  1582  		assert.Nil(t, err)
  1583  
  1584  		addrs := unlockAccount(t, neb)
  1585  		from := addrs[0]
  1586  
  1587  		// mint height 2, inner contracts >= 3
  1588  		mintBlock(t, neb, nil)
  1589  
  1590  		txs := []*core.Transaction{}
  1591  		contractsAddr := []string{}
  1592  
  1593  		// t.Run(tt.name, func(t *testing.T) {
  1594  		for k, v := range tt.contracts {
  1595  			data, err := ioutil.ReadFile(v.contractPath)
  1596  			assert.Nil(t, err, "contract path read error")
  1597  			source := string(data)
  1598  			sourceType := "js"
  1599  			argsDeploy := ""
  1600  			deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1601  			payloadDeploy, _ := deploy.ToBytes()
  1602  
  1603  			value, _ := util.NewUint128FromInt(0)
  1604  			gasLimit, _ := util.NewUint128FromInt(200000)
  1605  			txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(k+1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1606  			assert.Nil(t, err)
  1607  			assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1608  			txs = append(txs, txDeploy)
  1609  
  1610  			contractAddr, err := txDeploy.GenerateContractAddress()
  1611  			assert.Nil(t, err)
  1612  			contractsAddr = append(contractsAddr, contractAddr.String())
  1613  		}
  1614  		// })
  1615  
  1616  		// mint for contract deploy
  1617  		mintBlock(t, neb, txs)
  1618  
  1619  		for _, v := range contractsAddr {
  1620  			contract, err := core.AddressParse(v)
  1621  			assert.Nil(t, err)
  1622  			_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1623  			assert.Nil(t, err)
  1624  		}
  1625  
  1626  		callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf("[\"%s\"]", contractsAddr[0]))
  1627  		payloadCall, _ := callPayload.ToBytes()
  1628  
  1629  		value, _ := util.NewUint128FromInt(0)
  1630  		gasLimit, _ := util.NewUint128FromInt(200000)
  1631  
  1632  		tail := neb.BlockChain().TailBlock()
  1633  		aUser, err := tail.GetAccount(from.Bytes())
  1634  		balBefore := aUser.Balance()
  1635  
  1636  		proxyContractAddress, err := core.AddressParse(contractsAddr[1])
  1637  		txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1638  			uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1639  		assert.Nil(t, err)
  1640  		assert.Nil(t, manager.SignTransaction(from, txCall))
  1641  
  1642  		// mint for contract call
  1643  		mintBlock(t, neb, []*core.Transaction{txCall})
  1644  
  1645  		// // check
  1646  		tail = neb.BlockChain().TailBlock()
  1647  		events, err := tail.FetchEvents(txCall.Hash())
  1648  		assert.Nil(t, err)
  1649  		for _, event := range events {
  1650  			fmt.Println("==============", event.Data)
  1651  		}
  1652  
  1653  		aUser, err = tail.GetAccount(from.Bytes())
  1654  		assert.Nil(t, err)
  1655  		det, err := balBefore.Sub(aUser.Balance())
  1656  		assert.Nil(t, err)
  1657  		// fmt.Println("from account balance change: ", det.String())
  1658  		assert.Equal(t, call.exceptArgs[0], det.String())
  1659  		fmt.Printf("aI:%v\n", aUser)
  1660  	}
  1661  }
  1662  
  1663  func TestMultiLibVersionCall(t *testing.T) {
  1664  	core.NebCompatibility = core.NewCompatibilityLocal()
  1665  	m := core.NebCompatibility.V8JSLibVersionHeightMap().Data
  1666  	m["1.1.0"] = 4
  1667  	m["1.0.5"] = 3
  1668  	defer func() {
  1669  		m["1.1.0"] = 3
  1670  		m["1.0.5"] = 2
  1671  	}()
  1672  
  1673  	tests := []struct {
  1674  		name  string
  1675  		calls []call
  1676  	}{
  1677  		{
  1678  			"call contracts",
  1679  			[]call{
  1680  				call{
  1681  					"testInnerCall",
  1682  					"[\"%s\", \"undefined\"]", // in version before 1.1.0, typeof(Blockchain.Contract)=='undefined'
  1683  					[]string{"\"\"", ""},
  1684  				},
  1685  				call{
  1686  					"testRandom",
  1687  					// before 1.1.0
  1688  					// true -- Blockchain.block.seed is not empty
  1689  					// true -- Math.random.seed exists
  1690  					//
  1691  					// since 1.1.0
  1692  					// false -- Blockchain.block.seed is empty
  1693  					// false -- Math.random.seed not exist
  1694  					"[\"%s\", true, true, false, false]",
  1695  					[]string{"\"\"", ""},
  1696  				},
  1697  			},
  1698  		},
  1699  	}
  1700  	tt := tests[0]
  1701  
  1702  	neb := mockNeb(t)
  1703  	manager, err := account.NewManager(neb)
  1704  	assert.Nil(t, err)
  1705  
  1706  	addrs := unlockAccount(t, neb)
  1707  	from := addrs[0]
  1708  
  1709  	// mint height 2, inner contracts >= 3
  1710  	mintBlock(t, neb, nil)
  1711  
  1712  	txs := []*core.Transaction{}
  1713  	contractsAddr := []string{}
  1714  
  1715  	data, err := ioutil.ReadFile("./test/inner_call_tests/callee.js")
  1716  	assert.Nil(t, err, "contract path read error")
  1717  	source := string(data)
  1718  	sourceType := "js"
  1719  	argsDeploy := ""
  1720  	deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy)
  1721  	payloadDeploy, _ := deploy.ToBytes()
  1722  
  1723  	value, _ := util.NewUint128FromInt(0)
  1724  	gasLimit, _ := util.NewUint128FromInt(200000)
  1725  	txDeploy, err := core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(1), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1726  	assert.Nil(t, err)
  1727  	assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1728  	txs = append(txs, txDeploy)
  1729  
  1730  	contractAddr, err := txDeploy.GenerateContractAddress()
  1731  	assert.Nil(t, err)
  1732  	contractsAddr = append(contractsAddr, contractAddr.String())
  1733  
  1734  	// mint for contract deploy
  1735  	mintBlock(t, neb, txs)
  1736  
  1737  	data, err = ioutil.ReadFile("./test/inner_call_tests/caller.js")
  1738  	assert.Nil(t, err, "contract path read error")
  1739  	source = string(data)
  1740  	sourceType = "js"
  1741  	argsDeploy = ""
  1742  	deploy, _ = core.NewDeployPayload(source, sourceType, argsDeploy)
  1743  	payloadDeploy, _ = deploy.ToBytes()
  1744  
  1745  	txDeploy, err = core.NewTransaction(neb.BlockChain().ChainID(), from, from, value, uint64(2), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit)
  1746  	assert.Nil(t, err)
  1747  	assert.Nil(t, manager.SignTransaction(from, txDeploy))
  1748  
  1749  	contractAddr, err = txDeploy.GenerateContractAddress()
  1750  	assert.Nil(t, err)
  1751  	contractsAddr = append(contractsAddr, contractAddr.String())
  1752  
  1753  	// mint for contract deploy
  1754  	mintBlock(t, neb, []*core.Transaction{txDeploy})
  1755  
  1756  	for _, v := range contractsAddr {
  1757  		contract, err := core.AddressParse(v)
  1758  		assert.Nil(t, err)
  1759  		_, err = neb.BlockChain().TailBlock().CheckContract(contract)
  1760  		assert.Nil(t, err)
  1761  	}
  1762  
  1763  	for _, call := range tt.calls {
  1764  		callPayload, _ := core.NewCallPayload(call.function, fmt.Sprintf(call.args, contractsAddr[0]))
  1765  		payloadCall, _ := callPayload.ToBytes()
  1766  
  1767  		proxyContractAddress, err := core.AddressParse(contractsAddr[1])
  1768  		txCall, err := core.NewTransaction(neb.BlockChain().ChainID(), from, proxyContractAddress, value,
  1769  			uint64(len(contractsAddr)+1), core.TxPayloadCallType, payloadCall, core.TransactionGasPrice, gasLimit)
  1770  		assert.Nil(t, err)
  1771  		assert.Nil(t, manager.SignTransaction(from, txCall))
  1772  
  1773  		// mint for contract call
  1774  		mintBlock(t, neb, []*core.Transaction{txCall})
  1775  
  1776  		tail := neb.BlockChain().TailBlock()
  1777  		events, err := tail.WorldState().FetchEvents(txCall.Hash())
  1778  		assert.Nil(t, err)
  1779  		for _, event := range events {
  1780  			fmt.Println("==============", event.Data)
  1781  
  1782  			var jEvent SysEvent
  1783  			if event.Topic == core.TopicTransactionExecutionResult {
  1784  				if err = json.Unmarshal([]byte(event.Data), &jEvent); err == nil {
  1785  					assert.Equal(t, call.exceptArgs[0], jEvent.Result)
  1786  					assert.Equal(t, call.exceptArgs[1], jEvent.Err)
  1787  				}
  1788  			}
  1789  		}
  1790  
  1791  	}
  1792  }