Skip to content

Commit d351043

Browse files
authored
SUI - fix ExtraData parsing (LOOP) (#21796)
* SUI - fix ExtraData parsing (LOOP) * Add test * Fix destgasamount parsing
1 parent 8174693 commit d351043

4 files changed

Lines changed: 104 additions & 16 deletions

File tree

core/capabilities/ccip/ccipaptos/msghasher.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ func parseExtraDataMap(input map[string]any) (*big.Int, error) {
298298
lowercase := strings.ToLower(fieldName)
299299
switch lowercase {
300300
case "gaslimit":
301-
// Expect [][32]byte
302301
if val, ok := fieldValue.(*big.Int); ok {
303302
outputGas = val
304303
return outputGas, nil

core/capabilities/ccip/ccipsui/msghasher.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"math"
78
"math/big"
89
"strings"
910

@@ -71,13 +72,8 @@ func (h *MessageHasherV1) Hash(ctx context.Context, msg ccipocr3common.Message)
7172
return [32]byte{}, fmt.Errorf("failed to decode dest exec data: %w", err)
7273
}
7374

74-
destGasAmountValue, ok := destExecDataDecodedMap["destGasAmount"]
75-
if !ok {
76-
return [32]byte{}, errors.New("destGasAmount not found in destExecDataDecodedMap")
77-
}
78-
79-
destGasAmount, ok := destGasAmountValue.(uint32)
80-
if !ok {
75+
destGasAmount, err := extractDestGasAmountFromMap(destExecDataDecodedMap)
76+
if err != nil {
8177
return [32]byte{}, fmt.Errorf("invalid type for destGasAmount, expected uint32, got %T", destGasAmount)
8278
}
8379

@@ -306,10 +302,20 @@ func parseExtraDataMap(input map[string]any) (*big.Int, [32]byte, error) {
306302
if !ok {
307303
return nil, [32]byte{}, errors.New("token receiver not found in extra data map")
308304
}
309-
tokenReceiverBytes, ok := tokenReceiver.([32]byte)
310-
if !ok {
311-
return nil, [32]byte{}, errors.New("token receiver not a [32]byte")
305+
306+
tokenReceiverBytes := [32]byte{}
307+
switch v := tokenReceiver.(type) {
308+
case [32]byte:
309+
tokenReceiverBytes = v
310+
case []byte: // LOOP gRPC converts [32]byte -> []byte
311+
if len(v) != 32 {
312+
return nil, [32]byte{}, fmt.Errorf("invalid length for TokenReceiver: expected 32, got %d", len(v))
313+
}
314+
copy(tokenReceiverBytes[:], v)
315+
default:
316+
return nil, [32]byte{}, fmt.Errorf("invalid type for TokenReceiver, expected [32]byte, got %T", tokenReceiver)
312317
}
318+
313319
return outputGasInt, tokenReceiverBytes, nil
314320
}
315321

@@ -319,11 +325,17 @@ func extractDestGasAmountFromMap(input map[string]any) (uint32, error) {
319325
lowercase := strings.ToLower(fieldName)
320326
switch lowercase {
321327
case "destgasamount":
322-
// Expect uint32
323-
if val, ok := fieldValue.(uint32); ok {
324-
return val, nil
328+
switch v := fieldValue.(type) {
329+
case uint32:
330+
return v, nil
331+
case int64: // LOOP converts expected uint32 to int64
332+
if v > math.MaxUint32 {
333+
return 0, fmt.Errorf("destGasAmount exceeds uint32 max, got %d", v)
334+
}
335+
return uint32(v), nil //nolint:gosec // G115: validated to be within uint32 max above
336+
default:
337+
return 0, errors.New("invalid type for destgasamount, expected uint32 or int64")
325338
}
326-
return 0, errors.New("invalid type for destgasamount, expected uint32")
327339
default:
328340
}
329341
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package ccipsui
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestParseExtraDataMap(t *testing.T) {
12+
tokenReceiverExample := [32]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}
13+
14+
tests := []struct {
15+
name string
16+
input map[string]any
17+
want *struct {
18+
gasLimit *big.Int
19+
tokenReceiver [32]byte
20+
}
21+
expectErr bool
22+
}{
23+
{
24+
name: "valid input with [32]byte for tokenReceiver",
25+
input: map[string]any{
26+
"gasLimit": new(big.Int).SetInt64(500000),
27+
"tokenReceiver": [32]byte{0x01},
28+
},
29+
want: &struct {
30+
gasLimit *big.Int
31+
tokenReceiver [32]byte
32+
}{
33+
gasLimit: new(big.Int).SetInt64(500000),
34+
tokenReceiver: [32]byte{0x01},
35+
},
36+
expectErr: false,
37+
},
38+
{
39+
name: "valid input with []byte for tokenReceiver",
40+
input: map[string]any{
41+
"gasLimit": new(big.Int).SetInt64(500000),
42+
"tokenReceiver": tokenReceiverExample[:], // convert to slice for input
43+
},
44+
want: &struct {
45+
gasLimit *big.Int
46+
tokenReceiver [32]byte
47+
}{
48+
gasLimit: new(big.Int).SetInt64(500000),
49+
tokenReceiver: tokenReceiverExample,
50+
},
51+
expectErr: false,
52+
},
53+
{
54+
name: "invalid input with []byte for tokenReceiver",
55+
input: map[string]any{
56+
"gasLimit": new(big.Int).SetInt64(500000),
57+
"tokenReceiver": tokenReceiverExample[:16], // 16 bytes, we expect an error due to length
58+
},
59+
want: nil,
60+
expectErr: true,
61+
},
62+
}
63+
64+
// Run tests
65+
for _, tt := range tests {
66+
t.Run(tt.name, func(t *testing.T) {
67+
gasLimit, tokenReceiver, err := parseExtraDataMap(tt.input)
68+
if tt.expectErr {
69+
require.Error(t, err)
70+
} else {
71+
require.NoError(t, err)
72+
assert.Equal(t, tt.want.gasLimit, gasLimit)
73+
assert.Equal(t, tt.want.tokenReceiver, tokenReceiver)
74+
}
75+
})
76+
}
77+
}

deployment/ccip/shared/stateview/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,10 @@ func (c CCIPOnChainState) SupportedChains() map[uint64]struct{} {
539539
for chain := range c.SuiChains {
540540
chains[chain] = struct{}{}
541541
}
542-
543542
for chain := range c.TonChains {
544543
chains[chain] = struct{}{}
545544
}
545+
546546
return chains
547547
}
548548

0 commit comments

Comments
 (0)