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 }