Skip to content

Commit 7660ce0

Browse files
committed
fix edge case. If claim isMessage
1 parent fb56c63 commit 7660ce0

File tree

6 files changed

+106
-13
lines changed

6 files changed

+106
-13
lines changed

cmd/ulxly/balanceTreeUsage.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ Example usage:
77
polycli ulxly compute-balance-tree \
88
--l2-claims-file l2-claims-0-to-11454081.ndjson \
99
--l2-deposits-file l2-deposits-0-to-11454081.ndjson \
10-
--l2-network-id 3 | jq '.'
10+
--l2-network-id 3
11+
--bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 \
12+
--rpc-url http://localhost:8213 | jq '.'
1113
```
1214

1315
In this case we are assuming we have two files

cmd/ulxly/balanceandnullifiertreehelper.go

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package ulxly
22

33
import (
4+
"bytes"
45
"fmt"
56
"math/big"
67
"strings"
78

9+
"github.com/0xPolygon/cdk-rpc/types"
810
"github.com/ethereum/go-ethereum/common"
911
"github.com/ethereum/go-ethereum/crypto"
12+
"github.com/ethereum/go-ethereum/ethclient"
13+
"github.com/golang-collections/collections/stack"
1014
"github.com/rs/zerolog/log"
1115
)
1216

@@ -40,10 +44,10 @@ func (t *TokenInfo) ToBits() []bool {
4044
}
4145

4246
func (t *TokenInfo) String() string {
43-
return fmt.Sprintf("%s-%s", t.OriginNetwork.String(), t.OriginTokenAddress.Hex())
47+
return fmt.Sprintf("%s-%s", t.OriginNetwork.String(), t.OriginTokenAddress.Hex())
4448
}
4549

46-
func TokenInfoStringToStruct(key string) (TokenInfo, error){
50+
func TokenInfoStringToStruct(key string) (TokenInfo, error) {
4751
parts := strings.Split(key, "-")
4852
if len(parts) != 2 {
4953
return TokenInfo{}, fmt.Errorf("invalid key format: %s", key)
@@ -102,7 +106,7 @@ func NewBalanceTree() (*Balancer, error) {
102106
var depth uint8 = 192
103107
zeroHashes := generateZeroHashes(depth)
104108
initRoot := crypto.Keccak256Hash(zeroHashes[depth-1].Bytes(), zeroHashes[depth-1].Bytes())
105-
log.Info().Msg("Initial Root: "+ initRoot.String())
109+
log.Info().Msg("Initial Root: " + initRoot.String())
106110
return &Balancer{
107111
tree: Tree{
108112
zeroHashes: zeroHashes,
@@ -132,7 +136,7 @@ func NewNullifierTree() (*Nullifier, error) {
132136
var depth uint8 = 64
133137
zeroHashes := generateZeroHashes(depth)
134138
initRoot := crypto.Keccak256Hash(zeroHashes[depth-1].Bytes(), zeroHashes[depth-1].Bytes())
135-
log.Info().Msg("Initial Root: "+ initRoot.String())
139+
log.Info().Msg("Initial Root: " + initRoot.String())
136140
return &Nullifier{
137141
tree: Tree{
138142
zeroHashes: zeroHashes,
@@ -226,3 +230,62 @@ func (t *Tree) insertHelper(
226230

227231
return newHash, nil
228232
}
233+
234+
var methodIDClaimMessage = common.Hex2Bytes("f5efcd79")
235+
236+
func IsMessageClaim(input []byte) (bool, error) {
237+
methodID := input[:4]
238+
// Ignore ClaimAsset method
239+
if bytes.Equal(methodID, methodIDClaimMessage) {
240+
return true, nil
241+
} else {
242+
return false, nil
243+
}
244+
}
245+
246+
type call struct {
247+
To common.Address `json:"to"`
248+
Value *types.ArgBig `json:"value"`
249+
Err *string `json:"error"`
250+
Input types.ArgBytes `json:"input"`
251+
Calls []call `json:"calls"`
252+
}
253+
254+
type tracerCfg struct {
255+
Tracer string `json:"tracer"`
256+
}
257+
258+
func checkClaimCalldata(client *ethclient.Client, bridge common.Address, claimHash common.Hash) (bool, error) {
259+
c := &call{}
260+
err := client.Client().Call(c, "debug_traceTransaction", claimHash, tracerCfg{Tracer: "callTracer"})
261+
if err != nil {
262+
return false, err
263+
}
264+
265+
// find the claim linked to the event using DFS
266+
callStack := stack.New()
267+
callStack.Push(*c)
268+
for {
269+
if callStack.Len() == 0 {
270+
break
271+
}
272+
273+
currentCallInterface := callStack.Pop()
274+
currentCall, ok := currentCallInterface.(call)
275+
if !ok {
276+
return false, fmt.Errorf("unexpected type for 'currentCall'. Expected 'call', got '%T'", currentCallInterface)
277+
}
278+
279+
if currentCall.To == bridge {
280+
isMessage, err := IsMessageClaim(currentCall.Input)
281+
if err != nil {
282+
return false, err
283+
}
284+
return isMessage, err
285+
}
286+
for _, c := range currentCall.Calls {
287+
callStack.Push(c)
288+
}
289+
}
290+
return false, fmt.Errorf("claim not found")
291+
}

cmd/ulxly/nullifierAndBalanceTreeUsage.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ Example usage:
77
polycli ulxly compute-balance-nullifier-tree \
88
--l2-claim-file l2-claim-0-to-11454081.ndjson \
99
--l2-deposits-file l2-deposits-0-to-11454081.ndjson \
10-
--l2-network-id 3 | jq '.'
10+
--l2-network-id 3
11+
--bridge-address 0x528e26b25a34a4A5d0dbDa1d57D318153d2ED582 \
12+
--rpc-url http://localhost:8213 | jq '.'
1113
```
1214

1315
In this case we are assuming we have two files

cmd/ulxly/ulxly.go

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,16 @@ func proof(args []string) error {
319319

320320
func balanceTree() error {
321321
l2NetworkID := balanceTreeOptions.L2NetworkID
322+
bridgeAddress := common.HexToAddress(balanceTreeOptions.BridgeAddress)
323+
client, err := ethclient.DialContext(context.Background(), balanceTreeOptions.RpcURL)
324+
if err != nil {
325+
return err
326+
}
322327
l2RawClaimsData, l2RawDepositsData, err := getBalanceTreeData()
323328
if err != nil {
324329
return err
325330
}
326-
root, err := computeBalanceTree(l2RawClaimsData, l2NetworkID, l2RawDepositsData)
331+
root, err := computeBalanceTree(client, bridgeAddress, l2RawClaimsData, l2NetworkID, l2RawDepositsData)
327332
if err != nil {
328333
return err
329334
}
@@ -354,11 +359,16 @@ func nullifierTree(args []string) error {
354359

355360
func nullifierAndBalanceTree(args []string) error {
356361
l2NetworkID := balanceTreeOptions.L2NetworkID
362+
bridgeAddress := common.HexToAddress(balanceTreeOptions.BridgeAddress)
363+
client, err := ethclient.DialContext(context.Background(), balanceTreeOptions.RpcURL)
364+
if err != nil {
365+
return err
366+
}
357367
l2RawClaimsData, l2RawDepositsData, err := getBalanceTreeData()
358368
if err != nil {
359369
return err
360370
}
361-
balanceTreeRoot, err := computeBalanceTree(l2RawClaimsData, l2NetworkID, l2RawDepositsData)
371+
balanceTreeRoot, err := computeBalanceTree(client, bridgeAddress, l2RawClaimsData, l2NetworkID, l2RawDepositsData)
362372
if err != nil {
363373
return err
364374
}
@@ -405,15 +415,15 @@ func computeNullifierTree(rawClaims []byte) (common.Hash, error) {
405415
}
406416
root, err = nTree.UpdateNullifierTree(nullifierKey)
407417
if err != nil {
408-
log.Error().Err(err).Uint32("OriginNetwork: ", claim.OriginNetwork).Msg("error computing nullifierTree. Claim information: GlobalIndex: "+claim.GlobalIndex.String()+", OriginAddress: "+claim.OriginAddress.String()+", Amount: "+claim.Amount.String())
418+
log.Error().Err(err).Uint32("OriginNetwork: ", claim.OriginNetwork).Msg("error computing nullifierTree. Claim information: GlobalIndex: " + claim.GlobalIndex.String() + ", OriginAddress: " + claim.OriginAddress.String() + ", Amount: " + claim.Amount.String())
409419
return common.Hash{}, err
410420
}
411421
}
412422
log.Info().Msgf("Final nullifierTree root: %s", root.String())
413423
return root, nil
414424
}
415425

416-
func computeBalanceTree(l2RawClaims []byte, l2NetworkID uint32, l2RawDeposits []byte) (common.Hash, error) {
426+
func computeBalanceTree(client *ethclient.Client, bridgeAddress common.Address, l2RawClaims []byte, l2NetworkID uint32, l2RawDeposits []byte) (common.Hash, error) {
417427
buf := bytes.NewBuffer(l2RawClaims)
418428
scanner := bufio.NewScanner(buf)
419429
scannerBuf := make([]byte, 0)
@@ -433,7 +443,15 @@ func computeBalanceTree(l2RawClaims []byte, l2NetworkID uint32, l2RawDeposits []
433443
OriginNetwork: big.NewInt(0).SetUint64(uint64(l2Claim.OriginNetwork)),
434444
OriginTokenAddress: l2Claim.OriginAddress,
435445
}
436-
log.Info().Msgf("L2 Claim. OriginNetwork: %d. TokenAddress: %s. Amount: %s", token.OriginNetwork, token.OriginTokenAddress.String(), l2Claim.Amount.String())
446+
isMessage, err := checkClaimCalldata(client, bridgeAddress, l2Claim.Raw.TxHash)
447+
if err != nil {
448+
return common.Hash{}, err
449+
}
450+
if isMessage {
451+
token.OriginNetwork = big.NewInt(0)
452+
token.OriginTokenAddress = common.Address{}
453+
}
454+
log.Info().Msgf("L2 Claim. isMessage: %v OriginNetwork: %d. TokenAddress: %s. Amount: %s", isMessage, token.OriginNetwork, token.OriginTokenAddress.String(), l2Claim.Amount.String())
437455
if _, ok := balances[token.String()]; !ok {
438456
balances[token.String()] = big.NewInt(0)
439457
}
@@ -2017,13 +2035,15 @@ func (o *FileOptions) AddFlags(cmd *cobra.Command) {
20172035
}
20182036

20192037
type BalanceTreeOptions struct {
2020-
L2ClaimsFile, L2DepositsFile string
2021-
L2NetworkID uint32
2038+
L2ClaimsFile, L2DepositsFile, BridgeAddress, RpcURL string
2039+
L2NetworkID uint32
20222040
}
20232041

20242042
func (o *BalanceTreeOptions) AddFlags(cmd *cobra.Command) {
20252043
cmd.Flags().StringVarP(&o.L2ClaimsFile, ArgL2ClaimsFileName, "", "", "An ndjson file with l2 claim events data")
20262044
cmd.Flags().StringVarP(&o.L2DepositsFile, ArgL2DepositsFileName, "", "", "An ndjson file with l2 deposit events data")
2045+
cmd.Flags().StringVarP(&o.BridgeAddress, ArgBridgeAddress, "", "", "Bridge Address")
2046+
cmd.Flags().StringVarP(&o.RpcURL, ArgRPCURL, "r", "", "RPC URL")
20272047
cmd.Flags().Uint32VarP(&o.L2NetworkID, ArgL2NetworkID, "", 0, "The L2 networkID")
20282048
}
20292049

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ require (
163163
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
164164
cloud.google.com/go/iam v1.5.0 // indirect
165165
cloud.google.com/go/longrunning v0.6.6 // indirect
166+
github.com/0xPolygon/cdk-rpc v0.0.0-20250213125803-179882ad6229
166167
github.com/Microsoft/go-winio v0.6.2 // indirect
167168
github.com/btcsuite/btcd/btcec/v2 v2.3.4
168169
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect
@@ -179,6 +180,7 @@ require (
179180
github.com/go-logfmt/logfmt v0.6.0 // indirect
180181
github.com/go-logr/logr v1.4.2 // indirect
181182
github.com/go-logr/stdr v1.2.2 // indirect
183+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
182184
github.com/golang/glog v1.2.4 // indirect
183185
github.com/golang/protobuf v1.5.4 // indirect
184186
github.com/google/btree v1.1.3 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR
1717
cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw=
1818
github.com/0xPolygon/cdk-contracts-tooling v0.0.1 h1:2HH8KpO1CZRl1zHfn0IYwJhPA7l91DOWrjdExmaB9Kk=
1919
github.com/0xPolygon/cdk-contracts-tooling v0.0.1/go.mod h1:mFlcEjsm2YBBsu8atHJ3zyVnwM+Z/fMXpVmIJge+WVU=
20+
github.com/0xPolygon/cdk-rpc v0.0.0-20250213125803-179882ad6229 h1:6YhqNQVcXkoxqs5zQVg1bREuoeKvwpffpfoL8QQT+u4=
21+
github.com/0xPolygon/cdk-rpc v0.0.0-20250213125803-179882ad6229/go.mod h1:2scWqMMufrQXu7TikDgQ3BsyaKoX8qP26D6E262vSOg=
2022
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2123
github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY=
2224
github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
@@ -190,6 +192,8 @@ github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
190192
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
191193
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
192194
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
195+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
196+
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU=
193197
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
194198
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
195199
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=

0 commit comments

Comments
 (0)