You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1260 lines
44 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strconv"
  6. "testing"
  7. "time"
  8. acm "github.com/tendermint/tendermint/account"
  9. . "github.com/tendermint/tendermint/common"
  10. dbm "github.com/tendermint/tendermint/db"
  11. "github.com/tendermint/tendermint/events"
  12. ptypes "github.com/tendermint/tendermint/permission/types"
  13. "github.com/tendermint/tendermint/types"
  14. "github.com/tendermint/tendermint/vm"
  15. )
  16. /*
  17. Permission Tests:
  18. - SendTx:
  19. x - 1 input, no perm, call perm, create perm
  20. x - 1 input, perm
  21. x - 2 inputs, one with perm one without
  22. - CallTx, CALL
  23. x - 1 input, no perm, send perm, create perm
  24. x - 1 input, perm
  25. x - contract runs call but doesn't have call perm
  26. x - contract runs call and has call perm
  27. x - contract runs call (with perm), runs contract that runs call (without perm)
  28. x - contract runs call (with perm), runs contract that runs call (with perm)
  29. - CallTx for Create, CREATE
  30. x - 1 input, no perm, send perm, call perm
  31. x - 1 input, perm
  32. x - contract runs create but doesn't have create perm
  33. x - contract runs create but has perm
  34. x - contract runs call with empty address (has call and create perm)
  35. - NameTx
  36. - no perm, send perm, call perm
  37. - with perm
  38. - BondTx
  39. x - 1 input, no perm
  40. x - 1 input, perm
  41. x - 1 bonder with perm, input without send or bond
  42. x - 1 bonder with perm, input with send
  43. x - 1 bonder with perm, input with bond
  44. x - 2 inputs, one with perm one without
  45. - SendTx for new account
  46. x - 1 input, 1 unknown ouput, input with send, not create (fail)
  47. x - 1 input, 1 unknown ouput, input with send and create (pass)
  48. x - 2 inputs, 1 unknown ouput, both inputs with send, one with create, one without (fail)
  49. x - 2 inputs, 1 known output, 1 unknown ouput, one input with create, one without (fail)
  50. x - 2 inputs, 1 unknown ouput, both inputs with send, both inputs with create (pass )
  51. x - 2 inputs, 1 known output, 1 unknown ouput, both inputs with create, (pass)
  52. - CALL for new account
  53. x - unknown output, without create (fail)
  54. x - unknown output, with create (pass)
  55. - SNative (CallTx, CALL):
  56. - for each of CallTx, Call
  57. x - call each snative without permission, fails
  58. x - call each snative with permission, pass
  59. - list:
  60. x - base: has,set,unset
  61. x - globals: set
  62. x - roles: has, add, rm
  63. */
  64. // keys
  65. var user = makeUsers(10)
  66. var chainID = "testchain"
  67. func makeUsers(n int) []*acm.PrivAccount {
  68. accounts := []*acm.PrivAccount{}
  69. for i := 0; i < n; i++ {
  70. secret := []byte("mysecret" + strconv.Itoa(i))
  71. user := acm.GenPrivAccountFromSecret(secret)
  72. accounts = append(accounts, user)
  73. }
  74. return accounts
  75. }
  76. var (
  77. PermsAllFalse = ptypes.ZeroAccountPermissions
  78. )
  79. func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) GenesisDoc {
  80. genAccounts := []GenesisAccount{}
  81. for _, u := range user[:5] {
  82. accountPermCopy := accountPerm // Create new instance for custom overridability.
  83. genAccounts = append(genAccounts, GenesisAccount{
  84. Address: u.Address,
  85. Amount: 1000000,
  86. Permissions: &accountPermCopy,
  87. })
  88. }
  89. return GenesisDoc{
  90. GenesisTime: time.Now(),
  91. ChainID: chainID,
  92. Params: &GenesisParams{
  93. GlobalPermissions: &globalPerm,
  94. },
  95. Accounts: genAccounts,
  96. Validators: []GenesisValidator{
  97. GenesisValidator{
  98. PubKey: user[0].PubKey.(acm.PubKeyEd25519),
  99. Amount: 10,
  100. UnbondTo: []BasicAccount{
  101. BasicAccount{
  102. Address: user[0].Address,
  103. },
  104. },
  105. },
  106. },
  107. }
  108. }
  109. func TestSendFails(t *testing.T) {
  110. stateDB := dbm.GetDB("state")
  111. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  112. genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
  113. genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
  114. genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
  115. st := MakeGenesisState(stateDB, &genDoc)
  116. blockCache := NewBlockCache(st)
  117. //-------------------
  118. // send txs
  119. // simple send tx should fail
  120. tx := types.NewSendTx()
  121. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  122. t.Fatal(err)
  123. }
  124. tx.AddOutput(user[1].Address, 5)
  125. tx.SignInput(chainID, 0, user[0])
  126. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  127. t.Fatal("Expected error")
  128. } else {
  129. fmt.Println(err)
  130. }
  131. // simple send tx with call perm should fail
  132. tx = types.NewSendTx()
  133. if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil {
  134. t.Fatal(err)
  135. }
  136. tx.AddOutput(user[4].Address, 5)
  137. tx.SignInput(chainID, 0, user[2])
  138. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  139. t.Fatal("Expected error")
  140. } else {
  141. fmt.Println(err)
  142. }
  143. // simple send tx with create perm should fail
  144. tx = types.NewSendTx()
  145. if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil {
  146. t.Fatal(err)
  147. }
  148. tx.AddOutput(user[4].Address, 5)
  149. tx.SignInput(chainID, 0, user[3])
  150. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  151. t.Fatal("Expected error")
  152. } else {
  153. fmt.Println(err)
  154. }
  155. // simple send tx to unknown account without create_account perm should fail
  156. acc := blockCache.GetAccount(user[3].Address)
  157. acc.Permissions.Base.Set(ptypes.Send, true)
  158. blockCache.UpdateAccount(acc)
  159. tx = types.NewSendTx()
  160. if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil {
  161. t.Fatal(err)
  162. }
  163. tx.AddOutput(user[6].Address, 5)
  164. tx.SignInput(chainID, 0, user[3])
  165. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  166. t.Fatal("Expected error")
  167. } else {
  168. fmt.Println(err)
  169. }
  170. }
  171. func TestName(t *testing.T) {
  172. stateDB := dbm.GetDB("state")
  173. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  174. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true)
  175. genDoc.Accounts[1].Permissions.Base.Set(ptypes.Name, true)
  176. st := MakeGenesisState(stateDB, &genDoc)
  177. blockCache := NewBlockCache(st)
  178. //-------------------
  179. // name txs
  180. // simple name tx without perm should fail
  181. tx, err := types.NewNameTx(st, user[0].PubKey, "somename", "somedata", 10000, 100)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. tx.Sign(chainID, user[0])
  186. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  187. t.Fatal("Expected error")
  188. } else {
  189. fmt.Println(err)
  190. }
  191. // simple name tx with perm should pass
  192. tx, err = types.NewNameTx(st, user[1].PubKey, "somename", "somedata", 10000, 100)
  193. if err != nil {
  194. t.Fatal(err)
  195. }
  196. tx.Sign(chainID, user[1])
  197. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  198. t.Fatal(err)
  199. }
  200. }
  201. func TestCallFails(t *testing.T) {
  202. stateDB := dbm.GetDB("state")
  203. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  204. genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true)
  205. genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true)
  206. genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true)
  207. st := MakeGenesisState(stateDB, &genDoc)
  208. blockCache := NewBlockCache(st)
  209. //-------------------
  210. // call txs
  211. // simple call tx should fail
  212. tx, _ := types.NewCallTx(blockCache, user[0].PubKey, user[4].Address, nil, 100, 100, 100)
  213. tx.Sign(chainID, user[0])
  214. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  215. t.Fatal("Expected error")
  216. } else {
  217. fmt.Println(err)
  218. }
  219. // simple call tx with send permission should fail
  220. tx, _ = types.NewCallTx(blockCache, user[1].PubKey, user[4].Address, nil, 100, 100, 100)
  221. tx.Sign(chainID, user[1])
  222. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  223. t.Fatal("Expected error")
  224. } else {
  225. fmt.Println(err)
  226. }
  227. // simple call tx with create permission should fail
  228. tx, _ = types.NewCallTx(blockCache, user[3].PubKey, user[4].Address, nil, 100, 100, 100)
  229. tx.Sign(chainID, user[3])
  230. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  231. t.Fatal("Expected error")
  232. } else {
  233. fmt.Println(err)
  234. }
  235. //-------------------
  236. // create txs
  237. // simple call create tx should fail
  238. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, nil, nil, 100, 100, 100)
  239. tx.Sign(chainID, user[0])
  240. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  241. t.Fatal("Expected error")
  242. } else {
  243. fmt.Println(err)
  244. }
  245. // simple call create tx with send perm should fail
  246. tx, _ = types.NewCallTx(blockCache, user[1].PubKey, nil, nil, 100, 100, 100)
  247. tx.Sign(chainID, user[1])
  248. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  249. t.Fatal("Expected error")
  250. } else {
  251. fmt.Println(err)
  252. }
  253. // simple call create tx with call perm should fail
  254. tx, _ = types.NewCallTx(blockCache, user[2].PubKey, nil, nil, 100, 100, 100)
  255. tx.Sign(chainID, user[2])
  256. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  257. t.Fatal("Expected error")
  258. } else {
  259. fmt.Println(err)
  260. }
  261. }
  262. func TestSendPermission(t *testing.T) {
  263. stateDB := dbm.GetDB("state")
  264. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  265. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
  266. st := MakeGenesisState(stateDB, &genDoc)
  267. blockCache := NewBlockCache(st)
  268. // A single input, having the permission, should succeed
  269. tx := types.NewSendTx()
  270. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  271. t.Fatal(err)
  272. }
  273. tx.AddOutput(user[1].Address, 5)
  274. tx.SignInput(chainID, 0, user[0])
  275. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  276. t.Fatal("Transaction failed", err)
  277. }
  278. // Two inputs, one with permission, one without, should fail
  279. tx = types.NewSendTx()
  280. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  281. t.Fatal(err)
  282. }
  283. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  284. t.Fatal(err)
  285. }
  286. tx.AddOutput(user[2].Address, 10)
  287. tx.SignInput(chainID, 0, user[0])
  288. tx.SignInput(chainID, 1, user[1])
  289. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  290. t.Fatal("Expected error")
  291. } else {
  292. fmt.Println(err)
  293. }
  294. }
  295. func TestCallPermission(t *testing.T) {
  296. stateDB := dbm.GetDB("state")
  297. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  298. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
  299. st := MakeGenesisState(stateDB, &genDoc)
  300. blockCache := NewBlockCache(st)
  301. //------------------------------
  302. // call to simple contract
  303. fmt.Println("##### SIMPLE CONTRACT")
  304. // create simple contract
  305. simpleContractAddr := NewContractAddress(user[0].Address, 100)
  306. simpleAcc := &acm.Account{
  307. Address: simpleContractAddr,
  308. Balance: 0,
  309. Code: []byte{0x60},
  310. Sequence: 0,
  311. StorageRoot: Zero256.Bytes(),
  312. Permissions: ptypes.ZeroAccountPermissions,
  313. }
  314. st.UpdateAccount(simpleAcc)
  315. // A single input, having the permission, should succeed
  316. tx, _ := types.NewCallTx(blockCache, user[0].PubKey, simpleContractAddr, nil, 100, 100, 100)
  317. tx.Sign(chainID, user[0])
  318. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  319. t.Fatal("Transaction failed", err)
  320. }
  321. //----------------------------------------------------------
  322. // call to contract that calls simple contract - without perm
  323. fmt.Println("##### CALL TO SIMPLE CONTRACT (FAIL)")
  324. // create contract that calls the simple contract
  325. contractCode := callContractCode(simpleContractAddr)
  326. caller1ContractAddr := NewContractAddress(user[0].Address, 101)
  327. caller1Acc := &acm.Account{
  328. Address: caller1ContractAddr,
  329. Balance: 0,
  330. Code: contractCode,
  331. Sequence: 0,
  332. StorageRoot: Zero256.Bytes(),
  333. Permissions: ptypes.ZeroAccountPermissions,
  334. }
  335. blockCache.UpdateAccount(caller1Acc)
  336. // A single input, having the permission, but the contract doesn't have permission
  337. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100)
  338. tx.Sign(chainID, user[0])
  339. // we need to subscribe to the Receive event to detect the exception
  340. _, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(caller1ContractAddr)) //
  341. if exception == "" {
  342. t.Fatal("Expected exception")
  343. }
  344. //----------------------------------------------------------
  345. // call to contract that calls simple contract - with perm
  346. fmt.Println("##### CALL TO SIMPLE CONTRACT (PASS)")
  347. // A single input, having the permission, and the contract has permission
  348. caller1Acc.Permissions.Base.Set(ptypes.Call, true)
  349. blockCache.UpdateAccount(caller1Acc)
  350. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100)
  351. tx.Sign(chainID, user[0])
  352. // we need to subscribe to the Receive event to detect the exception
  353. _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(caller1ContractAddr)) //
  354. if exception != "" {
  355. t.Fatal("Unexpected exception:", exception)
  356. }
  357. //----------------------------------------------------------
  358. // call to contract that calls contract that calls simple contract - without perm
  359. // caller1Contract calls simpleContract. caller2Contract calls caller1Contract.
  360. // caller1Contract does not have call perms, but caller2Contract does.
  361. fmt.Println("##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (FAIL)")
  362. contractCode2 := callContractCode(caller1ContractAddr)
  363. caller2ContractAddr := NewContractAddress(user[0].Address, 102)
  364. caller2Acc := &acm.Account{
  365. Address: caller2ContractAddr,
  366. Balance: 1000,
  367. Code: contractCode2,
  368. Sequence: 0,
  369. StorageRoot: Zero256.Bytes(),
  370. Permissions: ptypes.ZeroAccountPermissions,
  371. }
  372. caller1Acc.Permissions.Base.Set(ptypes.Call, false)
  373. caller2Acc.Permissions.Base.Set(ptypes.Call, true)
  374. blockCache.UpdateAccount(caller1Acc)
  375. blockCache.UpdateAccount(caller2Acc)
  376. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller2ContractAddr, nil, 100, 10000, 100)
  377. tx.Sign(chainID, user[0])
  378. // we need to subscribe to the Receive event to detect the exception
  379. _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(caller1ContractAddr)) //
  380. if exception == "" {
  381. t.Fatal("Expected exception")
  382. }
  383. //----------------------------------------------------------
  384. // call to contract that calls contract that calls simple contract - without perm
  385. // caller1Contract calls simpleContract. caller2Contract calls caller1Contract.
  386. // both caller1 and caller2 have permission
  387. fmt.Println("##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)")
  388. caller1Acc.Permissions.Base.Set(ptypes.Call, true)
  389. blockCache.UpdateAccount(caller1Acc)
  390. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, caller2ContractAddr, nil, 100, 10000, 100)
  391. tx.Sign(chainID, user[0])
  392. // we need to subscribe to the Receive event to detect the exception
  393. _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(caller1ContractAddr)) //
  394. if exception != "" {
  395. t.Fatal("Unexpected exception", exception)
  396. }
  397. }
  398. func TestCreatePermission(t *testing.T) {
  399. stateDB := dbm.GetDB("state")
  400. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  401. genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateContract, true) // give the 0 account permission
  402. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
  403. st := MakeGenesisState(stateDB, &genDoc)
  404. blockCache := NewBlockCache(st)
  405. //------------------------------
  406. // create a simple contract
  407. fmt.Println("##### CREATE SIMPLE CONTRACT")
  408. contractCode := []byte{0x60}
  409. createCode := wrapContractForCreate(contractCode)
  410. // A single input, having the permission, should succeed
  411. tx, _ := types.NewCallTx(blockCache, user[0].PubKey, nil, createCode, 100, 100, 100)
  412. tx.Sign(chainID, user[0])
  413. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  414. t.Fatal("Transaction failed", err)
  415. }
  416. // ensure the contract is there
  417. contractAddr := NewContractAddress(tx.Input.Address, tx.Input.Sequence)
  418. contractAcc := blockCache.GetAccount(contractAddr)
  419. if contractAcc == nil {
  420. t.Fatalf("failed to create contract %X", contractAddr)
  421. }
  422. if bytes.Compare(contractAcc.Code, contractCode) != 0 {
  423. t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, contractCode)
  424. }
  425. //------------------------------
  426. // create contract that uses the CREATE op
  427. fmt.Println("##### CREATE FACTORY")
  428. contractCode = []byte{0x60}
  429. createCode = wrapContractForCreate(contractCode)
  430. factoryCode := createContractCode()
  431. createFactoryCode := wrapContractForCreate(factoryCode)
  432. // A single input, having the permission, should succeed
  433. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, nil, createFactoryCode, 100, 100, 100)
  434. tx.Sign(chainID, user[0])
  435. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  436. t.Fatal("Transaction failed", err)
  437. }
  438. // ensure the contract is there
  439. contractAddr = NewContractAddress(tx.Input.Address, tx.Input.Sequence)
  440. contractAcc = blockCache.GetAccount(contractAddr)
  441. if contractAcc == nil {
  442. t.Fatalf("failed to create contract %X", contractAddr)
  443. }
  444. if bytes.Compare(contractAcc.Code, factoryCode) != 0 {
  445. t.Fatalf("contract does not have correct code. Got %X, expected %X", contractAcc.Code, factoryCode)
  446. }
  447. //------------------------------
  448. // call the contract (should FAIL)
  449. fmt.Println("###### CALL THE FACTORY (FAIL)")
  450. // A single input, having the permission, should succeed
  451. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 100, 100)
  452. tx.Sign(chainID, user[0])
  453. // we need to subscribe to the Receive event to detect the exception
  454. _, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(contractAddr)) //
  455. if exception == "" {
  456. t.Fatal("expected exception")
  457. }
  458. //------------------------------
  459. // call the contract (should PASS)
  460. fmt.Println("###### CALL THE FACTORY (PASS)")
  461. contractAcc.Permissions.Base.Set(ptypes.CreateContract, true)
  462. blockCache.UpdateAccount(contractAcc)
  463. // A single input, having the permission, should succeed
  464. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 100, 100)
  465. tx.Sign(chainID, user[0])
  466. // we need to subscribe to the Receive event to detect the exception
  467. _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(contractAddr)) //
  468. if exception != "" {
  469. t.Fatal("unexpected exception", exception)
  470. }
  471. //--------------------------------
  472. fmt.Println("##### CALL to empty address")
  473. zeroAddr := LeftPadBytes([]byte{}, 20)
  474. code := callContractCode(zeroAddr)
  475. contractAddr = NewContractAddress(user[0].Address, 110)
  476. contractAcc = &acm.Account{
  477. Address: contractAddr,
  478. Balance: 1000,
  479. Code: code,
  480. Sequence: 0,
  481. StorageRoot: Zero256.Bytes(),
  482. Permissions: ptypes.ZeroAccountPermissions,
  483. }
  484. contractAcc.Permissions.Base.Set(ptypes.Call, true)
  485. contractAcc.Permissions.Base.Set(ptypes.CreateContract, true)
  486. blockCache.UpdateAccount(contractAcc)
  487. // this should call the 0 address but not create ...
  488. tx, _ = types.NewCallTx(blockCache, user[0].PubKey, contractAddr, createCode, 100, 10000, 100)
  489. tx.Sign(chainID, user[0])
  490. // we need to subscribe to the Receive event to detect the exception
  491. _, exception = execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(zeroAddr)) //
  492. if exception != "" {
  493. t.Fatal("unexpected exception", exception)
  494. }
  495. zeroAcc := blockCache.GetAccount(zeroAddr)
  496. if len(zeroAcc.Code) != 0 {
  497. t.Fatal("the zero account was given code from a CALL!")
  498. }
  499. }
  500. func TestBondPermission(t *testing.T) {
  501. stateDB := dbm.GetDB("state")
  502. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  503. st := MakeGenesisState(stateDB, &genDoc)
  504. blockCache := NewBlockCache(st)
  505. var bondAcc *acm.Account
  506. //------------------------------
  507. // one bonder without permission should fail
  508. tx, _ := types.NewBondTx(user[1].PubKey)
  509. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  510. t.Fatal(err)
  511. }
  512. tx.AddOutput(user[1].Address, 5)
  513. tx.SignInput(chainID, 0, user[1])
  514. tx.SignBond(chainID, user[1])
  515. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  516. t.Fatal("Expected error")
  517. } else {
  518. fmt.Println(err)
  519. }
  520. //------------------------------
  521. // one bonder with permission should pass
  522. bondAcc = blockCache.GetAccount(user[1].Address)
  523. bondAcc.Permissions.Base.Set(ptypes.Bond, true)
  524. blockCache.UpdateAccount(bondAcc)
  525. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  526. t.Fatal("Unexpected error", err)
  527. }
  528. // reset state (we can only bond with an account once ..)
  529. genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  530. st = MakeGenesisState(stateDB, &genDoc)
  531. blockCache = NewBlockCache(st)
  532. bondAcc = blockCache.GetAccount(user[1].Address)
  533. bondAcc.Permissions.Base.Set(ptypes.Bond, true)
  534. blockCache.UpdateAccount(bondAcc)
  535. //------------------------------
  536. // one bonder with permission and an input without send should fail
  537. tx, _ = types.NewBondTx(user[1].PubKey)
  538. if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil {
  539. t.Fatal(err)
  540. }
  541. tx.AddOutput(user[1].Address, 5)
  542. tx.SignInput(chainID, 0, user[2])
  543. tx.SignBond(chainID, user[1])
  544. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  545. t.Fatal("Expected error")
  546. } else {
  547. fmt.Println(err)
  548. }
  549. // reset state (we can only bond with an account once ..)
  550. genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  551. st = MakeGenesisState(stateDB, &genDoc)
  552. blockCache = NewBlockCache(st)
  553. bondAcc = blockCache.GetAccount(user[1].Address)
  554. bondAcc.Permissions.Base.Set(ptypes.Bond, true)
  555. blockCache.UpdateAccount(bondAcc)
  556. //------------------------------
  557. // one bonder with permission and an input with send should pass
  558. sendAcc := blockCache.GetAccount(user[2].Address)
  559. sendAcc.Permissions.Base.Set(ptypes.Send, true)
  560. blockCache.UpdateAccount(sendAcc)
  561. tx, _ = types.NewBondTx(user[1].PubKey)
  562. if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil {
  563. t.Fatal(err)
  564. }
  565. tx.AddOutput(user[1].Address, 5)
  566. tx.SignInput(chainID, 0, user[2])
  567. tx.SignBond(chainID, user[1])
  568. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  569. t.Fatal("Unexpected error", err)
  570. }
  571. // reset state (we can only bond with an account once ..)
  572. genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  573. st = MakeGenesisState(stateDB, &genDoc)
  574. blockCache = NewBlockCache(st)
  575. bondAcc = blockCache.GetAccount(user[1].Address)
  576. bondAcc.Permissions.Base.Set(ptypes.Bond, true)
  577. blockCache.UpdateAccount(bondAcc)
  578. //------------------------------
  579. // one bonder with permission and an input with bond should pass
  580. sendAcc.Permissions.Base.Set(ptypes.Bond, true)
  581. blockCache.UpdateAccount(sendAcc)
  582. tx, _ = types.NewBondTx(user[1].PubKey)
  583. if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil {
  584. t.Fatal(err)
  585. }
  586. tx.AddOutput(user[1].Address, 5)
  587. tx.SignInput(chainID, 0, user[2])
  588. tx.SignBond(chainID, user[1])
  589. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  590. t.Fatal("Unexpected error", err)
  591. }
  592. // reset state (we can only bond with an account once ..)
  593. genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  594. st = MakeGenesisState(stateDB, &genDoc)
  595. blockCache = NewBlockCache(st)
  596. bondAcc = blockCache.GetAccount(user[1].Address)
  597. bondAcc.Permissions.Base.Set(ptypes.Bond, true)
  598. blockCache.UpdateAccount(bondAcc)
  599. //------------------------------
  600. // one bonder with permission and an input from that bonder and an input without send or bond should fail
  601. tx, _ = types.NewBondTx(user[1].PubKey)
  602. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  603. t.Fatal(err)
  604. }
  605. if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil {
  606. t.Fatal(err)
  607. }
  608. tx.AddOutput(user[1].Address, 5)
  609. tx.SignInput(chainID, 0, user[1])
  610. tx.SignInput(chainID, 1, user[2])
  611. tx.SignBond(chainID, user[1])
  612. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  613. t.Fatal("Expected error")
  614. }
  615. }
  616. func TestCreateAccountPermission(t *testing.T) {
  617. stateDB := dbm.GetDB("state")
  618. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  619. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
  620. genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission
  621. genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission
  622. st := MakeGenesisState(stateDB, &genDoc)
  623. blockCache := NewBlockCache(st)
  624. //----------------------------------------------------------
  625. // SendTx to unknown account
  626. // A single input, having the permission, should succeed
  627. tx := types.NewSendTx()
  628. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  629. t.Fatal(err)
  630. }
  631. tx.AddOutput(user[6].Address, 5)
  632. tx.SignInput(chainID, 0, user[0])
  633. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  634. t.Fatal("Transaction failed", err)
  635. }
  636. // Two inputs, both with send, one with create, one without, should fail
  637. tx = types.NewSendTx()
  638. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  639. t.Fatal(err)
  640. }
  641. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  642. t.Fatal(err)
  643. }
  644. tx.AddOutput(user[7].Address, 10)
  645. tx.SignInput(chainID, 0, user[0])
  646. tx.SignInput(chainID, 1, user[1])
  647. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  648. t.Fatal("Expected error")
  649. } else {
  650. fmt.Println(err)
  651. }
  652. // Two inputs, both with send, one with create, one without, two ouputs (one known, one unknown) should fail
  653. tx = types.NewSendTx()
  654. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  655. t.Fatal(err)
  656. }
  657. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  658. t.Fatal(err)
  659. }
  660. tx.AddOutput(user[7].Address, 4)
  661. tx.AddOutput(user[4].Address, 6)
  662. tx.SignInput(chainID, 0, user[0])
  663. tx.SignInput(chainID, 1, user[1])
  664. if err := ExecTx(blockCache, tx, true, nil); err == nil {
  665. t.Fatal("Expected error")
  666. } else {
  667. fmt.Println(err)
  668. }
  669. // Two inputs, both with send, both with create, should pass
  670. acc := blockCache.GetAccount(user[1].Address)
  671. acc.Permissions.Base.Set(ptypes.CreateAccount, true)
  672. blockCache.UpdateAccount(acc)
  673. tx = types.NewSendTx()
  674. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  675. t.Fatal(err)
  676. }
  677. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  678. t.Fatal(err)
  679. }
  680. tx.AddOutput(user[7].Address, 10)
  681. tx.SignInput(chainID, 0, user[0])
  682. tx.SignInput(chainID, 1, user[1])
  683. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  684. t.Fatal("Unexpected error", err)
  685. }
  686. // Two inputs, both with send, both with create, two outputs (one known, one unknown) should pass
  687. tx = types.NewSendTx()
  688. if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil {
  689. t.Fatal(err)
  690. }
  691. if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil {
  692. t.Fatal(err)
  693. }
  694. tx.AddOutput(user[7].Address, 7)
  695. tx.AddOutput(user[4].Address, 3)
  696. tx.SignInput(chainID, 0, user[0])
  697. tx.SignInput(chainID, 1, user[1])
  698. if err := ExecTx(blockCache, tx, true, nil); err != nil {
  699. t.Fatal("Unexpected error", err)
  700. }
  701. //----------------------------------------------------------
  702. // CALL to unknown account
  703. acc = blockCache.GetAccount(user[0].Address)
  704. acc.Permissions.Base.Set(ptypes.Call, true)
  705. blockCache.UpdateAccount(acc)
  706. // call to contract that calls unknown account - without create_account perm
  707. // create contract that calls the simple contract
  708. contractCode := callContractCode(user[9].Address)
  709. caller1ContractAddr := NewContractAddress(user[4].Address, 101)
  710. caller1Acc := &acm.Account{
  711. Address: caller1ContractAddr,
  712. Balance: 0,
  713. Code: contractCode,
  714. Sequence: 0,
  715. StorageRoot: Zero256.Bytes(),
  716. Permissions: ptypes.ZeroAccountPermissions,
  717. }
  718. blockCache.UpdateAccount(caller1Acc)
  719. // A single input, having the permission, but the contract doesn't have permission
  720. txCall, _ := types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100)
  721. txCall.Sign(chainID, user[0])
  722. // we need to subscribe to the Receive event to detect the exception
  723. _, exception := execTxWaitEvent(t, blockCache, txCall, types.EventStringAccReceive(caller1ContractAddr)) //
  724. if exception == "" {
  725. t.Fatal("Expected exception")
  726. }
  727. // NOTE: for a contract to be able to CreateAccount, it must be able to call
  728. // NOTE: for a user to be able to CreateAccount, it must be able to send!
  729. caller1Acc.Permissions.Base.Set(ptypes.CreateAccount, true)
  730. caller1Acc.Permissions.Base.Set(ptypes.Call, true)
  731. blockCache.UpdateAccount(caller1Acc)
  732. // A single input, having the permission, but the contract doesn't have permission
  733. txCall, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100)
  734. txCall.Sign(chainID, user[0])
  735. // we need to subscribe to the Receive event to detect the exception
  736. _, exception = execTxWaitEvent(t, blockCache, txCall, types.EventStringAccReceive(caller1ContractAddr)) //
  737. if exception != "" {
  738. t.Fatal("Unexpected exception", exception)
  739. }
  740. }
  741. func TestSNativeCALL(t *testing.T) {
  742. stateDB := dbm.GetDB("state")
  743. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  744. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
  745. genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
  746. genDoc.Accounts[3].Permissions.AddRole("bumble")
  747. genDoc.Accounts[3].Permissions.AddRole("bee")
  748. st := MakeGenesisState(stateDB, &genDoc)
  749. blockCache := NewBlockCache(st)
  750. //----------------------------------------------------------
  751. // Test CALL to SNative contracts
  752. // make the main contract once
  753. doug := &acm.Account{
  754. Address: ptypes.DougAddress,
  755. Balance: 0,
  756. Code: nil,
  757. Sequence: 0,
  758. StorageRoot: Zero256.Bytes(),
  759. Permissions: ptypes.ZeroAccountPermissions,
  760. }
  761. doug.Permissions.Base.Set(ptypes.Call, true)
  762. blockCache.UpdateAccount(doug)
  763. fmt.Println("#### hasBasePerm")
  764. // hasBasePerm
  765. snativeAddress, data := snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
  766. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  767. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  768. // return value should be true or false as a 32 byte array...
  769. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  770. return fmt.Errorf("Expected 1. Got %X", ret)
  771. }
  772. return nil
  773. })
  774. fmt.Println("#### setBasePerm")
  775. // setBasePerm
  776. snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.Bond, false)
  777. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  778. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  779. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
  780. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  781. // return value should be true or false as a 32 byte array...
  782. if !IsZeros(ret) {
  783. return fmt.Errorf("Expected 0. Got %X", ret)
  784. }
  785. return nil
  786. })
  787. snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.CreateContract, true)
  788. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  789. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  790. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  791. // return value should be true or false as a 32 byte array...
  792. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  793. return fmt.Errorf("Expected 1. Got %X", ret)
  794. }
  795. return nil
  796. })
  797. fmt.Println("#### unsetBasePerm")
  798. // unsetBasePerm
  799. snativeAddress, data = snativePermTestInput("unsetBasePerm", user[3], ptypes.CreateContract, false)
  800. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  801. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  802. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  803. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  804. if !IsZeros(ret) {
  805. return fmt.Errorf("Expected 0. Got %X", ret)
  806. }
  807. return nil
  808. })
  809. fmt.Println("#### setGlobalPerm")
  810. // setGlobalPerm
  811. snativeAddress, data = snativePermTestInput("setGlobalPerm", user[3], ptypes.CreateContract, true)
  812. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  813. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  814. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  815. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  816. // return value should be true or false as a 32 byte array...
  817. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  818. return fmt.Errorf("Expected 1. Got %X", ret)
  819. }
  820. return nil
  821. })
  822. // clearBasePerm
  823. // TODO
  824. fmt.Println("#### hasRole")
  825. // hasRole
  826. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "bumble")
  827. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  828. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  829. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  830. return fmt.Errorf("Expected 1. Got %X", ret)
  831. }
  832. return nil
  833. })
  834. fmt.Println("#### addRole")
  835. // addRole
  836. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  837. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  838. if !IsZeros(ret) {
  839. return fmt.Errorf("Expected 0. Got %X", ret)
  840. }
  841. return nil
  842. })
  843. snativeAddress, data = snativeRoleTestInput("addRole", user[3], "chuck")
  844. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  845. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  846. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  847. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  848. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  849. return fmt.Errorf("Expected 1. Got %X", ret)
  850. }
  851. return nil
  852. })
  853. fmt.Println("#### rmRole")
  854. // rmRole
  855. snativeAddress, data = snativeRoleTestInput("rmRole", user[3], "chuck")
  856. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  857. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  858. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  859. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  860. if !IsZeros(ret) {
  861. return fmt.Errorf("Expected 0. Got %X", ret)
  862. }
  863. return nil
  864. })
  865. }
  866. func TestSNativeCallTx(t *testing.T) {
  867. stateDB := dbm.GetDB("state")
  868. genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse)
  869. genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission
  870. genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with
  871. genDoc.Accounts[3].Permissions.AddRole("bumble")
  872. genDoc.Accounts[3].Permissions.AddRole("bee")
  873. st := MakeGenesisState(stateDB, &genDoc)
  874. blockCache := NewBlockCache(st)
  875. //----------------------------------------------------------
  876. // Test CallTx to SNative contracts
  877. var doug *acm.Account = nil
  878. fmt.Println("#### hasBasePerm")
  879. // hasBasePerm
  880. snativeAddress, data := snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
  881. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  882. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  883. // return value should be true or false as a 32 byte array...
  884. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  885. return fmt.Errorf("Expected 1. Got %X", ret)
  886. }
  887. return nil
  888. })
  889. fmt.Println("#### setBasePerm")
  890. // setBasePerm
  891. snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.Bond, false)
  892. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  893. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  894. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.Bond, false)
  895. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  896. // return value should be true or false as a 32 byte array...
  897. if !IsZeros(ret) {
  898. return fmt.Errorf("Expected 0. Got %X", ret)
  899. }
  900. return nil
  901. })
  902. snativeAddress, data = snativePermTestInput("setBasePerm", user[3], ptypes.CreateContract, true)
  903. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  904. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  905. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  906. // return value should be true or false as a 32 byte array...
  907. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  908. return fmt.Errorf("Expected 1. Got %X", ret)
  909. }
  910. return nil
  911. })
  912. fmt.Println("#### unsetBasePerm")
  913. // unsetBasePerm
  914. snativeAddress, data = snativePermTestInput("unsetBasePerm", user[3], ptypes.CreateContract, false)
  915. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  916. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  917. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  918. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  919. if !IsZeros(ret) {
  920. return fmt.Errorf("Expected 0. Got %X", ret)
  921. }
  922. return nil
  923. })
  924. fmt.Println("#### setGlobalPerm")
  925. // setGlobalPerm
  926. snativeAddress, data = snativePermTestInput("setGlobalPerm", user[3], ptypes.CreateContract, true)
  927. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  928. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  929. snativeAddress, data = snativePermTestInput("hasBasePerm", user[3], ptypes.CreateContract, false)
  930. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  931. // return value should be true or false as a 32 byte array...
  932. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  933. return fmt.Errorf("Expected 1. Got %X", ret)
  934. }
  935. return nil
  936. })
  937. // clearBasePerm
  938. // TODO
  939. fmt.Println("#### hasRole")
  940. // hasRole
  941. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "bumble")
  942. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  943. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  944. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  945. return fmt.Errorf("Expected 1. Got %X", ret)
  946. }
  947. return nil
  948. })
  949. fmt.Println("#### addRole")
  950. // addRole
  951. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  952. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  953. if !IsZeros(ret) {
  954. return fmt.Errorf("Expected 0. Got %X", ret)
  955. }
  956. return nil
  957. })
  958. snativeAddress, data = snativeRoleTestInput("addRole", user[3], "chuck")
  959. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  960. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  961. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  962. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  963. if !IsZeros(ret[:31]) || ret[31] != byte(1) {
  964. return fmt.Errorf("Expected 1. Got %X", ret)
  965. }
  966. return nil
  967. })
  968. fmt.Println("#### rmRole")
  969. // rmRole
  970. snativeAddress, data = snativeRoleTestInput("rmRole", user[3], "chuck")
  971. testSNativeCALLExpectFail(t, blockCache, doug, snativeAddress, data)
  972. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error { return nil })
  973. snativeAddress, data = snativeRoleTestInput("hasRole", user[3], "chuck")
  974. testSNativeCALLExpectPass(t, blockCache, doug, snativeAddress, data, func(ret []byte) error {
  975. if !IsZeros(ret) {
  976. return fmt.Errorf("Expected 0. Got %X", ret)
  977. }
  978. return nil
  979. })
  980. }
  981. //-------------------------------------------------------------------------------------
  982. // helpers
  983. // run ExecTx and wait for the Receive event on given addr
  984. // returns the msg data and an error/exception
  985. func execTxWaitEvent(t *testing.T, blockCache *BlockCache, tx types.Tx, eventid string) (interface{}, string) {
  986. evsw := new(events.EventSwitch)
  987. evsw.Start()
  988. ch := make(chan interface{})
  989. evsw.AddListenerForEvent("test", eventid, func(msg interface{}) {
  990. ch <- msg
  991. })
  992. evc := events.NewEventCache(evsw)
  993. go func() {
  994. if err := ExecTx(blockCache, tx, true, evc); err != nil {
  995. ch <- err.Error()
  996. }
  997. evc.Flush()
  998. }()
  999. msg := <-ch
  1000. switch ev := msg.(type) {
  1001. case types.EventMsgCallTx:
  1002. return ev, ev.Exception
  1003. case types.EventMsgCall:
  1004. return ev, ev.Exception
  1005. case string:
  1006. return nil, ev
  1007. default:
  1008. return ev, ""
  1009. }
  1010. }
  1011. // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds
  1012. func testSNativeCALLExpectPass(t *testing.T, blockCache *BlockCache, doug *acm.Account, snativeAddress, data []byte, f func([]byte) error) {
  1013. perm := vm.RegisteredSNativePermissions[LeftPadWord256(snativeAddress)]
  1014. var addr []byte
  1015. if doug != nil {
  1016. contractCode := callContractCode(snativeAddress)
  1017. doug.Code = contractCode
  1018. doug.Permissions.Base.Set(perm, true)
  1019. blockCache.UpdateAccount(doug)
  1020. addr = doug.Address
  1021. } else {
  1022. acc := blockCache.GetAccount(user[0].Address)
  1023. acc.Permissions.Base.Set(perm, true)
  1024. blockCache.UpdateAccount(acc)
  1025. addr = snativeAddress
  1026. }
  1027. tx, _ := types.NewCallTx(blockCache, user[0].PubKey, addr, data, 100, 10000, 100)
  1028. tx.Sign(chainID, user[0])
  1029. ev, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(snativeAddress)) //
  1030. if exception != "" {
  1031. t.Fatal("Unexpected exception", exception)
  1032. }
  1033. evv := ev.(types.EventMsgCall)
  1034. ret := evv.Return
  1035. if err := f(ret); err != nil {
  1036. t.Fatal(err)
  1037. }
  1038. }
  1039. // assumes the contract has not been given the permission. calls the it, it calls the snative, expects to fail
  1040. func testSNativeCALLExpectFail(t *testing.T, blockCache *BlockCache, doug *acm.Account, snativeAddress, data []byte) {
  1041. var addr []byte
  1042. if doug != nil {
  1043. contractCode := callContractCode(snativeAddress)
  1044. doug.Code = contractCode
  1045. blockCache.UpdateAccount(doug)
  1046. addr = doug.Address
  1047. } else {
  1048. addr = snativeAddress
  1049. }
  1050. tx, _ := types.NewCallTx(blockCache, user[0].PubKey, addr, data, 100, 10000, 100)
  1051. tx.Sign(chainID, user[0])
  1052. fmt.Println("subscribing to", types.EventStringAccReceive(snativeAddress))
  1053. _, exception := execTxWaitEvent(t, blockCache, tx, types.EventStringAccReceive(snativeAddress))
  1054. if exception == "" {
  1055. t.Fatal("Expected exception")
  1056. }
  1057. }
  1058. func boolToWord256(v bool) Word256 {
  1059. var vint byte
  1060. if v {
  1061. vint = 0x1
  1062. } else {
  1063. vint = 0x0
  1064. }
  1065. return LeftPadWord256([]byte{vint})
  1066. }
  1067. func snativePermTestInput(name string, user *acm.PrivAccount, perm ptypes.PermFlag, val bool) (addr []byte, data []byte) {
  1068. addr = LeftPadWord256([]byte(name)).Postfix(20)
  1069. switch name {
  1070. case "hasBasePerm", "unsetBasePerm":
  1071. data = LeftPadBytes(user.Address, 32)
  1072. data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
  1073. case "setBasePerm":
  1074. data = LeftPadBytes(user.Address, 32)
  1075. data = append(data, Uint64ToWord256(uint64(perm)).Bytes()...)
  1076. data = append(data, boolToWord256(val).Bytes()...)
  1077. case "setGlobalPerm":
  1078. data = Uint64ToWord256(uint64(perm)).Bytes()
  1079. data = append(data, boolToWord256(val).Bytes()...)
  1080. case "clearBasePerm":
  1081. }
  1082. return
  1083. }
  1084. func snativeRoleTestInput(name string, user *acm.PrivAccount, role string) (addr []byte, data []byte) {
  1085. addr = LeftPadWord256([]byte(name)).Postfix(20)
  1086. data = LeftPadBytes(user.Address, 32)
  1087. data = append(data, LeftPadBytes([]byte(role), 32)...)
  1088. return
  1089. }
  1090. // convenience function for contract that calls a given address
  1091. func callContractCode(contractAddr []byte) []byte {
  1092. // calldatacopy into mem and use as input to call
  1093. memOff, inputOff := byte(0x0), byte(0x0)
  1094. contractCode := []byte{0x36, 0x60, inputOff, 0x60, memOff, 0x37}
  1095. gas1, gas2 := byte(0x1), byte(0x1)
  1096. value := byte(0x1)
  1097. inOff := byte(0x0)
  1098. retOff, retSize := byte(0x0), byte(0x20)
  1099. // this is the code we want to run (call a contract and return)
  1100. contractCode = append(contractCode, []byte{0x60, retSize, 0x60, retOff, 0x36, 0x60, inOff, 0x60, value, 0x73}...)
  1101. contractCode = append(contractCode, contractAddr...)
  1102. contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, 0x60, 0x0, 0xf3}...)
  1103. return contractCode
  1104. }
  1105. // convenience function for contract that is a factory for the code that comes as call data
  1106. func createContractCode() []byte {
  1107. // TODO: gas ...
  1108. // calldatacopy the calldatasize
  1109. memOff, inputOff := byte(0x0), byte(0x0)
  1110. contractCode := []byte{0x60, memOff, 0x60, inputOff, 0x36, 0x37}
  1111. // create
  1112. value := byte(0x1)
  1113. contractCode = append(contractCode, []byte{0x60, value, 0x36, 0x60, memOff, 0xf0}...)
  1114. return contractCode
  1115. }
  1116. // wrap a contract in create code
  1117. func wrapContractForCreate(contractCode []byte) []byte {
  1118. // the is the code we need to return the contractCode when the contract is initialized
  1119. lenCode := len(contractCode)
  1120. // push code to the stack
  1121. code := append([]byte{0x7f}, RightPadWord256(contractCode).Bytes()...)
  1122. // store it in memory
  1123. code = append(code, []byte{0x60, 0x0, 0x52}...)
  1124. // return whats in memory
  1125. code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...)
  1126. // return init code, contract code, expected return
  1127. return code
  1128. }