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.

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