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.

650 lines
25 KiB

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