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.

242 lines
7.1 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. package debugapi
  2. import (
  3. "crypto/ecdsa"
  4. "fmt"
  5. "io/ioutil"
  6. "math/big"
  7. "net/http"
  8. "os"
  9. "strconv"
  10. "sync"
  11. "testing"
  12. "github.com/dghubble/sling"
  13. ethCommon "github.com/ethereum/go-ethereum/common"
  14. ethCrypto "github.com/ethereum/go-ethereum/crypto"
  15. "github.com/hermeznetwork/hermez-node/common"
  16. dbUtils "github.com/hermeznetwork/hermez-node/db"
  17. "github.com/hermeznetwork/hermez-node/db/historydb"
  18. "github.com/hermeznetwork/hermez-node/db/statedb"
  19. "github.com/hermeznetwork/hermez-node/test"
  20. "github.com/hermeznetwork/hermez-node/test/til"
  21. "github.com/hermeznetwork/hermez-node/txprocessor"
  22. "github.com/iden3/go-iden3-crypto/babyjub"
  23. "github.com/stretchr/testify/assert"
  24. "github.com/stretchr/testify/require"
  25. "golang.org/x/net/context"
  26. )
  27. func newAccount(t *testing.T, i int) *common.Account {
  28. var sk babyjub.PrivateKey
  29. copy(sk[:], []byte(strconv.Itoa(i))) // only for testing
  30. pk := sk.Public()
  31. var key ecdsa.PrivateKey
  32. key.D = big.NewInt(int64(i + 1)) // only for testing
  33. key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
  34. key.Curve = ethCrypto.S256()
  35. address := ethCrypto.PubkeyToAddress(key.PublicKey)
  36. return &common.Account{
  37. Idx: common.Idx(256 + i),
  38. TokenID: common.TokenID(i),
  39. Nonce: common.Nonce(i),
  40. Balance: big.NewInt(1000),
  41. BJJ: pk.Compress(),
  42. EthAddr: address,
  43. }
  44. }
  45. func TestDebugAPI(t *testing.T) {
  46. dir, err := ioutil.TempDir("", "tmpdb")
  47. require.Nil(t, err)
  48. sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeSynchronizer, NLevels: 32})
  49. require.Nil(t, err)
  50. err = sdb.MakeCheckpoint() // Make a checkpoint to increment the batchNum
  51. require.Nil(t, err)
  52. addr := "localhost:12345"
  53. // We won't test the sync/stats endpoint, so we can se the Syncrhonizer to nil
  54. debugAPI := NewDebugAPI(addr, nil, sdb, nil)
  55. ctx, cancel := context.WithCancel(context.Background())
  56. wg := sync.WaitGroup{}
  57. wg.Add(1)
  58. go func() {
  59. err := debugAPI.Run(ctx)
  60. require.Nil(t, err)
  61. wg.Done()
  62. }()
  63. var accounts []common.Account
  64. for i := 0; i < 16; i++ {
  65. account := newAccount(t, i)
  66. accounts = append(accounts, *account)
  67. _, err = sdb.CreateAccount(account.Idx, account)
  68. require.Nil(t, err)
  69. }
  70. // Make a checkpoint (batchNum 2) to make the accounts available in Last
  71. err = sdb.MakeCheckpoint()
  72. require.Nil(t, err)
  73. url := fmt.Sprintf("http://%v/debug/", addr)
  74. var batchNum common.BatchNum
  75. req, err := sling.New().Get(url).Path("sdb/batchnum").ReceiveSuccess(&batchNum)
  76. require.Equal(t, http.StatusOK, req.StatusCode)
  77. require.Nil(t, err)
  78. assert.Equal(t, common.BatchNum(2), batchNum)
  79. var mtroot *big.Int
  80. req, err = sling.New().Get(url).Path("sdb/mtroot").ReceiveSuccess(&mtroot)
  81. require.Equal(t, http.StatusOK, req.StatusCode)
  82. require.Nil(t, err)
  83. // Testing against a hardcoded value obtained by running the test and
  84. // printing the value previously.
  85. assert.Equal(t, "21765339739823365993496282904432398015268846626944509989242908567129545640185",
  86. mtroot.String())
  87. var accountAPI common.Account
  88. req, err = sling.New().Get(url).
  89. Path(fmt.Sprintf("sdb/accounts/%v", accounts[0].Idx)).
  90. ReceiveSuccess(&accountAPI)
  91. require.Equal(t, http.StatusOK, req.StatusCode)
  92. require.Nil(t, err)
  93. assert.Equal(t, accounts[0], accountAPI)
  94. var accountsAPI []common.Account
  95. req, err = sling.New().Get(url).Path("sdb/accounts").ReceiveSuccess(&accountsAPI)
  96. require.Equal(t, http.StatusOK, req.StatusCode)
  97. require.Nil(t, err)
  98. assert.Equal(t, accounts, accountsAPI)
  99. cancel()
  100. wg.Wait()
  101. }
  102. func TestDebugAPITokenBalances(t *testing.T) {
  103. dir, err := ioutil.TempDir("", "tmpdb")
  104. require.Nil(t, err)
  105. sdb, err := statedb.NewStateDB(statedb.Config{Path: dir, Keep: 128, Type: statedb.TypeSynchronizer, NLevels: 32})
  106. require.Nil(t, err)
  107. // Init History DB
  108. pass := os.Getenv("POSTGRES_PASS")
  109. db, err := dbUtils.InitSQLDB(5432, "localhost", "hermez", pass, "hermez")
  110. require.NoError(t, err)
  111. historyDB := historydb.NewHistoryDB(db, nil)
  112. // Clear DB
  113. test.WipeDB(historyDB.DB())
  114. set := `
  115. Type: Blockchain
  116. AddToken(1)
  117. AddToken(2)
  118. AddToken(3)
  119. CreateAccountDeposit(1) A: 1000
  120. CreateAccountDeposit(2) A: 2000
  121. CreateAccountDeposit(1) B: 100
  122. CreateAccountDeposit(2) B: 200
  123. CreateAccountDeposit(2) C: 400
  124. > batchL1 // forge L1UserTxs{nil}, freeze defined L1UserTxs{5}
  125. > batchL1 // forge defined L1UserTxs{5}, freeze L1UserTxs{nil}
  126. > block // blockNum=2
  127. `
  128. chainID := uint16(0)
  129. tc := til.NewContext(chainID, common.RollupConstMaxL1UserTx)
  130. tilCfgExtra := til.ConfigExtra{
  131. BootCoordAddr: ethCommon.HexToAddress("0xE39fEc6224708f0772D2A74fd3f9055A90E0A9f2"),
  132. CoordUser: "A",
  133. }
  134. blocks, err := tc.GenerateBlocks(set)
  135. require.NoError(t, err)
  136. err = tc.FillBlocksExtra(blocks, &tilCfgExtra)
  137. require.NoError(t, err)
  138. tc.FillBlocksL1UserTxsBatchNum(blocks)
  139. err = tc.FillBlocksForgedL1UserTxs(blocks)
  140. require.NoError(t, err)
  141. tpc := txprocessor.Config{
  142. NLevels: 32,
  143. MaxTx: 100,
  144. ChainID: chainID,
  145. MaxFeeTx: common.RollupConstMaxFeeIdxCoordinator,
  146. MaxL1Tx: common.RollupConstMaxL1Tx,
  147. }
  148. tp := txprocessor.NewTxProcessor(sdb, tpc)
  149. for _, block := range blocks {
  150. require.NoError(t, historyDB.AddBlockSCData(&block))
  151. for _, batch := range block.Rollup.Batches {
  152. _, err := tp.ProcessTxs(batch.Batch.FeeIdxsCoordinator,
  153. batch.L1UserTxs, batch.L1CoordinatorTxs, []common.PoolL2Tx{})
  154. require.NoError(t, err)
  155. }
  156. }
  157. addr := "localhost:12345"
  158. // We won't test the sync/stats endpoint, so we can se the Syncrhonizer to nil
  159. debugAPI := NewDebugAPI(addr, historyDB, sdb, nil)
  160. ctx, cancel := context.WithCancel(context.Background())
  161. wg := sync.WaitGroup{}
  162. wg.Add(1)
  163. go func() {
  164. err := debugAPI.Run(ctx)
  165. require.Nil(t, err)
  166. wg.Done()
  167. }()
  168. var accounts []common.Account
  169. for i := 0; i < 16; i++ {
  170. account := newAccount(t, i)
  171. accounts = append(accounts, *account)
  172. _, err = sdb.CreateAccount(account.Idx, account)
  173. require.Nil(t, err)
  174. }
  175. // Make a checkpoint (batchNum 2) to make the accounts available in Last
  176. err = sdb.MakeCheckpoint()
  177. require.Nil(t, err)
  178. url := fmt.Sprintf("http://%v/debug/", addr)
  179. var batchNum common.BatchNum
  180. req, err := sling.New().Get(url).Path("sdb/batchnum").ReceiveSuccess(&batchNum)
  181. require.Equal(t, http.StatusOK, req.StatusCode)
  182. require.Nil(t, err)
  183. assert.Equal(t, common.BatchNum(2), batchNum)
  184. var mtroot *big.Int
  185. req, err = sling.New().Get(url).Path("sdb/mtroot").ReceiveSuccess(&mtroot)
  186. require.Equal(t, http.StatusOK, req.StatusCode)
  187. require.Nil(t, err)
  188. // Testing against a hardcoded value obtained by running the test and
  189. // printing the value previously.
  190. assert.Equal(t, "21765339739823365993496282904432398015268846626944509989242908567129545640185",
  191. mtroot.String())
  192. var accountAPI common.Account
  193. req, err = sling.New().Get(url).
  194. Path(fmt.Sprintf("sdb/accounts/%v", accounts[0].Idx)).
  195. ReceiveSuccess(&accountAPI)
  196. require.Equal(t, http.StatusOK, req.StatusCode)
  197. require.Nil(t, err)
  198. assert.Equal(t, accounts[0], accountAPI)
  199. var accountsAPI []common.Account
  200. req, err = sling.New().Get(url).Path("sdb/accounts").ReceiveSuccess(&accountsAPI)
  201. require.Equal(t, http.StatusOK, req.StatusCode)
  202. require.Nil(t, err)
  203. assert.Equal(t, accounts, accountsAPI)
  204. cancel()
  205. wg.Wait()
  206. }