Skip to content

Commit c36365d

Browse files
committed
Merge branch 'main' into thiago/fund-use-multicall3
2 parents d47b7f4 + bd9923c commit c36365d

File tree

10 files changed

+195
-84
lines changed

10 files changed

+195
-84
lines changed

cmd/fixnoncegap/fixnoncegap.go

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,12 @@ func fixNonceGap(cmd *cobra.Command, args []string) error {
115115
var maxNonce uint64
116116
if inputFixNonceGapArgs.maxNonce != 0 {
117117
maxNonce = inputFixNonceGapArgs.maxNonce
118+
log.Info().Uint64("maxNonce", maxNonce).Msg("maxNonce loaded from --max-nonce flag")
118119
} else {
119-
maxNonce, err = getMaxNonceFromTxPool(addr)
120+
log.Info().Msg("--max-nonce flag not set")
121+
maxNonce, err = getMaxNonce(addr)
120122
if err != nil {
121-
if strings.Contains(err.Error(), "the method txpool_content does not exist/is not available") {
122-
log.Error().Err(err).Msg("The RPC doesn't provide access to txpool_content, please check --help for more information about --max-nonce")
123-
return nil
124-
}
125-
log.Error().Err(err).Msg("Unable to get max nonce from txpool")
123+
log.Error().Err(err).Msg("Unable to get max nonce, please check --help for more information about --max-nonce")
126124
return err
127125
}
128126
}
@@ -132,7 +130,11 @@ func fixNonceGap(cmd *cobra.Command, args []string) error {
132130
log.Info().Stringer("addr", addr).Msg("There is no nonce gap.")
133131
return nil
134132
}
135-
log.Info().Stringer("addr", addr).Msgf("Nonce gap found. Max nonce: %d", maxNonce)
133+
log.Info().
134+
Stringer("addr", addr).
135+
Uint64("currentNonce", currentNonce).
136+
Uint64("maxNonce", maxNonce).
137+
Msg("Nonce gap found")
136138

137139
gasPrice, err := rpcClient.SuggestGasPrice(cmd.Context())
138140
if err != nil {
@@ -273,6 +275,26 @@ func WaitMineTransaction(ctx context.Context, client *ethclient.Client, tx *type
273275
}
274276
}
275277

278+
func getMaxNonce(addr common.Address) (uint64, error) {
279+
log.Info().Msg("getting max nonce from txpool_content")
280+
maxNonce, err := getMaxNonceFromTxPool(addr)
281+
if err == nil {
282+
log.Info().Uint64("maxNonce", maxNonce).Msg("maxNonce loaded from txpool_content")
283+
return maxNonce, nil
284+
}
285+
log.Warn().Err(err).Msg("unable to get max nonce from txpool_content")
286+
287+
log.Info().Msg("getting max nonce from pending nonce")
288+
// if the error is not about txpool_content, falls back to PendingNonceAt
289+
maxNonce, err = rpcClient.PendingNonceAt(context.Background(), addr)
290+
if err != nil {
291+
return 0, err
292+
}
293+
294+
log.Info().Uint64("maxNonce", maxNonce).Msg("maxNonce loaded from pending nonce")
295+
return maxNonce, nil
296+
}
297+
276298
func getMaxNonceFromTxPool(addr common.Address) (uint64, error) {
277299
var result PoolContent
278300
err := rpcClient.Client().Call(&result, "txpool_content")
@@ -299,6 +321,7 @@ func getMaxNonceFromTxPool(addr common.Address) (uint64, error) {
299321
nonceInt, ok := new(big.Int).SetString(nonce, 10)
300322
if !ok {
301323
err = fmt.Errorf("invalid nonce found: %s", nonce)
324+
log.Warn().Err(err).Msg("unable to get txpool_content")
302325
return 0, err
303326
}
304327

cmd/ulxly/bridge_service/aggkit/service.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,32 +57,43 @@ func (s *BridgeService) GetDeposits(destinationAddress string, offset, limit int
5757
return nil, 0, fmt.Errorf("GetDeposits is not supported by aggkit bridge service yet")
5858
}
5959

60-
func (s *BridgeService) GetProof(depositNetwork, depositCount uint32, ger *common.Hash) (*bridge_service.Proof, error) {
61-
var l1InfoTreeIndex uint32
60+
func (s *BridgeService) GetProof(depositNetwork, depositCount uint32) (*bridge_service.Proof, error) {
61+
return s.getProof(depositNetwork, depositCount, nil)
62+
}
6263

63-
if ger != nil {
64-
return nil, errors.New("getting proof by ger is not supported yet by Aggkit bridge service")
65-
}
64+
func (s *BridgeService) GetProofByGer(depositNetwork, depositCount uint32, ger common.Hash) (*bridge_service.Proof, error) {
65+
return nil, errors.New("getting proof by ger is not supported yet by Aggkit bridge service")
66+
}
6667

67-
timeout := time.After(time.Minute)
68-
out:
69-
for {
70-
idx, err := s.getL1InfoTreeIndex(depositNetwork, depositCount)
71-
if err != nil && !errors.Is(err, bridge_service.ErrNotFound) {
72-
return nil, err
73-
} else if err == nil {
74-
l1InfoTreeIndex = *idx
75-
break out
76-
}
77-
select {
78-
case <-timeout:
79-
return nil, fmt.Errorf("timeout waiting for l1 info tree index")
80-
default:
81-
time.Sleep(time.Second)
68+
func (s *BridgeService) GetProofByL1InfoTreeIndex(depositNetwork, depositCount uint32, l1InfoTreeIndex uint32) (*bridge_service.Proof, error) {
69+
return s.getProof(depositNetwork, depositCount, &l1InfoTreeIndex)
70+
}
71+
72+
func (s *BridgeService) getProof(depositNetwork, depositCount uint32, l1InfoTreeIndex *uint32) (*bridge_service.Proof, error) {
73+
var l1InfoTreeIndexValue uint32
74+
if l1InfoTreeIndex != nil {
75+
l1InfoTreeIndexValue = *l1InfoTreeIndex
76+
} else {
77+
78+
timeout := time.After(time.Minute)
79+
out:
80+
for {
81+
idx, err := s.getL1InfoTreeIndex(depositNetwork, depositCount)
82+
if err != nil && !errors.Is(err, bridge_service.ErrNotFound) {
83+
return nil, err
84+
} else if err == nil {
85+
l1InfoTreeIndexValue = *idx
86+
break out
87+
}
88+
select {
89+
case <-timeout:
90+
return nil, fmt.Errorf("timeout waiting for l1 info tree index")
91+
default:
92+
time.Sleep(time.Second)
93+
}
8294
}
8395
}
84-
85-
endpoint := fmt.Sprintf("%s/%s/claim-proof?network_id=%d&leaf_index=%d&deposit_count=%d", s.BridgeServiceBase.Url(), urlPath, depositNetwork, l1InfoTreeIndex, depositCount)
96+
endpoint := fmt.Sprintf("%s/%s/claim-proof?network_id=%d&leaf_index=%d&deposit_count=%d", s.BridgeServiceBase.Url(), urlPath, depositNetwork, l1InfoTreeIndexValue, depositCount)
8697
resp, respError, statusCode, err := httpjson.HTTPGetWithError[getClaimProofResponse, errorResponse](s.httpClient, endpoint)
8798
if err != nil {
8899
return nil, err

cmd/ulxly/bridge_service/interface.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ var (
1515
type BridgeService interface {
1616
GetDeposit(depositNetwork, depositCount uint32) (*Deposit, error)
1717
GetDeposits(destinationAddress string, offset, limit int) (deposits []Deposit, total int, err error)
18-
GetProof(depositNetwork, depositCount uint32, ger *common.Hash) (*Proof, error)
18+
GetProof(depositNetwork, depositCount uint32) (*Proof, error)
19+
GetProofByGer(depositNetwork, depositCount uint32, ger common.Hash) (*Proof, error)
20+
GetProofByL1InfoTreeIndex(depositNetwork, depositCount uint32, l1InfoTreeIndex uint32) (*Proof, error)
1921
Url() string
2022
}
2123

cmd/ulxly/bridge_service/legacy/service.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,21 @@ func (s *BridgeService) GetDeposits(destinationAddress string, offset, limit int
6666

6767
}
6868

69-
func (s *BridgeService) GetProof(depositNetwork, depositCount uint32, ger *common.Hash) (*bridge_service.Proof, error) {
69+
func (s *BridgeService) GetProof(depositNetwork, depositCount uint32) (*bridge_service.Proof, error) {
7070
endpoint := fmt.Sprintf("%s/merkle-proof?net_id=%d&deposit_cnt=%d", s.BridgeServiceBase.Url(), depositNetwork, depositCount)
71-
if ger != nil {
72-
endpoint = fmt.Sprintf("%s/merkle-proof-by-ger?net_id=%d&deposit_cnt=%d&ger=%s", s.BridgeServiceBase.Url(), depositNetwork, depositCount, ger.String())
71+
72+
resp, _, err := httpjson.HTTPGet[GetProofResponse](s.httpClient, endpoint)
73+
if err != nil {
74+
return nil, err
7375
}
7476

77+
proof := resp.Proof.ToProof()
78+
return proof, nil
79+
}
80+
81+
func (s *BridgeService) GetProofByGer(depositNetwork, depositCount uint32, ger common.Hash) (*bridge_service.Proof, error) {
82+
endpoint := fmt.Sprintf("%s/merkle-proof-by-ger?net_id=%d&deposit_cnt=%d&ger=%s", s.BridgeServiceBase.Url(), depositNetwork, depositCount, ger.String())
83+
7584
resp, _, err := httpjson.HTTPGet[GetProofResponse](s.httpClient, endpoint)
7685
if err != nil {
7786
return nil, err
@@ -80,3 +89,7 @@ func (s *BridgeService) GetProof(depositNetwork, depositCount uint32, ger *commo
8089
proof := resp.Proof.ToProof()
8190
return proof, nil
8291
}
92+
93+
func (s *BridgeService) GetProofByL1InfoTreeIndex(depositNetwork, depositCount uint32, l1InfoTreeIndex uint32) (*bridge_service.Proof, error) {
94+
return nil, fmt.Errorf("GetProofByL1InfoTreeIndex is not supported in the legacy bridge service")
95+
}

cmd/ulxly/ulxly.go

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ func claimAsset(cmd *cobra.Command) error {
904904
depositNetwork := inputUlxlyArgs.depositNetwork
905905
globalIndexOverride := inputUlxlyArgs.globalIndex
906906
proofGERHash := inputUlxlyArgs.proofGER
907+
proofL1InfoTreeIndex := inputUlxlyArgs.proofL1InfoTreeIndex
907908
wait := inputUlxlyArgs.wait
908909

909910
// Dial Ethereum client
@@ -933,7 +934,7 @@ func claimAsset(cmd *cobra.Command) error {
933934
deposit.GlobalIndex.SetString(globalIndexOverride, 10)
934935
}
935936

936-
proof, err := getMerkleProofsExitRoots(bridgeService, *deposit, proofGERHash)
937+
proof, err := getMerkleProofsExitRoots(bridgeService, *deposit, proofGERHash, proofL1InfoTreeIndex)
937938
if err != nil {
938939
log.Error().Err(err).Msg("error getting merkle proofs and exit roots from bridge service")
939940
return err
@@ -959,6 +960,7 @@ func claimMessage(cmd *cobra.Command) error {
959960
depositNetwork := inputUlxlyArgs.depositNetwork
960961
globalIndexOverride := inputUlxlyArgs.globalIndex
961962
proofGERHash := inputUlxlyArgs.proofGER
963+
proofL1InfoTreeIndex := inputUlxlyArgs.proofL1InfoTreeIndex
962964
wait := inputUlxlyArgs.wait
963965

964966
// Dial Ethereum client
@@ -988,7 +990,7 @@ func claimMessage(cmd *cobra.Command) error {
988990
deposit.GlobalIndex.SetString(globalIndexOverride, 10)
989991
}
990992

991-
proof, err := getMerkleProofsExitRoots(bridgeService, *deposit, proofGERHash)
993+
proof, err := getMerkleProofsExitRoots(bridgeService, *deposit, proofGERHash, proofL1InfoTreeIndex)
992994
if err != nil {
993995
log.Error().Err(err).Msg("error getting merkle proofs and exit roots from bridge service")
994996
return err
@@ -1242,7 +1244,7 @@ func claimSingleDeposit(cmd *cobra.Command, client *ethclient.Client, bridgeCont
12421244
return nil, fmt.Errorf("we don't have a bridge service url for network: %d", deposit.DestNet)
12431245
}
12441246

1245-
proof, err := getMerkleProofsExitRoots(bridgeServiceFromMap, deposit, "")
1247+
proof, err := getMerkleProofsExitRoots(bridgeServiceFromMap, deposit, "", 0)
12461248
if err != nil {
12471249
log.Error().Err(err).Msg("error getting merkle proofs and exit roots from bridge service")
12481250
return nil, err
@@ -1798,14 +1800,22 @@ func generateTransactionPayload(ctx context.Context, client *ethclient.Client, u
17981800
return bridgeV2, toAddress, opts, err
17991801
}
18001802

1801-
func getMerkleProofsExitRoots(bridgeService bridge_service.BridgeService, deposit bridge_service.Deposit, proofGERHash string) (*bridge_service.Proof, error) {
1803+
func getMerkleProofsExitRoots(bridgeService bridge_service.BridgeService, deposit bridge_service.Deposit, proofGERHash string, l1InfoTreeIndex uint32) (*bridge_service.Proof, error) {
18021804
var ger *common.Hash
18031805
if len(proofGERHash) > 0 {
18041806
hash := common.HexToHash(proofGERHash)
18051807
ger = &hash
18061808
}
18071809

1808-
proof, err := bridgeService.GetProof(deposit.NetworkID, deposit.DepositCnt, ger)
1810+
var proof *bridge_service.Proof
1811+
var err error
1812+
if ger != nil {
1813+
proof, err = bridgeService.GetProofByGer(deposit.NetworkID, deposit.DepositCnt, *ger)
1814+
} else if l1InfoTreeIndex > 0 {
1815+
proof, err = bridgeService.GetProofByL1InfoTreeIndex(deposit.NetworkID, deposit.DepositCnt, l1InfoTreeIndex)
1816+
} else {
1817+
proof, err = bridgeService.GetProof(deposit.NetworkID, deposit.DepositCnt)
1818+
}
18091819
if err != nil {
18101820
return nil, fmt.Errorf("error getting proof for deposit %d on network %d: %w", deposit.DepositCnt, deposit.NetworkID, err)
18111821
}
@@ -2001,34 +2011,35 @@ var ulxlyClaimCmd = &cobra.Command{
20012011
}
20022012

20032013
type ulxlyArgs struct {
2004-
gasLimit uint64
2005-
chainID string
2006-
privateKey string
2007-
addressOfPrivateKey string
2008-
value string
2009-
rpcURL string
2010-
bridgeAddress string
2011-
destNetwork uint32
2012-
destAddress string
2013-
tokenAddress string
2014-
forceUpdate bool
2015-
callData string
2016-
callDataFile string
2017-
timeout uint64
2018-
depositCount uint32
2019-
depositNetwork uint32
2020-
bridgeServiceURL string
2021-
globalIndex string
2022-
gasPrice string
2023-
dryRun bool
2024-
bridgeServiceURLs []string
2025-
bridgeLimit int
2026-
bridgeOffset int
2027-
wait time.Duration
2028-
concurrency uint
2029-
insecure bool
2030-
legacy bool
2031-
proofGER string
2014+
gasLimit uint64
2015+
chainID string
2016+
privateKey string
2017+
addressOfPrivateKey string
2018+
value string
2019+
rpcURL string
2020+
bridgeAddress string
2021+
destNetwork uint32
2022+
destAddress string
2023+
tokenAddress string
2024+
forceUpdate bool
2025+
callData string
2026+
callDataFile string
2027+
timeout uint64
2028+
depositCount uint32
2029+
depositNetwork uint32
2030+
bridgeServiceURL string
2031+
globalIndex string
2032+
gasPrice string
2033+
dryRun bool
2034+
bridgeServiceURLs []string
2035+
bridgeLimit int
2036+
bridgeOffset int
2037+
wait time.Duration
2038+
concurrency uint
2039+
insecure bool
2040+
legacy bool
2041+
proofGER string
2042+
proofL1InfoTreeIndex uint32
20322043
}
20332044

20342045
var inputUlxlyArgs = ulxlyArgs{}
@@ -2098,6 +2109,7 @@ const (
20982109
ArgInsecure = "insecure"
20992110
ArgLegacy = "legacy"
21002111
ArgProofGER = "proof-ger"
2112+
ArgProofL1InfoTreeIndex = "proof-l1-info-tree-index"
21012113
)
21022114

21032115
var (
@@ -2491,9 +2503,11 @@ or if it's actually an intermediate hash.`,
24912503
fClaim.StringVar(&inputUlxlyArgs.globalIndex, ArgGlobalIndex, "", "an override of the global index value")
24922504
fClaim.DurationVar(&inputUlxlyArgs.wait, ArgWait, time.Duration(0), "retry claiming until deposit is ready, up to specified duration (available for claim asset and claim message)")
24932505
fClaim.StringVar(&inputUlxlyArgs.proofGER, ArgProofGER, "", "if specified and using legacy mode, the proof will be generated against this GER")
2506+
fClaim.Uint32Var(&inputUlxlyArgs.proofL1InfoTreeIndex, ArgProofL1InfoTreeIndex, 0, "if specified and using aggkit mode, the proof will be generated against this L1 Info Tree Index")
24942507
fatalIfError(ulxlyClaimCmd.MarkPersistentFlagRequired(ArgDepositCount))
24952508
fatalIfError(ulxlyClaimCmd.MarkPersistentFlagRequired(ArgDepositNetwork))
24962509
fatalIfError(ulxlyClaimCmd.MarkPersistentFlagRequired(ArgBridgeServiceURL))
2510+
ulxlyClaimCmd.MarkFlagsMutuallyExclusive(ArgProofGER, ArgProofL1InfoTreeIndex)
24972511

24982512
// Claim Everything Helper Command
24992513
fClaimEverything := claimEverythingCommand.Flags()

doc/polycli_fund.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,24 @@ $ cast balance 0x5D8121cf716B70d3e345adB58157752304eED5C3
8484
## Flags
8585
8686
```bash
87-
--addresses strings comma-separated list of wallet addresses to fund
88-
--contract-address string address of pre-deployed Funder contract
89-
--eth-amount big.Int amount of wei to send to each wallet (default 50000000000000000)
90-
-f, --file string output JSON file path for storing addresses and private keys of funded wallets (default "wallets.json")
91-
--hd-derivation derive wallets to fund from private key in deterministic way (default true)
92-
-h, --help help for fund
93-
--key-file string file containing accounts private keys, one per line
94-
-n, --number uint number of wallets to fund (default 10)
95-
--private-key string hex encoded private key to use for sending transactions (default "0x42b6e34dc21598a807dc19d7784c71b2a7a01f6480dc6f58258f78e539f1a1fa")
96-
-r, --rpc-url string RPC endpoint URL (default "http://localhost:8545")
97-
--seed string seed string for deterministic wallet generation (e.g., 'ephemeral_test')
87+
--addresses strings comma-separated list of wallet addresses to fund
88+
--approve-amount big.Int amount of ERC20 tokens to approve for the spender (default 1000000000000000000000)
89+
--approve-spender string address to approve for spending tokens from each funded wallet
90+
--erc20-bulk-funder-address string address of pre-deployed ERC20BulkFunder contract
91+
--eth-amount big.Int amount of wei to send to each wallet (default 50000000000000000)
92+
-f, --file string output JSON file path for storing addresses and private keys of funded wallets (default "wallets.json")
93+
--funder-address string address of pre-deployed funder contract
94+
--hd-derivation derive wallets to fund from private key in deterministic way (default true)
95+
-h, --help help for fund
96+
--key-file string file containing accounts private keys, one per line
97+
--multicall3-address string address of pre-deployed multicall3 contract
98+
-n, --number uint number of wallets to fund (default 10)
99+
--private-key string hex encoded private key to use for sending transactions (default "0x42b6e34dc21598a807dc19d7784c71b2a7a01f6480dc6f58258f78e539f1a1fa")
100+
--rate-limit float requests per second limit (use negative value to remove limit) (default 4)
101+
-r, --rpc-url string RPC endpoint URL (default "http://localhost:8545")
102+
--seed string seed string for deterministic wallet generation (e.g., 'ephemeral_test')
103+
--token-address string address of the ERC20 token contract to mint and fund (if provided, enables ERC20 mode)
104+
--token-amount big.Int amount of ERC20 tokens to mint and transfer to each wallet (default 1000000000000000000)
98105
```
99106
100107
The command also inherits flags from parent commands.

doc/polycli_ulxly_claim.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ Commands for claiming deposits on a particular chain.
1616
## Flags
1717

1818
```bash
19-
--bridge-service-url string URL of the bridge service
20-
--deposit-count uint32 deposit count of the bridge transaction
21-
--deposit-network uint32 rollup ID of the network where the deposit was made
22-
--global-index string an override of the global index value
23-
-h, --help help for claim
24-
--proof-ger string if specified and using legacy mode, the proof will be generated against this GER
25-
--wait duration retry claiming until deposit is ready, up to specified duration (available for claim asset and claim message)
19+
--bridge-service-url string URL of the bridge service
20+
--deposit-count uint32 deposit count of the bridge transaction
21+
--deposit-network uint32 rollup ID of the network where the deposit was made
22+
--global-index string an override of the global index value
23+
-h, --help help for claim
24+
--proof-ger string if specified and using legacy mode, the proof will be generated against this GER
25+
--proof-l1-info-tree-index uint32 if specified and using aggkit mode, the proof will be generated against this L1 Info Tree Index
26+
--wait duration retry claiming until deposit is ready, up to specified duration (available for claim asset and claim message)
2627
```
2728
2829
The command also inherits flags from parent commands.

doc/polycli_ulxly_claim_asset.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ The command also inherits flags from parent commands.
124124
--pretty-logs output logs in pretty format instead of JSON (default true)
125125
--private-key string hex encoded private key for sending transaction
126126
--proof-ger string if specified and using legacy mode, the proof will be generated against this GER
127+
--proof-l1-info-tree-index uint32 if specified and using aggkit mode, the proof will be generated against this L1 Info Tree Index
127128
--rpc-url string RPC URL to send the transaction
128129
--transaction-receipt-timeout uint timeout in seconds to wait for transaction receipt confirmation (default 60)
129130
-v, --verbosity string log level (string or int):

0 commit comments

Comments
 (0)