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

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "strconv"
  6. "testing"
  7. "time"
  8. "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) []*account.PrivAccount {
  68. accounts := []*account.PrivAccount{}
  69. for i := 0; i < n; i++ {
  70. secret := []byte("mysecret" + strconv.Itoa(i))
  71. user := account.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.(account.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 := &account.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 := &account.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 := &account.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 = &account.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 *account.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 := &account.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 := &account.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 *account.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 *account.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 *account.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 *account.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 *account.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. }