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.

654 lines
25 KiB

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