github.com/turingchain2020/turingchain@v1.1.21/executor/executor_test.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package executor
     6  
     7  import (
     8  	"encoding/hex"
     9  	"fmt"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/turingchain2020/turingchain/client"
    15  	"github.com/turingchain2020/turingchain/client/api"
    16  	"github.com/turingchain2020/turingchain/common/address"
    17  	"github.com/turingchain2020/turingchain/queue"
    18  	"github.com/turingchain2020/turingchain/store"
    19  	_ "github.com/turingchain2020/turingchain/system"
    20  	drivers "github.com/turingchain2020/turingchain/system/dapp"
    21  	"github.com/turingchain2020/turingchain/types"
    22  	"github.com/turingchain2020/turingchain/util"
    23  	"github.com/stretchr/testify/assert"
    24  )
    25  
    26  func initEnv(cfgstring string) (*Executor, queue.Queue) {
    27  	cfg := types.NewTuringchainConfig(cfgstring)
    28  	q := queue.New("channel")
    29  	q.SetConfig(cfg)
    30  	exec := New(cfg)
    31  	exec.client = q.Client()
    32  	exec.qclient, _ = client.New(exec.client, nil)
    33  	return exec, q
    34  }
    35  
    36  func TestIsModule(t *testing.T) {
    37  	var qmodule queue.Module = &Executor{}
    38  	assert.NotNil(t, qmodule)
    39  }
    40  
    41  func TestExecutorGetTxGroup(t *testing.T) {
    42  	exec, _ := initEnv(types.GetDefaultCfgstring())
    43  	cfg := exec.client.GetConfig()
    44  	execInit(nil)
    45  	var txs []*types.Transaction
    46  	addr2, priv2 := util.Genaddress()
    47  	addr3, priv3 := util.Genaddress()
    48  	addr4, _ := util.Genaddress()
    49  	genkey := util.TestPrivkeyList[0]
    50  	txs = append(txs, util.CreateCoinsTx(cfg, genkey, addr2, types.Coin))
    51  	txs = append(txs, util.CreateCoinsTx(cfg, priv2, addr3, types.Coin))
    52  	txs = append(txs, util.CreateCoinsTx(cfg, priv3, addr4, types.Coin))
    53  	//执行三笔交易: 全部正确
    54  	txgroup, err := types.CreateTxGroup(txs, cfg.GetMinTxFeeRate())
    55  	if err != nil {
    56  		t.Error(err)
    57  		return
    58  	}
    59  	//重新签名
    60  	txgroup.SignN(0, types.SECP256K1, genkey)
    61  	txgroup.SignN(1, types.SECP256K1, priv2)
    62  	txgroup.SignN(2, types.SECP256K1, priv3)
    63  	txs = txgroup.GetTxs()
    64  	ctx := &executorCtx{
    65  		stateHash:  nil,
    66  		height:     1,
    67  		blocktime:  time.Now().Unix(),
    68  		difficulty: 1,
    69  		mainHash:   nil,
    70  		parentHash: nil,
    71  	}
    72  	execute := newExecutor(ctx, exec, nil, txs, nil)
    73  	e := execute.loadDriver(txs[0], 0)
    74  	execute.setEnv(e)
    75  	txs2 := e.GetTxs()
    76  	assert.Equal(t, txs2, txgroup.GetTxs())
    77  	for i := 0; i < len(txs); i++ {
    78  		txg, err := e.GetTxGroup(i)
    79  		assert.Nil(t, err)
    80  		assert.Equal(t, txg, txgroup.GetTxs())
    81  	}
    82  	_, err = e.GetTxGroup(len(txs))
    83  	assert.Equal(t, err, types.ErrTxGroupIndex)
    84  
    85  	//err tx group list
    86  	txs[0].Header = nil
    87  	execute = newExecutor(ctx, exec, nil, txs, nil)
    88  	e = execute.loadDriver(txs[0], 0)
    89  	execute.setEnv(e)
    90  	_, err = e.GetTxGroup(len(txs) - 1)
    91  	assert.Equal(t, err, types.ErrTxGroupFormat)
    92  }
    93  
    94  //gen 1万币需要 2s,主要是签名的花费
    95  func BenchmarkGenRandBlock(b *testing.B) {
    96  	exec, _ := initEnv(types.GetDefaultCfgstring())
    97  	cfg := exec.client.GetConfig()
    98  	_, key := util.Genaddress()
    99  	for i := 0; i < b.N; i++ {
   100  		util.CreateNoneBlock(cfg, key, 10000)
   101  	}
   102  }
   103  
   104  func TestLoadDriver(t *testing.T) {
   105  	d, err := drivers.LoadDriver("none", 0)
   106  	if err != nil {
   107  		t.Error(err)
   108  	}
   109  
   110  	if d.GetName() != "none" {
   111  		t.Error(d.GetName())
   112  	}
   113  }
   114  
   115  func TestKeyAllow(t *testing.T) {
   116  	exect, _ := initEnv(types.GetDefaultCfgstring())
   117  	execInit(nil)
   118  	key := []byte("mavl-coins-trc-exec-1wvmD6RNHzwhY4eN75WnM6JcaAvNQ4nHx:19xXg1WHzti5hzBRTUphkM8YmuX6jJkoAA")
   119  	exec := []byte("retrieve")
   120  	tx1 := "0a05636f696e73120e18010a0a1080c2d72f1a036f746520a08d0630f1cdebc8f7efa5e9283a22313271796f6361794e46374c7636433971573461767873324537553431664b536676"
   121  	tx11, _ := hex.DecodeString(tx1)
   122  	var tx12 types.Transaction
   123  	types.Decode(tx11, &tx12)
   124  	tx12.Execer = exec
   125  	ctx := &executorCtx{
   126  		stateHash:  nil,
   127  		height:     1,
   128  		blocktime:  time.Now().Unix(),
   129  		difficulty: 1,
   130  		mainHash:   nil,
   131  		parentHash: nil,
   132  	}
   133  	execute := newExecutor(ctx, exect, nil, nil, nil)
   134  	if !isAllowKeyWrite(execute, key, exec, &tx12, 0) {
   135  		t.Error("retrieve can modify exec")
   136  	}
   137  }
   138  
   139  func TestKeyAllow_evm(t *testing.T) {
   140  	exect, _ := initEnv(types.GetDefaultCfgstring())
   141  	execInit(nil)
   142  	key := []byte("mavl-coins-trc-exec-1GacM93StrZveMrPjXDoz5TxajKa9LM5HG:19EJVYexvSn1kZ6MWiKcW14daXsPpdVDuF")
   143  	exec := []byte("user.evm.0xc79c9113a71c0a4244e20f0780e7c13552f40ee30b05998a38edb08fe617aaa5")
   144  	tx1 := "0a05636f696e73120e18010a0a1080c2d72f1a036f746520a08d0630f1cdebc8f7efa5e9283a22313271796f6361794e46374c7636433971573461767873324537553431664b536676"
   145  	tx11, _ := hex.DecodeString(tx1)
   146  	var tx12 types.Transaction
   147  	types.Decode(tx11, &tx12)
   148  	tx12.Execer = exec
   149  	ctx := &executorCtx{
   150  		stateHash:  nil,
   151  		height:     1,
   152  		blocktime:  time.Now().Unix(),
   153  		difficulty: 1,
   154  		mainHash:   nil,
   155  		parentHash: nil,
   156  	}
   157  	execute := newExecutor(ctx, exect, nil, nil, nil)
   158  	if !isAllowKeyWrite(execute, key, exec, &tx12, 0) {
   159  		t.Error("user.evm.hash can modify exec")
   160  	}
   161  	//assert.Nil(t, t)
   162  }
   163  
   164  func TestKeyLocalAllow(t *testing.T) {
   165  	exec, _ := initEnv(types.GetDefaultCfgstring())
   166  	cfg := exec.client.GetConfig()
   167  	err := isAllowLocalKey(cfg, []byte("token"), []byte("LODB-token-"))
   168  	assert.Equal(t, err, types.ErrLocalKeyLen)
   169  	err = isAllowLocalKey(cfg, []byte("token"), []byte("LODB_token-a"))
   170  	assert.Equal(t, err, types.ErrLocalPrefix)
   171  	err = isAllowLocalKey(cfg, []byte("token"), []byte("LODB-token-a"))
   172  	assert.Nil(t, err)
   173  	err = isAllowLocalKey(cfg, []byte(""), []byte("LODB--a"))
   174  	assert.Equal(t, err, types.ErrLocalPrefix)
   175  	err = isAllowLocalKey(cfg, []byte("exec"), []byte("LODB-execaa"))
   176  	assert.Equal(t, err, types.ErrLocalPrefix)
   177  	err = isAllowLocalKey(cfg, []byte("exec"), []byte("-exec------aa"))
   178  	assert.Equal(t, err, types.ErrLocalPrefix)
   179  	err = isAllowLocalKey(cfg, []byte("paracross"), []byte("LODB-user.p.para.paracross-xxxx"))
   180  	assert.Equal(t, err, types.ErrLocalPrefix)
   181  	err = isAllowLocalKey(cfg, []byte("user.p.para.paracross"), []byte("LODB-user.p.para.paracross-xxxx"))
   182  	assert.Nil(t, err)
   183  	err = isAllowLocalKey(cfg, []byte("user.p.para.user.wasm.abc"), []byte("LODB-user.p.para.user.wasm.abc-xxxx"))
   184  	assert.Nil(t, err)
   185  	err = isAllowLocalKey(cfg, []byte("user.p.para.paracross"), []byte("LODB-paracross-xxxx"))
   186  	assert.Nil(t, err)
   187  }
   188  
   189  func init() {
   190  	types.AllowUserExec = append(types.AllowUserExec, []byte("demo"), []byte("demof"))
   191  }
   192  
   193  var testRegOnce sync.Once
   194  
   195  func Register(cfg *types.TuringchainConfig) {
   196  	testRegOnce.Do(func() {
   197  		drivers.Register(cfg, "demo", newdemoApp, 1)
   198  		drivers.Register(cfg, "demof", newdemofApp, 1)
   199  	})
   200  }
   201  
   202  //ErrEnvAPI 测试
   203  type demoApp struct {
   204  	*drivers.DriverBase
   205  }
   206  
   207  func newdemoApp() drivers.Driver {
   208  	demo := &demoApp{DriverBase: &drivers.DriverBase{}}
   209  	demo.SetChild(demo)
   210  	return demo
   211  }
   212  
   213  func (demo *demoApp) GetDriverName() string {
   214  	return "demo"
   215  }
   216  
   217  func (demo *demoApp) Exec(tx *types.Transaction, index int) (receipt *types.Receipt, err error) {
   218  	return nil, queue.ErrQueueTimeout
   219  }
   220  
   221  func (demo *demoApp) Upgrade() (*types.LocalDBSet, error) {
   222  	db := demo.GetLocalDB()
   223  	db.Set([]byte("LODB-demo-a"), []byte("t1"))
   224  	db.Set([]byte("LODB-demo-b"), []byte("t2"))
   225  	var kvset types.LocalDBSet
   226  	kvset.KV = []*types.KeyValue{
   227  		{Key: []byte("LODB-demo-a"), Value: []byte("t1")},
   228  		{Key: []byte("LODB-demo-b"), Value: []byte("t2")},
   229  	}
   230  	return &kvset, nil
   231  }
   232  
   233  type demofApp struct {
   234  	*drivers.DriverBase
   235  }
   236  
   237  func newdemofApp() drivers.Driver {
   238  	demo := &demofApp{DriverBase: &drivers.DriverBase{}}
   239  	demo.SetChild(demo)
   240  	return demo
   241  }
   242  
   243  func (demo *demofApp) GetDriverName() string {
   244  	return "demof"
   245  }
   246  
   247  func (demo *demofApp) Exec(tx *types.Transaction, index int) (receipt *types.Receipt, err error) {
   248  	return nil, queue.ErrQueueTimeout
   249  }
   250  
   251  func (demo *demofApp) Upgrade() (kvset *types.LocalDBSet, err error) {
   252  	return nil, types.ErrInvalidParam
   253  }
   254  
   255  func TestExecutorErrAPIEnv(t *testing.T) {
   256  	exec, q := initEnv(types.GetDefaultCfgstring())
   257  	exec.disableLocal = true
   258  	cfg := exec.client.GetConfig()
   259  	cfg.SetMinFee(0)
   260  	Register(cfg)
   261  	execInit(cfg)
   262  
   263  	store := store.New(cfg)
   264  	store.SetQueueClient(q.Client())
   265  	defer store.Close()
   266  
   267  	var txs []*types.Transaction
   268  	genkey := util.TestPrivkeyList[0]
   269  	txs = append(txs, util.CreateTxWithExecer(cfg, genkey, "demo"))
   270  	txlist := &types.ExecTxList{
   271  		StateHash:  nil,
   272  		Height:     1,
   273  		BlockTime:  time.Now().Unix(),
   274  		Difficulty: 1,
   275  		MainHash:   nil,
   276  		MainHeight: 1,
   277  		ParentHash: nil,
   278  		Txs:        txs,
   279  	}
   280  	msg := queue.NewMessage(0, "", 1, txlist)
   281  	exec.procExecTxList(msg)
   282  	_, err := exec.client.WaitTimeout(msg, 100*time.Second)
   283  	fmt.Println(err)
   284  	assert.Equal(t, true, api.IsAPIEnvError(err))
   285  }
   286  func TestCheckTx(t *testing.T) {
   287  	exec, q := initEnv(types.ReadFile("../cmd/turingchain/turingchain.test.toml"))
   288  	cfg := exec.client.GetConfig()
   289  
   290  	store := store.New(cfg)
   291  	store.SetQueueClient(q.Client())
   292  	defer store.Close()
   293  
   294  	addr, priv := util.Genaddress()
   295  
   296  	tx := util.CreateCoinsTx(cfg, priv, addr, types.Coin)
   297  	tx.Execer = []byte("user.xxx")
   298  	tx.To = address.ExecAddress("user.xxx")
   299  	tx.Fee = 2 * types.Coin
   300  	tx.Sign(types.SECP256K1, priv)
   301  
   302  	var txs []*types.Transaction
   303  	txs = append(txs, tx)
   304  	ctx := &executorCtx{
   305  		stateHash:  nil,
   306  		height:     0,
   307  		blocktime:  time.Now().Unix(),
   308  		difficulty: 1,
   309  		mainHash:   nil,
   310  		parentHash: nil,
   311  	}
   312  	execute := newExecutor(ctx, exec, nil, txs, nil)
   313  	err := execute.execCheckTx(tx, 0)
   314  	assert.Equal(t, err, types.ErrNoBalance)
   315  }
   316  
   317  func TestExecutorUpgradeMsg(t *testing.T) {
   318  	exec, q := initEnv(types.GetDefaultCfgstring())
   319  	cfg := exec.client.GetConfig()
   320  	cfg.SetMinFee(0)
   321  	Register(cfg)
   322  	execInit(cfg)
   323  
   324  	exec.SetQueueClient(q.Client())
   325  	client := q.Client()
   326  	msg := client.NewMessage("execs", types.EventUpgrade, nil)
   327  	err := client.Send(msg, true)
   328  	assert.Nil(t, err)
   329  }
   330  
   331  func TestExecutorPluginUpgrade(t *testing.T) {
   332  	exec, q := initEnv(types.GetDefaultCfgstring())
   333  	cfg := exec.client.GetConfig()
   334  	cfg.SetMinFee(0)
   335  	Register(cfg)
   336  	execInit(cfg)
   337  
   338  	go func() {
   339  		client := q.Client()
   340  		client.Sub("blockchain")
   341  		for msg := range client.Recv() {
   342  			if msg.Ty == types.EventLocalNew {
   343  				msg.Reply(client.NewMessage("", types.EventHeader, &types.Int64{Data: 100}))
   344  			} else {
   345  				msg.Reply(client.NewMessage("", types.EventHeader, &types.Header{Height: 100}))
   346  			}
   347  		}
   348  	}()
   349  
   350  	kvset, err := exec.upgradePlugin("demo")
   351  	assert.Nil(t, err)
   352  	assert.Equal(t, 2, len(kvset.GetKV()))
   353  	kvset, err = exec.upgradePlugin("demof")
   354  	assert.NotNil(t, err)
   355  	assert.Nil(t, kvset)
   356  }