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.

260 lines
7.2 KiB

  1. package test
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "encoding/binary"
  6. "math/big"
  7. "testing"
  8. "time"
  9. ethCommon "github.com/ethereum/go-ethereum/common"
  10. ethCrypto "github.com/ethereum/go-ethereum/crypto"
  11. "github.com/hermeznetwork/hermez-node/common"
  12. "github.com/hermeznetwork/hermez-node/eth"
  13. "github.com/iden3/go-iden3-crypto/babyjub"
  14. "github.com/stretchr/testify/assert"
  15. "github.com/stretchr/testify/require"
  16. )
  17. type timer struct {
  18. time int64
  19. }
  20. func (t *timer) Time() int64 {
  21. currentTime := t.time
  22. t.time++
  23. return currentTime
  24. }
  25. func TestClientInterface(t *testing.T) {
  26. var c eth.ClientInterface
  27. var timer timer
  28. clientSetup := NewClientSetupExample()
  29. client := NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
  30. c = client
  31. require.NotNil(t, c)
  32. }
  33. func TestClientEth(t *testing.T) {
  34. var timer timer
  35. clientSetup := NewClientSetupExample()
  36. c := NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
  37. blockNum, err := c.EthCurrentBlock()
  38. require.Nil(t, err)
  39. assert.Equal(t, int64(0), blockNum)
  40. block, err := c.EthBlockByNumber(context.TODO(), 0)
  41. require.Nil(t, err)
  42. assert.Equal(t, int64(0), block.EthBlockNum)
  43. assert.Equal(t, time.Unix(0, 0), block.Timestamp)
  44. assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", block.Hash.Hex())
  45. assert.Equal(t, int64(0), c.blockNum)
  46. // Mine some empty blocks
  47. c.CtlMineBlock()
  48. assert.Equal(t, int64(1), c.blockNum)
  49. c.CtlMineBlock()
  50. assert.Equal(t, int64(2), c.blockNum)
  51. block, err = c.EthBlockByNumber(context.TODO(), 2)
  52. require.Nil(t, err)
  53. assert.Equal(t, int64(2), block.EthBlockNum)
  54. assert.Equal(t, time.Unix(2, 0), block.Timestamp)
  55. // Add a token
  56. tokenAddr := ethCommon.HexToAddress("0x44021007485550008e0f9f1f7b506c7d970ad8ce")
  57. constants := eth.ERC20Consts{
  58. Name: "FooBar",
  59. Symbol: "FOO",
  60. Decimals: 4,
  61. }
  62. c.CtlAddERC20(tokenAddr, constants)
  63. c.CtlMineBlock()
  64. tokenConstants, err := c.EthERC20Consts(tokenAddr)
  65. require.Nil(t, err)
  66. assert.Equal(t, constants, *tokenConstants)
  67. }
  68. func TestClientAuction(t *testing.T) {
  69. addrWithdraw := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
  70. addrForge := ethCommon.HexToAddress("0xCfAA413eEb796f328620a3630Ae39124cabcEa92")
  71. addrForge2 := ethCommon.HexToAddress("0x1fCb4ac309428feCc61B1C8cA5823C15A5e1a800")
  72. var timer timer
  73. clientSetup := NewClientSetupExample()
  74. clientSetup.AuctionVariables.ClosedAuctionSlots = 2
  75. clientSetup.AuctionVariables.OpenAuctionSlots = 4320
  76. clientSetup.AuctionVariables.DefaultSlotSetBid = [6]*big.Int{
  77. big.NewInt(1000), big.NewInt(1100), big.NewInt(1200),
  78. big.NewInt(1300), big.NewInt(1400), big.NewInt(1500)}
  79. c := NewClient(true, &timer, &addrWithdraw, clientSetup)
  80. // Check several cases in which bid doesn't succed, and also do 2 successful bids.
  81. _, err := c.AuctionBid(0, big.NewInt(1), addrForge)
  82. assert.Equal(t, errBidClosed, err)
  83. _, err = c.AuctionBid(4322, big.NewInt(1), addrForge)
  84. assert.Equal(t, errBidNotOpen, err)
  85. // 101 % 6 = 5; defaultSlotSetBid[5] = 1500; 1500 + 10% = 1650
  86. _, err = c.AuctionBid(101, big.NewInt(1650), addrForge)
  87. assert.Equal(t, errCoordNotReg, err)
  88. _, err = c.AuctionRegisterCoordinator(addrForge, "https://foo.bar")
  89. assert.Nil(t, err)
  90. _, err = c.AuctionBid(3, big.NewInt(1), addrForge)
  91. assert.Equal(t, errBidBelowMin, err)
  92. _, err = c.AuctionBid(3, big.NewInt(1650), addrForge)
  93. assert.Nil(t, err)
  94. _, err = c.AuctionRegisterCoordinator(addrForge2, "https://foo2.bar")
  95. assert.Nil(t, err)
  96. _, err = c.AuctionBid(3, big.NewInt(16), addrForge2)
  97. assert.Equal(t, errBidBelowMin, err)
  98. // 1650 + 10% = 1815
  99. _, err = c.AuctionBid(3, big.NewInt(1815), addrForge2)
  100. assert.Nil(t, err)
  101. c.CtlMineBlock()
  102. blockNum, err := c.EthCurrentBlock()
  103. require.Nil(t, err)
  104. auctionEvents, _, err := c.AuctionEventsByBlock(blockNum)
  105. require.Nil(t, err)
  106. assert.Equal(t, 2, len(auctionEvents.NewBid))
  107. }
  108. func TestClientRollup(t *testing.T) {
  109. token1Addr := ethCommon.HexToAddress("0x6b175474e89094c44da98b954eedeac495271d0f")
  110. var timer timer
  111. clientSetup := NewClientSetupExample()
  112. c := NewClient(true, &timer, &ethCommon.Address{}, clientSetup)
  113. // Add a token
  114. tx, err := c.RollupAddToken(token1Addr)
  115. require.Nil(t, err)
  116. assert.NotNil(t, tx)
  117. // Add some L1UserTxs
  118. // Create Accounts
  119. const N = 16
  120. var keys [N]*keys
  121. for i := 0; i < N; i++ {
  122. keys[i] = genKeys(int64(i))
  123. l1UserTx := common.L1Tx{
  124. FromIdx: nil,
  125. FromEthAddr: keys[i].Addr,
  126. FromBJJ: keys[i].BJJPublicKey,
  127. TokenID: common.TokenID(0),
  128. LoadAmount: big.NewInt(10 + int64(i)),
  129. }
  130. c.CtlAddL1TxUser(&l1UserTx)
  131. }
  132. c.CtlMineBlock()
  133. blockNum, err := c.EthCurrentBlock()
  134. require.Nil(t, err)
  135. rollupEvents, _, err := c.RollupEventsByBlock(blockNum)
  136. require.Nil(t, err)
  137. assert.Equal(t, N, len(rollupEvents.L1UserTx))
  138. assert.Equal(t, 1, len(rollupEvents.AddToken))
  139. // Forge a batch
  140. c.CtlAddBatch(&eth.RollupForgeBatchArgs{
  141. NewLastIdx: 0,
  142. NewStRoot: big.NewInt(1),
  143. NewExitRoot: big.NewInt(100),
  144. L1CoordinatorTxs: []*common.L1Tx{},
  145. L2Txs: []*common.L2Tx{},
  146. FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
  147. VerifierIdx: 0,
  148. L1Batch: true,
  149. })
  150. c.CtlMineBlock()
  151. blockNumA, err := c.EthCurrentBlock()
  152. require.Nil(t, err)
  153. rollupEvents, hashA, err := c.RollupEventsByBlock(blockNumA)
  154. require.Nil(t, err)
  155. assert.Equal(t, 0, len(rollupEvents.L1UserTx))
  156. assert.Equal(t, 0, len(rollupEvents.AddToken))
  157. assert.Equal(t, 1, len(rollupEvents.ForgeBatch))
  158. // Simulate reorg discarding last mined block
  159. c.CtlRollback()
  160. c.CtlMineBlock()
  161. blockNumB, err := c.EthCurrentBlock()
  162. require.Nil(t, err)
  163. rollupEvents, hashB, err := c.RollupEventsByBlock(blockNumA)
  164. require.Nil(t, err)
  165. assert.Equal(t, 0, len(rollupEvents.L1UserTx))
  166. assert.Equal(t, 0, len(rollupEvents.AddToken))
  167. assert.Equal(t, 0, len(rollupEvents.ForgeBatch))
  168. assert.Equal(t, blockNumA, blockNumB)
  169. assert.NotEqual(t, hashA, hashB)
  170. // Forge again
  171. rollupForgeBatchArgs0 := &eth.RollupForgeBatchArgs{
  172. NewLastIdx: 0,
  173. NewStRoot: big.NewInt(1),
  174. NewExitRoot: big.NewInt(100),
  175. L1CoordinatorTxs: []*common.L1Tx{},
  176. L2Txs: []*common.L2Tx{},
  177. FeeIdxCoordinator: make([]common.Idx, eth.FeeIdxCoordinatorLen),
  178. VerifierIdx: 0,
  179. L1Batch: true,
  180. }
  181. c.CtlAddBatch(rollupForgeBatchArgs0)
  182. c.CtlMineBlock()
  183. // Retrieve ForgeBatchArguments starting from the events
  184. blockNum, err = c.EthCurrentBlock()
  185. require.Nil(t, err)
  186. rollupEvents, _, err = c.RollupEventsByBlock(blockNum)
  187. require.Nil(t, err)
  188. rollupForgeBatchArgs1, err := c.RollupForgeBatchArgs(rollupEvents.ForgeBatch[0].EthTxHash)
  189. require.Nil(t, err)
  190. assert.Equal(t, rollupForgeBatchArgs0, rollupForgeBatchArgs1)
  191. }
  192. type keys struct {
  193. BJJSecretKey *babyjub.PrivateKey
  194. BJJPublicKey *babyjub.PublicKey
  195. Addr ethCommon.Address
  196. }
  197. func genKeys(i int64) *keys {
  198. i++ // i = 0 doesn't work for the ecdsa key generation
  199. var sk babyjub.PrivateKey
  200. binary.LittleEndian.PutUint64(sk[:], uint64(i))
  201. // eth address
  202. var key ecdsa.PrivateKey
  203. key.D = big.NewInt(i) // only for testing
  204. key.PublicKey.X, key.PublicKey.Y = ethCrypto.S256().ScalarBaseMult(key.D.Bytes())
  205. key.Curve = ethCrypto.S256()
  206. addr := ethCrypto.PubkeyToAddress(key.PublicKey)
  207. return &keys{
  208. BJJSecretKey: &sk,
  209. BJJPublicKey: sk.Public(),
  210. Addr: addr,
  211. }
  212. }