44 "bytes"
55 "errors"
66 "fmt"
7+ "io"
78 "math/big"
89 "reflect"
910 "strings"
@@ -28,7 +29,7 @@ func DeserializeBCS(data []byte, moveTypes []string) ([]any, error) {
2829 deserializer := mystenbcs .NewDecoder (reader )
2930 ret := make ([]any , 0 , len (moveTypes ))
3031 for _ , moveType := range moveTypes {
31- decoded , _ , err := bcsDeserializeType (deserializer , moveType )
32+ decoded , _ , err := bcsDeserializeType (reader , deserializer , moveType )
3233 if err != nil {
3334 return ret , err
3435 }
@@ -41,11 +42,7 @@ func DeserializeBCS(data []byte, moveTypes []string) ([]any, error) {
4142 return ret , nil
4243}
4344
44- func bcsDeserializeType (deserializer * mystenbcs.Decoder , moveType string ) (any , reflect.Type , error ) {
45- if _ , ok := bcsStructDecoders [moveType ]; ok {
46- return nil , nil , fmt .Errorf ("struct decoder path not supported in DeserializeBCS for type %s" , moveType )
47- }
48-
45+ func bcsDeserializeType (reader io.Reader , deserializer * mystenbcs.Decoder , moveType string ) (any , reflect.Type , error ) {
4946 switch {
5047 case moveType == "bool" :
5148 var res bool
@@ -72,15 +69,16 @@ func bcsDeserializeType(deserializer *mystenbcs.Decoder, moveType string) (any,
7269 typ , err := bcsDecode (deserializer , & res )
7370 return res , typ , err
7471 case strings .HasPrefix (moveType , "vector<" ) && strings .HasSuffix (moveType , ">" ):
75- return bcsDeserializeSlice (deserializer , moveType )
72+ return bcsDeserializeSlice (reader , deserializer , moveType )
7673 case moveType == "address" :
7774 return bcsDeserializeAddress (deserializer )
7875 case moveType == "u128" :
7976 return bcsDeserializeBigInt (deserializer , moveType , 16 )
8077 case moveType == "u256" :
8178 return bcsDeserializeBigInt (deserializer , moveType , 32 )
8279 default :
83- return nil , nil , fmt .Errorf ("unsupported type for BCS deserialization: %s" , moveType )
80+ // custom move structs are decoded by their IDs
81+ return bcsDeserializeAddress (deserializer )
8482 }
8583}
8684
@@ -91,17 +89,28 @@ func bcsDecode(deserializer *mystenbcs.Decoder, target any) (reflect.Type, error
9189 return reflect .TypeOf (target ).Elem (), nil
9290}
9391
94- func bcsDeserializeSlice (deserializer * mystenbcs.Decoder , moveType string ) (any , reflect.Type , error ) {
92+ func bcsDeserializeSlice (reader io. Reader , deserializer * mystenbcs.Decoder , moveType string ) (any , reflect.Type , error ) {
9593 innerType := moveType [len ("vector<" ) : len (moveType )- 1 ]
96- var length uint64
97- if _ , err := deserializer .Decode (& length ); err != nil {
94+
95+ // vector<u8> uses ULEB128 length + raw bytes; mystenbcs handles this natively.
96+ if innerType == "u8" {
97+ var res []byte
98+ typ , err := bcsDecode (deserializer , & res )
99+ return res , typ , err
100+ }
101+
102+ length , _ , err := mystenbcs.ULEB128Decode [uint64 ](reader )
103+ if err != nil {
98104 return nil , nil , fmt .Errorf ("failed to decode vector length: %w" , err )
99105 }
106+ if length > uint64 (^ uint (0 )>> 1 ) {
107+ return nil , nil , fmt .Errorf ("vector length %d out of range" , length )
108+ }
100109
101110 elements := make ([]any , length )
102111 var elemType reflect.Type
103112 for i := uint64 (0 ); i < length ; i ++ {
104- dec , refT , err := bcsDeserializeType (deserializer , innerType )
113+ dec , refT , err := bcsDeserializeType (reader , deserializer , innerType )
105114 if err != nil {
106115 return nil , nil , err
107116 }
0 commit comments