Skip to content

Commit ab071fd

Browse files
authored
Merge pull request #594 from 0xPolygon/feature/#593_readClaims
read claim events
2 parents 9f76a8c + bc97d43 commit ab071fd

File tree

4 files changed

+266
-26
lines changed

4 files changed

+266
-26
lines changed

cmd/ulxly/claimGetUsage.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
This command will attempt to scan a range of blocks and look for uLxLy
2+
Claim Events. This is the specific signature that we're interested
3+
in:
4+
5+
```solidity
6+
/**
7+
* @dev Emitted when a claim is done from another network
8+
*/
9+
event ClaimEvent(
10+
uint256 globalIndex,
11+
uint32 originNetwork,
12+
address originAddress,
13+
address destinationAddress,
14+
uint256 amount
15+
);
16+
```
17+
18+
If you're looking at the raw topics from on chain or in an explorer, this is the associated value:
19+
20+
`0x1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d`
21+
22+
Each event that we counter will be parsed and written as JSON to
23+
stdout. Example usage:
24+
25+
```bash
26+
polycli ulxly get-claims \
27+
--bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 \
28+
--rpc-url https://eth-sepolia.g.alchemy.com/v2/demo \
29+
--from-block 4880876 \
30+
--to-block 6028159 \
31+
--filter-size 9999 > cardona-4880876-to-6028159.ndjson
32+
```
33+
34+
This command will look for claim events from block `4880876` to
35+
block `6028159` in increments of `9999` blocks at a time for the
36+
contract address `0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582`. The
37+
output will be written as newline delimited JSON.
38+
39+
This command is very specific for the ulxly bridge, and it's meant to
40+
serve as the input to the proof command.
41+
42+

cmd/ulxly/ulxly.go

Lines changed: 129 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"errors"
1212
"fmt"
1313
"io"
14+
"math"
1415
"math/big"
1516
"net/http"
1617
"os"
@@ -108,11 +109,11 @@ type BridgeDepositResponse struct {
108109
}
109110

110111
func readDeposit(cmd *cobra.Command) error {
111-
bridgeAddress := getDepositOptions.BridgeAddress
112-
rpcUrl := getDepositsAndVerifyBatchesSharedOptions.URL
113-
toBlock := getDepositsAndVerifyBatchesSharedOptions.ToBlock
114-
fromBlock := getDepositsAndVerifyBatchesSharedOptions.FromBlock
115-
filter := getDepositsAndVerifyBatchesSharedOptions.FilterSize
112+
bridgeAddress := getSmcOptions.BridgeAddress
113+
rpcUrl := getEvent.URL
114+
toBlock := getEvent.ToBlock
115+
fromBlock := getEvent.FromBlock
116+
filter := getEvent.FilterSize
116117

117118
// Dial the Ethereum RPC server.
118119
rpc, err := ethrpc.DialContext(cmd.Context(), rpcUrl)
@@ -164,12 +165,96 @@ func readDeposit(cmd *cobra.Command) error {
164165
return nil
165166
}
166167

168+
func DecodeGlobalIndex(globalIndex *big.Int) (bool, uint32, uint32, error) {
169+
const lengthGlobalIndexInBytes = 32
170+
var buf [32]byte
171+
gIBytes := globalIndex.FillBytes(buf[:])
172+
if len(gIBytes) != lengthGlobalIndexInBytes {
173+
return false, 0, 0, fmt.Errorf("invalid globaIndex length. Should be 32. Current length: %d", len(gIBytes))
174+
}
175+
mainnetFlag := big.NewInt(0).SetBytes([]byte{gIBytes[23]}).Uint64() == 1
176+
rollupIndex := big.NewInt(0).SetBytes(gIBytes[24:28])
177+
localRootIndex := big.NewInt(0).SetBytes(gIBytes[28:32])
178+
if rollupIndex.Uint64() > math.MaxUint32 {
179+
return false, 0, 0, fmt.Errorf("invalid rollupIndex length. Should be fit into uint32 type")
180+
}
181+
if localRootIndex.Uint64() > math.MaxUint32 {
182+
return false, 0, 0, fmt.Errorf("invalid localRootIndex length. Should be fit into uint32 type")
183+
}
184+
return mainnetFlag, uint32(rollupIndex.Uint64()), uint32(localRootIndex.Uint64()), nil // nolint:gosec
185+
}
186+
187+
func readClaim(cmd *cobra.Command) error {
188+
bridgeAddress := getSmcOptions.BridgeAddress
189+
rpcUrl := getEvent.URL
190+
toBlock := getEvent.ToBlock
191+
fromBlock := getEvent.FromBlock
192+
filter := getEvent.FilterSize
193+
194+
// Dial the Ethereum RPC server.
195+
rpc, err := ethrpc.DialContext(cmd.Context(), rpcUrl)
196+
if err != nil {
197+
log.Error().Err(err).Msg("Unable to Dial RPC")
198+
return err
199+
}
200+
defer rpc.Close()
201+
ec := ethclient.NewClient(rpc)
202+
203+
bridgeV2, err := ulxly.NewUlxly(common.HexToAddress(bridgeAddress), ec)
204+
if err != nil {
205+
return err
206+
}
207+
currentBlock := fromBlock
208+
for currentBlock < toBlock {
209+
endBlock := currentBlock + filter
210+
if endBlock > toBlock {
211+
endBlock = toBlock
212+
}
213+
214+
opts := bind.FilterOpts{
215+
Start: currentBlock,
216+
End: &endBlock,
217+
Context: cmd.Context(),
218+
}
219+
evtV2Iterator, err := bridgeV2.FilterClaimEvent(&opts)
220+
if err != nil {
221+
return err
222+
}
223+
224+
for evtV2Iterator.Next() {
225+
evt := evtV2Iterator.Event
226+
var (
227+
mainnetFlag bool
228+
rollupIndex, localExitRootIndex uint32
229+
)
230+
mainnetFlag, rollupIndex, localExitRootIndex, err = DecodeGlobalIndex(evt.GlobalIndex)
231+
if err != nil {
232+
log.Error().Err(err).Msg("error decoding globalIndex")
233+
return err
234+
}
235+
log.Info().Bool("claim-mainnetFlag", mainnetFlag).Uint32("claim-RollupIndex", rollupIndex).Uint32("claim-LocalExitRootIndex", localExitRootIndex).Uint64("block-number", evt.Raw.BlockNumber).Msg("Found Claim")
236+
var jBytes []byte
237+
jBytes, err = json.Marshal(evt)
238+
if err != nil {
239+
return err
240+
}
241+
fmt.Println(string(jBytes))
242+
}
243+
err = evtV2Iterator.Close()
244+
if err != nil {
245+
log.Error().Err(err).Msg("error closing event iterator")
246+
}
247+
currentBlock = endBlock
248+
}
249+
250+
return nil
251+
}
167252
func readVerifyBatches(cmd *cobra.Command) error {
168253
rollupManagerAddress := getVerifyBatchesOptions.RollupManagerAddress
169-
rpcUrl := getDepositsAndVerifyBatchesSharedOptions.URL
170-
toBlock := getDepositsAndVerifyBatchesSharedOptions.ToBlock
171-
fromBlock := getDepositsAndVerifyBatchesSharedOptions.FromBlock
172-
filter := getDepositsAndVerifyBatchesSharedOptions.FilterSize
254+
rpcUrl := getEvent.URL
255+
toBlock := getEvent.ToBlock
256+
fromBlock := getEvent.FromBlock
257+
filter := getEvent.FilterSize
173258

174259
// Dial the Ethereum RPC server.
175260
rpc, err := ethrpc.DialContext(cmd.Context(), rpcUrl)
@@ -1528,6 +1613,9 @@ var rollupsProofUsage string
15281613
//go:embed depositGetUsage.md
15291614
var depositGetUsage string
15301615

1616+
//go:embed claimGetUsage.md
1617+
var claimGetUsage string
1618+
15311619
//go:embed verifyBatchesGetUsage.md
15321620
var verifyBatchesGetUsage string
15331621

@@ -1555,7 +1643,7 @@ var ulxlyBridgeAndClaimCmd = &cobra.Command{
15551643
},
15561644
}
15571645

1558-
var ulxlyGetDepositsAndVerifyBatchesCmd = &cobra.Command{
1646+
var ulxlyGetEventsCmd = &cobra.Command{
15591647
Args: cobra.NoArgs,
15601648
Hidden: true,
15611649
}
@@ -1619,14 +1707,15 @@ var (
16191707
proofCommand *cobra.Command
16201708
rollupsProofCommand *cobra.Command
16211709
getDepositCommand *cobra.Command
1710+
getClaimCommand *cobra.Command
16221711
getVerifyBatchesCommand *cobra.Command
16231712

1624-
getDepositsAndVerifyBatchesSharedOptions = &GetDepositsAndVerifyBatchesSharedOptions{}
1625-
getDepositOptions = &GetDepositOptions{}
1626-
getVerifyBatchesOptions = &GetVerifyBatchesOptions{}
1627-
proofsSharedOptions = &ProofsSharedOptions{}
1628-
proofOptions = &ProofOptions{}
1629-
rollupsProofOptions = &RollupsProofOptions{}
1713+
getEvent = &GetEvent{}
1714+
getSmcOptions = &GetSmcOptions{}
1715+
getVerifyBatchesOptions = &GetVerifyBatchesOptions{}
1716+
proofsSharedOptions = &ProofsSharedOptions{}
1717+
proofOptions = &ProofOptions{}
1718+
rollupsProofOptions = &RollupsProofOptions{}
16301719
)
16311720

16321721
const (
@@ -1734,12 +1823,12 @@ func (o *RollupsProofOptions) AddFlags(cmd *cobra.Command) {
17341823
cmd.Flags().BoolVarP(&o.CompleteMerkleTree, ArgCompleteMT, "", false, "Allows to get the proof for a leave higher than the highest rollupID")
17351824
}
17361825

1737-
type GetDepositsAndVerifyBatchesSharedOptions struct {
1826+
type GetEvent struct {
17381827
URL string
17391828
FromBlock, ToBlock, FilterSize uint64
17401829
}
17411830

1742-
func (o *GetDepositsAndVerifyBatchesSharedOptions) AddFlags(cmd *cobra.Command) {
1831+
func (o *GetEvent) AddFlags(cmd *cobra.Command) {
17431832
cmd.Flags().StringVarP(&o.URL, ArgRPCURL, "u", "", "The RPC URL to read the events data")
17441833
cmd.Flags().Uint64VarP(&o.FromBlock, ArgFromBlock, "f", 0, "The start of the range of blocks to retrieve")
17451834
cmd.Flags().Uint64VarP(&o.ToBlock, ArgToBlock, "t", 0, "The end of the range of blocks to retrieve")
@@ -1749,11 +1838,11 @@ func (o *GetDepositsAndVerifyBatchesSharedOptions) AddFlags(cmd *cobra.Command)
17491838
fatalIfError(cmd.MarkFlagRequired(ArgRPCURL))
17501839
}
17511840

1752-
type GetDepositOptions struct {
1841+
type GetSmcOptions struct {
17531842
BridgeAddress string
17541843
}
17551844

1756-
func (o *GetDepositOptions) AddFlags(cmd *cobra.Command) {
1845+
func (o *GetSmcOptions) AddFlags(cmd *cobra.Command) {
17571846
cmd.Flags().StringVarP(&o.BridgeAddress, ArgBridgeAddress, "a", "", "The address of the ulxly bridge")
17581847
}
17591848

@@ -1885,11 +1974,25 @@ or if it's actually an intermediate hash.`,
18851974
},
18861975
SilenceUsage: true,
18871976
}
1888-
getDepositsAndVerifyBatchesSharedOptions.AddFlags(getDepositCommand)
1889-
getDepositOptions.AddFlags(getDepositCommand)
1890-
ulxlyGetDepositsAndVerifyBatchesCmd.AddCommand(getDepositCommand)
1977+
getEvent.AddFlags(getDepositCommand)
1978+
getSmcOptions.AddFlags(getDepositCommand)
1979+
ulxlyGetEventsCmd.AddCommand(getDepositCommand)
18911980
ULxLyCmd.AddCommand(getDepositCommand)
18921981

1982+
getClaimCommand = &cobra.Command{
1983+
Use: "get-claims",
1984+
Short: "Generate ndjson for each bridge claim over a particular range of blocks",
1985+
Long: claimGetUsage,
1986+
RunE: func(cmd *cobra.Command, args []string) error {
1987+
return readClaim(cmd)
1988+
},
1989+
SilenceUsage: true,
1990+
}
1991+
getEvent.AddFlags(getClaimCommand)
1992+
getSmcOptions.AddFlags(getClaimCommand)
1993+
ulxlyGetEventsCmd.AddCommand(getClaimCommand)
1994+
ULxLyCmd.AddCommand(getClaimCommand)
1995+
18931996
getVerifyBatchesCommand = &cobra.Command{
18941997
Use: "get-verify-batches",
18951998
Short: "Generate ndjson for each verify batch over a particular range of blocks",
@@ -1899,9 +2002,9 @@ or if it's actually an intermediate hash.`,
18992002
},
19002003
SilenceUsage: true,
19012004
}
1902-
getDepositsAndVerifyBatchesSharedOptions.AddFlags(getVerifyBatchesCommand)
2005+
getEvent.AddFlags(getVerifyBatchesCommand)
19032006
getVerifyBatchesOptions.AddFlags(getVerifyBatchesCommand)
1904-
ulxlyGetDepositsAndVerifyBatchesCmd.AddCommand(getVerifyBatchesCommand)
2007+
ulxlyGetEventsCmd.AddCommand(getVerifyBatchesCommand)
19052008
ULxLyCmd.AddCommand(getVerifyBatchesCommand)
19062009

19072010
// Arguments for both bridge and claim
@@ -1945,7 +2048,7 @@ or if it's actually an intermediate hash.`,
19452048

19462049
// Top Level
19472050
ULxLyCmd.AddCommand(ulxlyBridgeAndClaimCmd)
1948-
ULxLyCmd.AddCommand(ulxlyGetDepositsAndVerifyBatchesCmd)
2051+
ULxLyCmd.AddCommand(ulxlyGetEventsCmd)
19492052
ULxLyCmd.AddCommand(ulxlyProofsCmd)
19502053
ULxLyCmd.AddCommand(emptyProofCommand)
19512054
ULxLyCmd.AddCommand(zeroProofCommand)

doc/polycli_ulxly.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ The command also inherits flags from parent commands.
4848

4949
- [polycli ulxly empty-proof](polycli_ulxly_empty-proof.md) - create an empty proof
5050

51+
- [polycli ulxly get-claims](polycli_ulxly_get-claims.md) - Generate ndjson for each bridge claim over a particular range of blocks
52+
5153
- [polycli ulxly get-deposits](polycli_ulxly_get-deposits.md) - Generate ndjson for each bridge deposit over a particular range of blocks
5254

5355
- [polycli ulxly get-verify-batches](polycli_ulxly_get-verify-batches.md) - Generate ndjson for each verify batch over a particular range of blocks

doc/polycli_ulxly_get-claims.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# `polycli ulxly get-claims`
2+
3+
> Auto-generated documentation.
4+
5+
## Table of Contents
6+
7+
- [Description](#description)
8+
- [Usage](#usage)
9+
- [Flags](#flags)
10+
- [See Also](#see-also)
11+
12+
## Description
13+
14+
Generate ndjson for each bridge claim over a particular range of blocks
15+
16+
```bash
17+
polycli ulxly get-claims [flags]
18+
```
19+
20+
## Usage
21+
22+
This command will attempt to scan a range of blocks and look for uLxLy
23+
Claim Events. This is the specific signature that we're interested
24+
in:
25+
26+
```solidity
27+
/**
28+
* @dev Emitted when a claim is done from another network
29+
*/
30+
event ClaimEvent(
31+
uint256 globalIndex,
32+
uint32 originNetwork,
33+
address originAddress,
34+
address destinationAddress,
35+
uint256 amount
36+
);
37+
```
38+
39+
If you're looking at the raw topics from on chain or in an explorer, this is the associated value:
40+
41+
`0x1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d`
42+
43+
Each event that we counter will be parsed and written as JSON to
44+
stdout. Example usage:
45+
46+
```bash
47+
polycli ulxly get-claims \
48+
--bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 \
49+
--rpc-url https://eth-sepolia.g.alchemy.com/v2/demo \
50+
--from-block 4880876 \
51+
--to-block 6028159 \
52+
--filter-size 9999 > cardona-4880876-to-6028159.ndjson
53+
```
54+
55+
This command will look for claim events from block `4880876` to
56+
block `6028159` in increments of `9999` blocks at a time for the
57+
contract address `0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582`. The
58+
output will be written as newline delimited JSON.
59+
60+
This command is very specific for the ulxly bridge, and it's meant to
61+
serve as the input to the proof command.
62+
63+
64+
65+
## Flags
66+
67+
```bash
68+
-a, --bridge-address string The address of the ulxly bridge
69+
-i, --filter-size uint The batch size for individual filter queries (default 1000)
70+
-f, --from-block uint The start of the range of blocks to retrieve
71+
-h, --help help for get-claims
72+
-u, --rpc-url string The RPC URL to read the events data
73+
-t, --to-block uint The end of the range of blocks to retrieve
74+
```
75+
76+
The command also inherits flags from parent commands.
77+
78+
```bash
79+
--config string config file (default is $HOME/.polygon-cli.yaml)
80+
--pretty-logs Should logs be in pretty format or JSON (default true)
81+
-v, --verbosity int 0 - Silent
82+
100 Panic
83+
200 Fatal
84+
300 Error
85+
400 Warning
86+
500 Info
87+
600 Debug
88+
700 Trace (default 500)
89+
```
90+
91+
## See also
92+
93+
- [polycli ulxly](polycli_ulxly.md) - Utilities for interacting with the uLxLy bridge

0 commit comments

Comments
 (0)