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.

739 lines
29 KiB

  1. package eth
  2. import (
  3. "context"
  4. "fmt"
  5. "math/big"
  6. "strings"
  7. "github.com/ethereum/go-ethereum"
  8. "github.com/ethereum/go-ethereum/accounts/abi"
  9. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  10. ethCommon "github.com/ethereum/go-ethereum/common"
  11. "github.com/ethereum/go-ethereum/core/types"
  12. "github.com/ethereum/go-ethereum/crypto"
  13. "github.com/ethereum/go-ethereum/ethclient"
  14. "github.com/hermeznetwork/hermez-node/common"
  15. ERC777 "github.com/hermeznetwork/hermez-node/eth/contracts/erc777"
  16. Hermez "github.com/hermeznetwork/hermez-node/eth/contracts/hermez"
  17. "github.com/hermeznetwork/hermez-node/log"
  18. "github.com/iden3/go-iden3-crypto/babyjub"
  19. "golang.org/x/crypto/sha3"
  20. )
  21. const (
  22. // RollupConstFeeIdxCoordinatorLen is the number of tokens the coordinator can use
  23. // to collect fees (determines the number of tokens that the
  24. // coordinator can collect fees from). This value is determined by the
  25. // circuit.
  26. RollupConstFeeIdxCoordinatorLen = 64
  27. // RollupConstReservedIDx First 256 indexes reserved, first user index will be the 256
  28. RollupConstReservedIDx = 255
  29. // RollupConstExitIDx IDX 1 is reserved for exits
  30. RollupConstExitIDx = 1
  31. // RollupConstLimitLoadAmount Max load amount allowed (loadAmount: L1 --> L2)
  32. RollupConstLimitLoadAmount = (1 << 128)
  33. // RollupConstLimitL2TransferAmount Max amount allowed (amount L2 --> L2)
  34. RollupConstLimitL2TransferAmount = (1 << 192)
  35. // RollupConstLimitTokens Max number of tokens allowed to be registered inside the rollup
  36. RollupConstLimitTokens = (1 << 32)
  37. // RollupConstL1CoordinatorTotalBytes [4 bytes] token + [32 bytes] babyjub + [65 bytes] compressedSignature
  38. RollupConstL1CoordinatorTotalBytes = 101
  39. // RollupConstL1UserTotalBytes [20 bytes] fromEthAddr + [32 bytes] fromBjj-compressed + [6 bytes] fromIdx +
  40. // [2 bytes] loadAmountFloat16 + [2 bytes] amountFloat16 + [4 bytes] tokenId + [6 bytes] toIdx
  41. RollupConstL1UserTotalBytes = 72
  42. // RollupConstMaxL1UserTx Maximum L1-user transactions allowed to be queued in a batch
  43. RollupConstMaxL1UserTx = 128
  44. // RollupConstMaxL1Tx Maximum L1 transactions allowed to be queued in a batch
  45. RollupConstMaxL1Tx = 256
  46. // RollupConstInputSHAConstantBytes [6 bytes] lastIdx + [6 bytes] newLastIdx + [32 bytes] stateRoot + [32 bytes] newStRoot + [32 bytes] newExitRoot +
  47. // [_MAX_L1_TX * _L1_USER_TOTALBYTES bytes] l1TxsData + totalL2TxsDataLength + feeIdxCoordinatorLength + [2 bytes] chainID =
  48. // 18542 bytes + totalL2TxsDataLength + feeIdxCoordinatorLength
  49. RollupConstInputSHAConstantBytes = 18542
  50. // RollupConstNumBuckets Number of buckets
  51. RollupConstNumBuckets = 5
  52. // RollupConstMaxWithdrawalDelay max withdrawal delay in seconds
  53. RollupConstMaxWithdrawalDelay = 2 * 7 * 24 * 60 * 60
  54. // RollupConstExchangeMultiplier exchange multiplier
  55. RollupConstExchangeMultiplier = 1e14
  56. // LenVerifiers number of Rollup Smart Contract Verifiers
  57. LenVerifiers = 1
  58. )
  59. var (
  60. // RollupConstEthAddressInternalOnly This ethereum address is used internally for rollup accounts that don't have ethereum address, only Babyjubjub
  61. // This non-ethereum accounts can be created by the coordinator and allow users to have a rollup
  62. // account without needing an ethereum address
  63. RollupConstEthAddressInternalOnly = ethCommon.HexToAddress("0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF")
  64. // RollupConstRfield Modulus zkSNARK
  65. RollupConstRfield, _ = new(big.Int).SetString(
  66. "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
  67. // RollupConstERC1820 ERC1820Registry address
  68. RollupConstERC1820 = ethCommon.HexToAddress("0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24")
  69. // ERC777 tokens signatures
  70. // RollupConstRecipientInterfaceHash ERC777 recipient interface hash
  71. RollupConstRecipientInterfaceHash = crypto.Keccak256([]byte("ERC777TokensRecipient"))
  72. // RollupConstPerformL1UserTxSignature the signature of the function that can be called thru an ERC777 `send`
  73. RollupConstPerformL1UserTxSignature = crypto.Keccak256([]byte("addL1Transaction(uint256,uint48,uint16,uint16,uint32,uint48)"))
  74. // RollupConstAddTokenSignature the signature of the function that can be called thru an ERC777 `send`
  75. RollupConstAddTokenSignature = crypto.Keccak256([]byte("addToken(address)"))
  76. // RollupConstSendSignature ERC777 Signature
  77. RollupConstSendSignature = crypto.Keccak256([]byte("send(address,uint256,bytes)"))
  78. // RollupConstERC777Granularity ERC777 Signature
  79. RollupConstERC777Granularity = crypto.Keccak256([]byte("granularity()"))
  80. // RollupConstWithdrawalDelayerDeposit This constant are used to deposit tokens from ERC77 tokens into withdrawal delayer
  81. RollupConstWithdrawalDelayerDeposit = crypto.Keccak256([]byte("deposit(address,address,uint192)"))
  82. // ERC20 signature
  83. // RollupConstTransferSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
  84. RollupConstTransferSignature = crypto.Keccak256([]byte("transfer(address,uint256)"))
  85. // RollupConstTransferFromSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
  86. RollupConstTransferFromSignature = crypto.Keccak256([]byte("transferFrom(address,address,uint256)"))
  87. // RollupConstApproveSignature This constant is used in the _safeTransfer internal method in order to safe GAS.
  88. RollupConstApproveSignature = crypto.Keccak256([]byte("approve(address,uint256)"))
  89. // RollupConstERC20Signature ERC20 decimals signature
  90. RollupConstERC20Signature = crypto.Keccak256([]byte("decimals()"))
  91. )
  92. // RollupConstants are the constants of the Rollup Smart Contract
  93. /* type RollupConstants struct {
  94. // Maxim Deposit allowed
  95. MaxAmountDeposit *big.Int
  96. MaxAmountL2 *big.Int
  97. MaxTokens int64
  98. // maximum L1 transactions allowed to be queued for a batch
  99. MaxL1Tx int
  100. // maximum L1 user transactions allowed to be queued for a batch
  101. MaxL1UserTx int
  102. Rfield *big.Int
  103. L1CoordinatorBytes int
  104. L1UserBytes int
  105. L2Bytes int
  106. MaxTxVerifiers []int
  107. TokenHEZ ethCommon.Address
  108. // Only test
  109. GovernanceAddress ethCommon.Address
  110. // Only test
  111. SafetyBot ethCommon.Address
  112. // Only test
  113. ConsensusContract ethCommon.Address
  114. // Only test
  115. WithdrawalContract ethCommon.Address
  116. ReservedIDx uint32
  117. LastIDx uint32
  118. ExitIDx uint32
  119. NoLimitToken int
  120. NumBuckets int
  121. MaxWDelay int64
  122. }*/
  123. // RollupPublicConstants are the constants of the Rollup Smart Contract
  124. type RollupPublicConstants struct {
  125. AbsoluteMaxL1L2BatchTimeout int64
  126. TokenHEZ ethCommon.Address
  127. Verifiers []RollupVerifierStruct
  128. HermezAuctionContract ethCommon.Address
  129. HermezGovernanceDAOAddress ethCommon.Address
  130. SafetyAddress ethCommon.Address
  131. WithdrawDelayerContract ethCommon.Address
  132. }
  133. // RollupVariables are the variables of the Rollup Smart Contract
  134. type RollupVariables struct {
  135. FeeAddToken *big.Int
  136. ForgeL1L2BatchTimeout int64
  137. WithdrawalDelay uint64
  138. }
  139. // QueueStruct is the queue of L1Txs for a batch
  140. //nolint:structcheck
  141. type QueueStruct struct {
  142. L1TxQueue []common.L1Tx
  143. TotalL1TxFee *big.Int
  144. }
  145. // NewQueueStruct creates a new clear QueueStruct.
  146. func NewQueueStruct() *QueueStruct {
  147. return &QueueStruct{
  148. L1TxQueue: make([]common.L1Tx, 0),
  149. TotalL1TxFee: big.NewInt(0),
  150. }
  151. }
  152. // RollupVerifierStruct is the information about verifiers of the Rollup Smart Contract
  153. type RollupVerifierStruct struct {
  154. MaxTx int64
  155. NLevels int64
  156. }
  157. // RollupState represents the state of the Rollup in the Smart Contract
  158. //nolint:structcheck,unused
  159. type RollupState struct {
  160. StateRoot *big.Int
  161. ExitRoots []*big.Int
  162. ExitNullifierMap map[[256 / 8]byte]bool
  163. TokenList []ethCommon.Address
  164. TokenMap map[ethCommon.Address]bool
  165. MapL1TxQueue map[int64]*QueueStruct
  166. LastL1L2Batch int64
  167. CurrentToForgeL1TxsNum int64
  168. LastToForgeL1TxsNum int64
  169. CurrentIdx int64
  170. }
  171. // RollupEventL1UserTx is an event of the Rollup Smart Contract
  172. type RollupEventL1UserTx struct {
  173. ToForgeL1TxsNum int64 // QueueIndex *big.Int
  174. Position int // TransactionIndex *big.Int
  175. L1Tx common.L1Tx
  176. }
  177. // RollupEventL1UserTxAux is an event of the Rollup Smart Contract
  178. type RollupEventL1UserTxAux struct {
  179. ToForgeL1TxsNum uint64 // QueueIndex *big.Int
  180. Position uint8 // TransactionIndex *big.Int
  181. L1Tx []byte
  182. }
  183. // RollupEventAddToken is an event of the Rollup Smart Contract
  184. type RollupEventAddToken struct {
  185. Address ethCommon.Address
  186. TokenID uint32
  187. }
  188. // RollupEventForgeBatch is an event of the Rollup Smart Contract
  189. type RollupEventForgeBatch struct {
  190. BatchNum int64
  191. EthTxHash ethCommon.Hash
  192. }
  193. // RollupEventUpdateForgeL1L2BatchTimeout is an event of the Rollup Smart Contract
  194. type RollupEventUpdateForgeL1L2BatchTimeout struct {
  195. ForgeL1L2BatchTimeout uint8
  196. }
  197. // RollupEventUpdateFeeAddToken is an event of the Rollup Smart Contract
  198. type RollupEventUpdateFeeAddToken struct {
  199. FeeAddToken *big.Int
  200. }
  201. // RollupEventWithdrawEvent is an event of the Rollup Smart Contract
  202. type RollupEventWithdrawEvent struct {
  203. Idx uint64
  204. NumExitRoot uint64
  205. InstantWithdraw bool
  206. }
  207. // RollupEvents is the list of events in a block of the Rollup Smart Contract
  208. type RollupEvents struct { //nolint:structcheck
  209. L1UserTx []RollupEventL1UserTx
  210. AddToken []RollupEventAddToken
  211. ForgeBatch []RollupEventForgeBatch
  212. UpdateForgeL1L2BatchTimeout []RollupEventUpdateForgeL1L2BatchTimeout
  213. UpdateFeeAddToken []RollupEventUpdateFeeAddToken
  214. WithdrawEvent []RollupEventWithdrawEvent
  215. }
  216. // NewRollupEvents creates an empty RollupEvents with the slices initialized.
  217. func NewRollupEvents() RollupEvents {
  218. return RollupEvents{
  219. L1UserTx: make([]RollupEventL1UserTx, 0),
  220. AddToken: make([]RollupEventAddToken, 0),
  221. ForgeBatch: make([]RollupEventForgeBatch, 0),
  222. UpdateForgeL1L2BatchTimeout: make([]RollupEventUpdateForgeL1L2BatchTimeout, 0),
  223. UpdateFeeAddToken: make([]RollupEventUpdateFeeAddToken, 0),
  224. WithdrawEvent: make([]RollupEventWithdrawEvent, 0),
  225. }
  226. }
  227. // RollupForgeBatchArgs are the arguments to the ForgeBatch function in the Rollup Smart Contract
  228. //nolint:structcheck,unused
  229. type RollupForgeBatchArgs struct {
  230. NewLastIdx int64
  231. NewStRoot *big.Int
  232. NewExitRoot *big.Int
  233. L1CoordinatorTxs []*common.L1Tx
  234. L1CoordinatorTxsAuths [][]byte // Authorization for accountCreations for each L1CoordinatorTx
  235. L2TxsData []*common.L2Tx
  236. FeeIdxCoordinator []common.Idx
  237. // Circuit selector
  238. VerifierIdx uint8
  239. L1Batch bool
  240. ProofA [2]*big.Int
  241. ProofB [2][2]*big.Int
  242. ProofC [2]*big.Int
  243. }
  244. // RollupForgeBatchArgsAux are the arguments to the ForgeBatch function in the Rollup Smart Contract
  245. //nolint:structcheck,unused
  246. type RollupForgeBatchArgsAux struct {
  247. NewLastIdx *big.Int
  248. NewStRoot *big.Int
  249. NewExitRoot *big.Int
  250. EncodedL1CoordinatorTx []byte
  251. L2TxsData []byte
  252. FeeIdxCoordinator []byte
  253. // Circuit selector
  254. VerifierIdx uint8
  255. L1Batch bool
  256. ProofA [2]*big.Int
  257. ProofB [2][2]*big.Int
  258. ProofC [2]*big.Int
  259. }
  260. // RollupInterface is the inteface to to Rollup Smart Contract
  261. type RollupInterface interface {
  262. //
  263. // Smart Contract Methods
  264. //
  265. // Public Functions
  266. RollupForgeBatch(*RollupForgeBatchArgs) (*types.Transaction, error)
  267. RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int) (*types.Transaction, error)
  268. RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey,
  269. numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error)
  270. RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error)
  271. RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error)
  272. RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey,
  273. loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error)
  274. RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16,
  275. tokenID int64, toIdx int64) (*types.Transaction, error)
  276. RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error)
  277. RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte,
  278. babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error)
  279. RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16,
  280. tokenID int64) (*types.Transaction, error)
  281. RollupGetCurrentTokens() (*big.Int, error)
  282. // RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error)
  283. // RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error)
  284. // RollupGetQueue(queue int64) ([]byte, error)
  285. // Governance Public Functions
  286. RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error)
  287. RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error)
  288. //
  289. // Smart Contract Status
  290. //
  291. RollupConstants() (*RollupPublicConstants, error)
  292. RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error)
  293. RollupForgeBatchArgs(ethCommon.Hash) (*RollupForgeBatchArgs, error)
  294. }
  295. //
  296. // Implementation
  297. //
  298. // RollupClient is the implementation of the interface to the Rollup Smart Contract in ethereum.
  299. type RollupClient struct {
  300. client *EthereumClient
  301. address ethCommon.Address
  302. tokenHEZAddress ethCommon.Address
  303. gasLimit uint64
  304. contractAbi abi.ABI
  305. }
  306. // NewRollupClient creates a new RollupClient
  307. func NewRollupClient(client *EthereumClient, address ethCommon.Address, tokenHEZAddress ethCommon.Address) (*RollupClient, error) {
  308. contractAbi, err := abi.JSON(strings.NewReader(string(Hermez.HermezABI)))
  309. if err != nil {
  310. return nil, err
  311. }
  312. return &RollupClient{
  313. client: client,
  314. address: address,
  315. tokenHEZAddress: tokenHEZAddress,
  316. gasLimit: 1000000, //nolint:gomnd
  317. contractAbi: contractAbi,
  318. }, nil
  319. }
  320. // RollupForgeBatch is the interface to call the smart contract function
  321. func (c *RollupClient) RollupForgeBatch(args *RollupForgeBatchArgs) (*types.Transaction, error) {
  322. var tx *types.Transaction
  323. var err error
  324. if tx, err = c.client.CallAuth(
  325. c.gasLimit,
  326. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  327. hermez, err := Hermez.NewHermez(c.address, ec)
  328. if err != nil {
  329. return nil, err
  330. }
  331. rollupConst, err := c.RollupConstants()
  332. if err != nil {
  333. return nil, err
  334. }
  335. nLevels := rollupConst.Verifiers[args.VerifierIdx].NLevels
  336. lenBytes := nLevels / 8 //nolint:gomnd
  337. newLastIdx := big.NewInt(int64(args.NewLastIdx))
  338. var l1CoordinatorBytes []byte
  339. for i := 0; i < len(args.L1CoordinatorTxs); i++ {
  340. l1 := args.L1CoordinatorTxs[i]
  341. bytesl1, err := l1.BytesCoordinatorTx(args.L1CoordinatorTxsAuths[i])
  342. if err != nil {
  343. return nil, err
  344. }
  345. l1CoordinatorBytes = append(l1CoordinatorBytes, bytesl1[:]...)
  346. }
  347. var l2DataBytes []byte
  348. for i := 0; i < len(args.L2TxsData); i++ {
  349. l2 := args.L2TxsData[i]
  350. bytesl2, err := l2.Bytes(int(nLevels))
  351. if err != nil {
  352. return nil, err
  353. }
  354. l2DataBytes = append(l2DataBytes, bytesl2[:]...)
  355. }
  356. var feeIdxCoordinator []byte
  357. for i := 0; i < len(args.FeeIdxCoordinator); i++ {
  358. feeIdx := args.FeeIdxCoordinator[i]
  359. bytesFeeIdx, err := feeIdx.Bytes()
  360. if err != nil {
  361. return nil, err
  362. }
  363. feeIdxCoordinator = append(feeIdxCoordinator, bytesFeeIdx[len(bytesFeeIdx)-int(lenBytes):]...)
  364. }
  365. return hermez.ForgeBatch(auth, newLastIdx, args.NewStRoot, args.NewExitRoot, l1CoordinatorBytes, l2DataBytes, feeIdxCoordinator, args.VerifierIdx, args.L1Batch, args.ProofA, args.ProofB, args.ProofC)
  366. },
  367. ); err != nil {
  368. return nil, fmt.Errorf("Failed forge batch: %w", err)
  369. }
  370. return tx, nil
  371. }
  372. // RollupAddToken is the interface to call the smart contract function.
  373. // `feeAddToken` is the amount of HEZ tokens that will be paid to add the
  374. // token. `feeAddToken` must match the public value of the smart contract.
  375. func (c *RollupClient) RollupAddToken(tokenAddress ethCommon.Address, feeAddToken *big.Int) (*types.Transaction, error) {
  376. var tx *types.Transaction
  377. var err error
  378. if tx, err = c.client.CallAuth(
  379. c.gasLimit,
  380. func(ec *ethclient.Client, auth *bind.TransactOpts) (*types.Transaction, error) {
  381. tokens, err := ERC777.NewERC777(c.tokenHEZAddress, ec)
  382. if err != nil {
  383. return nil, err
  384. }
  385. addTokenFnSignature := []byte("addToken(address)")
  386. hash := sha3.NewLegacyKeccak256()
  387. _, err = hash.Write(addTokenFnSignature)
  388. if err != nil {
  389. return nil, err
  390. }
  391. methodID := hash.Sum(nil)[:4]
  392. var data []byte
  393. data = append(data, methodID...)
  394. paddedAddress := ethCommon.LeftPadBytes(tokenAddress.Bytes(), 32)
  395. data = append(data, paddedAddress[:]...)
  396. return tokens.Send(auth, c.address, feeAddToken, data)
  397. },
  398. ); err != nil {
  399. return nil, fmt.Errorf("Failed add Token %w", err)
  400. }
  401. return tx, nil
  402. }
  403. // RollupWithdrawSNARK is the interface to call the smart contract function
  404. // func (c *RollupClient) RollupWithdrawSNARK() (*types.Transaction, error) { // TODO (Not defined in Hermez.sol)
  405. // return nil, errTODO
  406. // }
  407. // RollupWithdraw is the interface to call the smart contract function
  408. func (c *RollupClient) RollupWithdraw(tokenID int64, balance *big.Int, babyPubKey *babyjub.PublicKey, numExitRoot int64, siblings []*big.Int, idx int64, instantWithdraw bool) (*types.Transaction, error) {
  409. log.Error("TODO")
  410. return nil, errTODO
  411. }
  412. // RollupForceExit is the interface to call the smart contract function
  413. func (c *RollupClient) RollupForceExit(fromIdx int64, amountF common.Float16, tokenID int64) (*types.Transaction, error) {
  414. log.Error("TODO")
  415. return nil, errTODO
  416. }
  417. // RollupForceTransfer is the interface to call the smart contract function
  418. func (c *RollupClient) RollupForceTransfer(fromIdx int64, amountF common.Float16, tokenID, toIdx int64) (*types.Transaction, error) {
  419. log.Error("TODO")
  420. return nil, errTODO
  421. }
  422. // RollupCreateAccountDepositTransfer is the interface to call the smart contract function
  423. func (c *RollupClient) RollupCreateAccountDepositTransfer(babyPubKey babyjub.PublicKey, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
  424. log.Error("TODO")
  425. return nil, errTODO
  426. }
  427. // RollupDepositTransfer is the interface to call the smart contract function
  428. func (c *RollupClient) RollupDepositTransfer(fromIdx int64, loadAmountF, amountF common.Float16, tokenID int64, toIdx int64) (*types.Transaction, error) {
  429. log.Error("TODO")
  430. return nil, errTODO
  431. }
  432. // RollupDeposit is the interface to call the smart contract function
  433. func (c *RollupClient) RollupDeposit(fromIdx int64, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
  434. log.Error("TODO")
  435. return nil, errTODO
  436. }
  437. // RollupCreateAccountDepositFromRelayer is the interface to call the smart contract function
  438. func (c *RollupClient) RollupCreateAccountDepositFromRelayer(accountCreationAuthSig []byte, babyPubKey babyjub.PublicKey, loadAmountF common.Float16) (*types.Transaction, error) {
  439. log.Error("TODO")
  440. return nil, errTODO
  441. }
  442. // RollupCreateAccountDeposit is the interface to call the smart contract function
  443. func (c *RollupClient) RollupCreateAccountDeposit(babyPubKey babyjub.PublicKey, loadAmountF common.Float16, tokenID int64) (*types.Transaction, error) {
  444. log.Error("TODO")
  445. return nil, errTODO
  446. }
  447. // RollupGetTokenAddress is the interface to call the smart contract function
  448. /* func (c *RollupClient) RollupGetTokenAddress(tokenID int64) (*ethCommon.Address, error) {
  449. return nil, errTODO
  450. } */
  451. // RollupGetCurrentTokens is the interface to call the smart contract function
  452. func (c *RollupClient) RollupGetCurrentTokens() (*big.Int, error) {
  453. log.Error("TODO")
  454. return nil, errTODO
  455. }
  456. // RollupGetL1TxFromQueue is the interface to call the smart contract function
  457. /* func (c *RollupClient) RollupGetL1TxFromQueue(queue int64, position int64) ([]byte, error) {
  458. return nil, errTODO
  459. } */
  460. // RollupGetQueue is the interface to call the smart contract function
  461. /* func (c *RollupClient) RollupGetQueue(queue int64) ([]byte, error) {
  462. return nil, errTODO
  463. }*/
  464. // RollupUpdateForgeL1L2BatchTimeout is the interface to call the smart contract function
  465. func (c *RollupClient) RollupUpdateForgeL1L2BatchTimeout(newForgeL1Timeout int64) (*types.Transaction, error) {
  466. log.Error("TODO")
  467. return nil, errTODO
  468. }
  469. // RollupUpdateFeeAddToken is the interface to call the smart contract function
  470. func (c *RollupClient) RollupUpdateFeeAddToken(newFeeAddToken *big.Int) (*types.Transaction, error) {
  471. log.Error("TODO")
  472. return nil, errTODO
  473. }
  474. // RollupConstants returns the Constants of the Rollup Smart Contract
  475. func (c *RollupClient) RollupConstants() (*RollupPublicConstants, error) {
  476. rollupConstants := new(RollupPublicConstants)
  477. if err := c.client.Call(func(ec *ethclient.Client) error {
  478. hermez, err := Hermez.NewHermez(c.address, ec)
  479. if err != nil {
  480. return err
  481. }
  482. absoluteMaxL1L2BatchTimeout, err := hermez.ABSOLUTEMAXL1L2BATCHTIMEOUT(nil)
  483. if err != nil {
  484. return err
  485. }
  486. rollupConstants.AbsoluteMaxL1L2BatchTimeout = int64(absoluteMaxL1L2BatchTimeout)
  487. rollupConstants.TokenHEZ, err = hermez.TokenHEZ(nil)
  488. if err != nil {
  489. return err
  490. }
  491. for i := int64(0); i < int64(LenVerifiers); i++ {
  492. var newRollupVerifier RollupVerifierStruct
  493. rollupVerifier, err := hermez.RollupVerifiers(nil, big.NewInt(i))
  494. if err != nil {
  495. return err
  496. }
  497. newRollupVerifier.MaxTx = rollupVerifier.MaxTx.Int64()
  498. newRollupVerifier.NLevels = rollupVerifier.NLevels.Int64()
  499. rollupConstants.Verifiers = append(rollupConstants.Verifiers, newRollupVerifier)
  500. }
  501. rollupConstants.HermezAuctionContract, err = hermez.HermezAuctionContract(nil)
  502. if err != nil {
  503. return err
  504. }
  505. rollupConstants.HermezGovernanceDAOAddress, err = hermez.HermezGovernanceDAOAddress(nil)
  506. if err != nil {
  507. return err
  508. }
  509. rollupConstants.SafetyAddress, err = hermez.SafetyAddress(nil)
  510. if err != nil {
  511. return err
  512. }
  513. rollupConstants.WithdrawDelayerContract, err = hermez.WithdrawDelayerContract(nil)
  514. return err
  515. }); err != nil {
  516. return nil, err
  517. }
  518. return rollupConstants, nil
  519. }
  520. var (
  521. logHermezL1UserTxEvent = crypto.Keccak256Hash([]byte("L1UserTxEvent(uint64,uint8,bytes)"))
  522. logHermezAddToken = crypto.Keccak256Hash([]byte("AddToken(address,uint32)"))
  523. logHermezForgeBatch = crypto.Keccak256Hash([]byte("ForgeBatch(uint64)"))
  524. logHermezUpdateForgeL1L2BatchTimeout = crypto.Keccak256Hash([]byte("UpdateForgeL1L2BatchTimeout(uint8)"))
  525. logHermezUpdateFeeAddToken = crypto.Keccak256Hash([]byte("UpdateFeeAddToken(uint256)"))
  526. logHermezWithdrawEvent = crypto.Keccak256Hash([]byte("WithdrawEvent(uint48,uint48,bool)"))
  527. )
  528. // RollupEventsByBlock returns the events in a block that happened in the Rollup Smart Contract
  529. func (c *RollupClient) RollupEventsByBlock(blockNum int64) (*RollupEvents, *ethCommon.Hash, error) {
  530. var rollupEvents RollupEvents
  531. var blockHash ethCommon.Hash
  532. query := ethereum.FilterQuery{
  533. FromBlock: big.NewInt(blockNum),
  534. ToBlock: big.NewInt(blockNum),
  535. Addresses: []ethCommon.Address{
  536. c.address,
  537. },
  538. BlockHash: nil,
  539. Topics: [][]ethCommon.Hash{},
  540. }
  541. logs, err := c.client.client.FilterLogs(context.Background(), query)
  542. if err != nil {
  543. return nil, nil, err
  544. }
  545. if len(logs) > 0 {
  546. blockHash = logs[0].BlockHash
  547. }
  548. for _, vLog := range logs {
  549. if vLog.BlockHash != blockHash {
  550. return nil, nil, ErrBlockHashMismatchEvent
  551. }
  552. switch vLog.Topics[0] {
  553. case logHermezL1UserTxEvent:
  554. var L1UserTxAux RollupEventL1UserTxAux
  555. var L1UserTx RollupEventL1UserTx
  556. err := c.contractAbi.Unpack(&L1UserTxAux, "L1UserTxEvent", vLog.Data)
  557. if err != nil {
  558. return nil, nil, err
  559. }
  560. L1Tx, err := common.L1TxFromBytes(L1UserTxAux.L1Tx)
  561. if err != nil {
  562. return nil, nil, err
  563. }
  564. L1UserTx.ToForgeL1TxsNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
  565. L1UserTx.Position = int(new(big.Int).SetBytes(vLog.Topics[2][:]).Int64())
  566. L1UserTx.L1Tx = *L1Tx
  567. rollupEvents.L1UserTx = append(rollupEvents.L1UserTx, L1UserTx)
  568. case logHermezAddToken:
  569. var addToken RollupEventAddToken
  570. err := c.contractAbi.Unpack(&addToken, "AddToken", vLog.Data)
  571. if err != nil {
  572. return nil, nil, err
  573. }
  574. addToken.Address = ethCommon.BytesToAddress(vLog.Topics[1].Bytes())
  575. rollupEvents.AddToken = append(rollupEvents.AddToken, addToken)
  576. case logHermezForgeBatch:
  577. var forgeBatch RollupEventForgeBatch
  578. forgeBatch.BatchNum = new(big.Int).SetBytes(vLog.Topics[1][:]).Int64()
  579. forgeBatch.EthTxHash = vLog.TxHash
  580. rollupEvents.ForgeBatch = append(rollupEvents.ForgeBatch, forgeBatch)
  581. case logHermezUpdateForgeL1L2BatchTimeout:
  582. var updateForgeL1L2BatchTimeout RollupEventUpdateForgeL1L2BatchTimeout
  583. err := c.contractAbi.Unpack(&updateForgeL1L2BatchTimeout, "UpdateForgeL1L2BatchTimeout", vLog.Data)
  584. if err != nil {
  585. return nil, nil, err
  586. }
  587. rollupEvents.UpdateForgeL1L2BatchTimeout = append(rollupEvents.UpdateForgeL1L2BatchTimeout, updateForgeL1L2BatchTimeout)
  588. case logHermezUpdateFeeAddToken:
  589. var updateFeeAddToken RollupEventUpdateFeeAddToken
  590. err := c.contractAbi.Unpack(&updateFeeAddToken, "UpdateFeeAddToken", vLog.Data)
  591. if err != nil {
  592. return nil, nil, err
  593. }
  594. rollupEvents.UpdateFeeAddToken = append(rollupEvents.UpdateFeeAddToken, updateFeeAddToken)
  595. case logHermezWithdrawEvent:
  596. var withdraw RollupEventWithdrawEvent
  597. err := c.contractAbi.Unpack(&withdraw, "WithdrawEvent", vLog.Data)
  598. if err != nil {
  599. return nil, nil, err
  600. }
  601. withdraw.Idx = new(big.Int).SetBytes(vLog.Topics[1][:]).Uint64()
  602. withdraw.NumExitRoot = new(big.Int).SetBytes(vLog.Topics[2][:]).Uint64()
  603. rollupEvents.WithdrawEvent = append(rollupEvents.WithdrawEvent, withdraw)
  604. }
  605. }
  606. return &rollupEvents, &blockHash, nil
  607. }
  608. // RollupForgeBatchArgs returns the arguments used in a ForgeBatch call in the Rollup Smart Contract in the given transaction
  609. func (c *RollupClient) RollupForgeBatchArgs(ethTxHash ethCommon.Hash) (*RollupForgeBatchArgs, error) {
  610. tx, _, err := c.client.client.TransactionByHash(context.Background(), ethTxHash)
  611. if err != nil {
  612. return nil, err
  613. }
  614. txData := tx.Data()
  615. method, err := c.contractAbi.MethodById(txData[:4])
  616. if err != nil {
  617. return nil, err
  618. }
  619. var aux RollupForgeBatchArgsAux
  620. if err := method.Inputs.Unpack(&aux, txData[4:]); err != nil {
  621. return nil, err
  622. }
  623. var rollupForgeBatchArgs RollupForgeBatchArgs
  624. rollupForgeBatchArgs.L1Batch = aux.L1Batch
  625. rollupForgeBatchArgs.NewExitRoot = aux.NewExitRoot
  626. rollupForgeBatchArgs.NewLastIdx = aux.NewLastIdx.Int64()
  627. rollupForgeBatchArgs.NewStRoot = aux.NewStRoot
  628. rollupForgeBatchArgs.ProofA = aux.ProofA
  629. rollupForgeBatchArgs.ProofB = aux.ProofB
  630. rollupForgeBatchArgs.ProofC = aux.ProofC
  631. rollupForgeBatchArgs.VerifierIdx = aux.VerifierIdx
  632. numTxsL1 := len(aux.EncodedL1CoordinatorTx) / common.L1CoordinatorTxBytesLen
  633. for i := 0; i < numTxsL1; i++ {
  634. bytesL1Coordinator := aux.EncodedL1CoordinatorTx[i*common.L1CoordinatorTxBytesLen : (i+1)*common.L1CoordinatorTxBytesLen]
  635. var signature []byte
  636. v := bytesL1Coordinator[0]
  637. s := bytesL1Coordinator[1:33]
  638. r := bytesL1Coordinator[33:65]
  639. signature = append(signature, r[:]...)
  640. signature = append(signature, s[:]...)
  641. signature = append(signature, v)
  642. l1Tx, err := common.L1TxFromCoordinatorBytes(bytesL1Coordinator)
  643. if err != nil {
  644. return nil, err
  645. }
  646. rollupForgeBatchArgs.L1CoordinatorTxs = append(rollupForgeBatchArgs.L1CoordinatorTxs, l1Tx)
  647. rollupForgeBatchArgs.L1CoordinatorTxsAuths = append(rollupForgeBatchArgs.L1CoordinatorTxsAuths, signature)
  648. }
  649. rollupConsts, err := c.RollupConstants()
  650. if err != nil {
  651. return nil, err
  652. }
  653. nLevels := rollupConsts.Verifiers[rollupForgeBatchArgs.VerifierIdx].NLevels
  654. lenL2TxsBytes := int((nLevels/8)*2 + 2 + 1)
  655. numTxsL2 := len(aux.L2TxsData) / lenL2TxsBytes
  656. for i := 0; i < numTxsL2; i++ {
  657. l2Tx, err := common.L2TxFromBytes(aux.L2TxsData[i*lenL2TxsBytes:(i+1)*lenL2TxsBytes], int(nLevels))
  658. if err != nil {
  659. return nil, err
  660. }
  661. rollupForgeBatchArgs.L2TxsData = append(rollupForgeBatchArgs.L2TxsData, l2Tx)
  662. }
  663. lenFeeIdxCoordinatorBytes := int(nLevels / 8) //nolint:gomnd
  664. numFeeIdxCoordinator := len(aux.FeeIdxCoordinator) / lenFeeIdxCoordinatorBytes
  665. for i := 0; i < numFeeIdxCoordinator; i++ {
  666. var paddedFeeIdx [6]byte
  667. // TODO: This check is not necessary: the first case will always work. Test it before removing the if.
  668. if lenFeeIdxCoordinatorBytes < common.IdxBytesLen {
  669. copy(paddedFeeIdx[6-lenFeeIdxCoordinatorBytes:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
  670. } else {
  671. copy(paddedFeeIdx[:], aux.FeeIdxCoordinator[i*lenFeeIdxCoordinatorBytes:(i+1)*lenFeeIdxCoordinatorBytes])
  672. }
  673. FeeIdxCoordinator, err := common.IdxFromBytes(paddedFeeIdx[:])
  674. if err != nil {
  675. return nil, err
  676. }
  677. rollupForgeBatchArgs.FeeIdxCoordinator = append(rollupForgeBatchArgs.FeeIdxCoordinator, FeeIdxCoordinator)
  678. }
  679. return &rollupForgeBatchArgs, nil
  680. }