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.

219 lines
9.4 KiB

Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
Fix eth events query and sync inconsistent state - kvdb - Fix path in Last when doing `setNew` - Only close if db != nil, and after closing, always set db to nil - This will avoid a panic in the case where the db is closed but there's an error soon after, and a future call tries to close again. This is because pebble.Close() will panic if the db is already closed. - Avoid calling pebble methods when a the Storage interface already implements that method (like Close). - statedb - In test, avoid calling KVDB method if the same method is available for the StateDB (like MakeCheckpoint, CurrentBatch). - eth - In *EventByBlock methods, take blockHash as input argument and use it when querying the event logs. Previously the blockHash was only taken from the logs results *only if* there was any log. This caused the following issue: if there was no logs, it was not possible to know if the result was from the expected block or an uncle block! By querying logs by blockHash we make sure that even if there are no logs, they are from the right block. - Note that now the function can either be called with a blockNum or blockHash, but not both at the same time. - sync - If there's an error during call to Sync call resetState, which internally resets the stateDB to avoid stale checkpoints (and a corresponding invalid increase in the StateDB batchNum). - During a Sync, after very batch processed, make sure that the StateDB currentBatch corresponds to the batchNum in the smart contract log/event.
3 years ago
  1. package eth
  2. import (
  3. "math/big"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. )
  9. var wdelayerClient *WDelayerClient
  10. var wdelayerClientTest *WDelayerClient
  11. var initWithdrawalDelay int64 = 60
  12. var newWithdrawalDelay int64 = 79
  13. var maxEmergencyModeTime = time.Hour * 24 * 7 * 26
  14. var maxWithdrawalDelay = time.Hour * 24 * 7 * 2
  15. func TestWDelayerInit(t *testing.T) {
  16. wDelayerInit, blockNum, err := wdelayerClientTest.WDelayerEventInit()
  17. require.NoError(t, err)
  18. assert.Equal(t, int64(16), blockNum)
  19. assert.Equal(t, uint64(initWithdrawalDelay), wDelayerInit.InitialWithdrawalDelay)
  20. assert.Equal(t, governanceAddressConst, wDelayerInit.InitialHermezGovernanceAddress)
  21. assert.Equal(t, emergencyCouncilAddressConst, wDelayerInit.InitialEmergencyCouncil)
  22. }
  23. func TestWDelayerConstants(t *testing.T) {
  24. wDelayerConstants, err := wdelayerClientTest.WDelayerConstants()
  25. require.Nil(t, err)
  26. assert.Equal(t, uint64(maxWithdrawalDelay.Seconds()), wDelayerConstants.MaxWithdrawalDelay)
  27. assert.Equal(t, uint64(maxEmergencyModeTime.Seconds()), wDelayerConstants.MaxEmergencyModeTime)
  28. assert.Equal(t, hermezRollupTestAddressConst, wDelayerConstants.HermezRollup)
  29. }
  30. func TestWDelayerGetHermezGovernanceAddress(t *testing.T) {
  31. governanceAddress, err := wdelayerClientTest.WDelayerGetHermezGovernanceAddress()
  32. require.Nil(t, err)
  33. assert.Equal(t, &governanceAddressConst, governanceAddress)
  34. }
  35. func TestWDelayerSetHermezGovernanceAddress(t *testing.T) {
  36. wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerTestAddressConst)
  37. require.Nil(t, err)
  38. _, err = wdelayerClientTest.WDelayerTransferGovernance(auxAddressConst)
  39. require.Nil(t, err)
  40. _, err = wdelayerClientAux.WDelayerClaimGovernance()
  41. require.Nil(t, err)
  42. auxAddress, err := wdelayerClientTest.WDelayerGetHermezGovernanceAddress()
  43. require.Nil(t, err)
  44. assert.Equal(t, &auxAddressConst, auxAddress)
  45. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  46. require.Nil(t, err)
  47. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  48. require.Nil(t, err)
  49. assert.Equal(t, auxAddressConst, wdelayerEvents.NewHermezGovernanceAddress[0].NewHermezGovernanceAddress)
  50. _, err = wdelayerClientAux.WDelayerTransferGovernance(governanceAddressConst)
  51. require.Nil(t, err)
  52. _, err = wdelayerClientTest.WDelayerClaimGovernance()
  53. require.Nil(t, err)
  54. }
  55. func TestWDelayerGetEmergencyCouncil(t *testing.T) {
  56. emergencyCouncil, err := wdelayerClientTest.WDelayerGetEmergencyCouncil()
  57. require.Nil(t, err)
  58. assert.Equal(t, &emergencyCouncilAddressConst, emergencyCouncil)
  59. }
  60. func TestWDelayerSetEmergencyCouncil(t *testing.T) {
  61. wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil, wdelayerTestAddressConst)
  62. require.Nil(t, err)
  63. wdelayerClientAux, err := NewWDelayerClient(ethereumClientAux, wdelayerTestAddressConst)
  64. require.Nil(t, err)
  65. _, err = wdelayerClientEmergencyCouncil.WDelayerTransferEmergencyCouncil(auxAddressConst)
  66. require.Nil(t, err)
  67. _, err = wdelayerClientAux.WDelayerClaimEmergencyCouncil()
  68. require.Nil(t, err)
  69. auxAddress, err := wdelayerClientTest.WDelayerGetEmergencyCouncil()
  70. require.Nil(t, err)
  71. assert.Equal(t, &auxAddressConst, auxAddress)
  72. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  73. require.Nil(t, err)
  74. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  75. require.Nil(t, err)
  76. assert.Equal(t, auxAddressConst, wdelayerEvents.NewEmergencyCouncil[0].NewEmergencyCouncil)
  77. _, err = wdelayerClientAux.WDelayerTransferEmergencyCouncil(emergencyCouncilAddressConst)
  78. require.Nil(t, err)
  79. _, err = wdelayerClientEmergencyCouncil.WDelayerClaimEmergencyCouncil()
  80. require.Nil(t, err)
  81. }
  82. func TestWDelayerIsEmergencyMode(t *testing.T) {
  83. emergencyMode, err := wdelayerClientTest.WDelayerIsEmergencyMode()
  84. require.Nil(t, err)
  85. assert.Equal(t, false, emergencyMode)
  86. }
  87. func TestWDelayerGetWithdrawalDelay(t *testing.T) {
  88. withdrawalDelay, err := wdelayerClientTest.WDelayerGetWithdrawalDelay()
  89. require.Nil(t, err)
  90. assert.Equal(t, initWithdrawalDelay, withdrawalDelay)
  91. }
  92. func TestWDelayerChangeWithdrawalDelay(t *testing.T) {
  93. _, err := wdelayerClientTest.WDelayerChangeWithdrawalDelay(uint64(newWithdrawalDelay))
  94. require.Nil(t, err)
  95. withdrawalDelay, err := wdelayerClientTest.WDelayerGetWithdrawalDelay()
  96. require.Nil(t, err)
  97. assert.Equal(t, newWithdrawalDelay, withdrawalDelay)
  98. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  99. require.Nil(t, err)
  100. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  101. require.Nil(t, err)
  102. assert.Equal(t, uint64(newWithdrawalDelay), wdelayerEvents.NewWithdrawalDelay[0].WithdrawalDelay)
  103. }
  104. func TestWDelayerDeposit(t *testing.T) {
  105. amount := new(big.Int)
  106. amount.SetString("1100000000000000000", 10)
  107. wdelayerClientHermez, err := NewWDelayerClient(ethereumClientHermez, wdelayerTestAddressConst)
  108. require.Nil(t, err)
  109. _, err = wdelayerClientHermez.WDelayerDeposit(auxAddressConst, tokenHEZAddressConst, amount)
  110. require.Nil(t, err)
  111. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  112. require.Nil(t, err)
  113. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  114. require.Nil(t, err)
  115. assert.Equal(t, amount, wdelayerEvents.Deposit[0].Amount)
  116. assert.Equal(t, auxAddressConst, wdelayerEvents.Deposit[0].Owner)
  117. assert.Equal(t, tokenHEZAddressConst, wdelayerEvents.Deposit[0].Token)
  118. }
  119. func TestWDelayerDepositInfo(t *testing.T) {
  120. amount := new(big.Int)
  121. amount.SetString("1100000000000000000", 10)
  122. state, err := wdelayerClientTest.WDelayerDepositInfo(auxAddressConst, tokenHEZAddressConst)
  123. require.Nil(t, err)
  124. assert.Equal(t, state.Amount, amount)
  125. }
  126. func TestWDelayerWithdrawal(t *testing.T) {
  127. amount := new(big.Int)
  128. amount.SetString("1100000000000000000", 10)
  129. _, err := wdelayerClientTest.WDelayerWithdrawal(auxAddressConst, tokenHEZAddressConst)
  130. require.Contains(t, err.Error(), "WITHDRAWAL_NOT_ALLOWED")
  131. addTime(float64(newWithdrawalDelay), ethClientDialURL)
  132. addBlock(ethClientDialURL)
  133. _, err = wdelayerClientTest.WDelayerWithdrawal(auxAddressConst, tokenHEZAddressConst)
  134. require.Nil(t, err)
  135. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  136. require.Nil(t, err)
  137. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  138. require.Nil(t, err)
  139. assert.Equal(t, amount, wdelayerEvents.Withdraw[0].Amount)
  140. assert.Equal(t, auxAddressConst, wdelayerEvents.Withdraw[0].Owner)
  141. assert.Equal(t, tokenHEZAddressConst, wdelayerEvents.Withdraw[0].Token)
  142. }
  143. func TestWDelayerSecondDeposit(t *testing.T) {
  144. amount := new(big.Int)
  145. amount.SetString("1100000000000000000", 10)
  146. wdelayerClientHermez, err := NewWDelayerClient(ethereumClientHermez, wdelayerTestAddressConst)
  147. require.Nil(t, err)
  148. _, err = wdelayerClientHermez.WDelayerDeposit(auxAddressConst, tokenHEZAddressConst, amount)
  149. require.Nil(t, err)
  150. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  151. require.Nil(t, err)
  152. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  153. require.Nil(t, err)
  154. assert.Equal(t, amount, wdelayerEvents.Deposit[0].Amount)
  155. assert.Equal(t, auxAddressConst, wdelayerEvents.Deposit[0].Owner)
  156. assert.Equal(t, tokenHEZAddressConst, wdelayerEvents.Deposit[0].Token)
  157. }
  158. func TestWDelayerEnableEmergencyMode(t *testing.T) {
  159. _, err := wdelayerClientTest.WDelayerEnableEmergencyMode()
  160. require.Nil(t, err)
  161. emergencyMode, err := wdelayerClientTest.WDelayerIsEmergencyMode()
  162. require.Nil(t, err)
  163. assert.Equal(t, true, emergencyMode)
  164. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  165. require.Nil(t, err)
  166. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  167. require.Nil(t, err)
  168. auxEvent := new(WDelayerEventEmergencyModeEnabled)
  169. assert.Equal(t, auxEvent, &wdelayerEvents.EmergencyModeEnabled[0])
  170. }
  171. func TestWDelayerGetEmergencyModeStartingTime(t *testing.T) {
  172. emergencyModeStartingTime, err := wdelayerClientTest.WDelayerGetEmergencyModeStartingTime()
  173. require.Nil(t, err)
  174. // `emergencyModeStartingTime` is initialized to 0 in the smart
  175. // contract construction. Since we called WDelayerEnableEmergencyMode
  176. // previously, `emergencyModeStartingTime` is set to the time when the
  177. // call was made, so it's > 0.
  178. assert.Greater(t, emergencyModeStartingTime, int64(0))
  179. }
  180. func TestWDelayerEscapeHatchWithdrawal(t *testing.T) {
  181. amount := new(big.Int)
  182. amount.SetString("10000000000000000", 10)
  183. wdelayerClientEmergencyCouncil, err := NewWDelayerClient(ethereumClientEmergencyCouncil, wdelayerTestAddressConst)
  184. require.Nil(t, err)
  185. _, err = wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHEZAddressConst, amount)
  186. require.Contains(t, err.Error(), "NO_MAX_EMERGENCY_MODE_TIME")
  187. seconds := maxEmergencyModeTime.Seconds()
  188. addTime(seconds, ethClientDialURL)
  189. _, err = wdelayerClientEmergencyCouncil.WDelayerEscapeHatchWithdrawal(governanceAddressConst, tokenHEZAddressConst, amount)
  190. require.Nil(t, err)
  191. currentBlockNum, err := wdelayerClientTest.client.EthLastBlock()
  192. require.Nil(t, err)
  193. wdelayerEvents, err := wdelayerClientTest.WDelayerEventsByBlock(currentBlockNum, nil)
  194. require.Nil(t, err)
  195. assert.Equal(t, tokenHEZAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].Token)
  196. assert.Equal(t, governanceAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].To)
  197. assert.Equal(t, emergencyCouncilAddressConst, wdelayerEvents.EscapeHatchWithdrawal[0].Who)
  198. assert.Equal(t, amount, wdelayerEvents.EscapeHatchWithdrawal[0].Amount)
  199. }