diff --git a/tx/textual/internal/testdata/bytes.json b/tx/textual/internal/testdata/bytes.json new file mode 100644 index 0000000000..0080bd5a49 --- /dev/null +++ b/tx/textual/internal/testdata/bytes.json @@ -0,0 +1,10 @@ +[ + ["", ""], + ["00", "AA=="], + ["66", "Zg=="], + ["666F", "Zm8="], + ["666F6F", "Zm9v"], + ["666F6F62", "Zm9vYg=="], + ["666F6F6261", "Zm9vYmE="], + ["666F6F626172", "Zm9vYmFy"] + ] \ No newline at end of file diff --git a/tx/textual/internal/testpb/1.proto b/tx/textual/internal/testpb/1.proto index 74da9b82dc..8501cc06c6 100644 --- a/tx/textual/internal/testpb/1.proto +++ b/tx/textual/internal/testpb/1.proto @@ -21,6 +21,7 @@ message A { string SDKDEC = 6 [(cosmos_proto.scalar) = "cosmos.Dec"]; cosmos.base.v1beta1.Coin COIN = 7; repeated cosmos.base.v1beta1.Coin COINS = 8; + bytes BYTES = 9; } // B contains fields that are not parseable by SIGN_MODE_TEXTUAL, some fields diff --git a/tx/textual/internal/testpb/1.pulsar.go b/tx/textual/internal/testpb/1.pulsar.go index 78ad4b16aa..50aab3696f 100644 --- a/tx/textual/internal/testpb/1.pulsar.go +++ b/tx/textual/internal/testpb/1.pulsar.go @@ -79,6 +79,7 @@ var ( fd_A_SDKDEC protoreflect.FieldDescriptor fd_A_COIN protoreflect.FieldDescriptor fd_A_COINS protoreflect.FieldDescriptor + fd_A_BYTES protoreflect.FieldDescriptor ) func init() { @@ -92,6 +93,7 @@ func init() { fd_A_SDKDEC = md_A.Fields().ByName("SDKDEC") fd_A_COIN = md_A.Fields().ByName("COIN") fd_A_COINS = md_A.Fields().ByName("COINS") + fd_A_BYTES = md_A.Fields().ByName("BYTES") } var _ protoreflect.Message = (*fastReflection_A)(nil) @@ -207,6 +209,12 @@ func (x *fastReflection_A) Range(f func(protoreflect.FieldDescriptor, protorefle return } } + if len(x.BYTES) != 0 { + value := protoreflect.ValueOfBytes(x.BYTES) + if !f(fd_A_BYTES, value) { + return + } + } } // Has reports whether a field is populated. @@ -238,6 +246,8 @@ func (x *fastReflection_A) Has(fd protoreflect.FieldDescriptor) bool { return x.COIN != nil case "A.COINS": return len(x.COINS) != 0 + case "A.BYTES": + return len(x.BYTES) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -270,6 +280,8 @@ func (x *fastReflection_A) Clear(fd protoreflect.FieldDescriptor) { x.COIN = nil case "A.COINS": x.COINS = nil + case "A.BYTES": + x.BYTES = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -313,6 +325,9 @@ func (x *fastReflection_A) Get(descriptor protoreflect.FieldDescriptor) protoref } listValue := &_A_8_list{list: &x.COINS} return protoreflect.ValueOfList(listValue) + case "A.BYTES": + value := x.BYTES + return protoreflect.ValueOfBytes(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -351,6 +366,8 @@ func (x *fastReflection_A) Set(fd protoreflect.FieldDescriptor, value protorefle lv := value.List() clv := lv.(*_A_8_list) x.COINS = *clv.list + case "A.BYTES": + x.BYTES = value.Bytes() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -394,6 +411,8 @@ func (x *fastReflection_A) Mutable(fd protoreflect.FieldDescriptor) protoreflect panic(fmt.Errorf("field SDKINT of message A is not mutable")) case "A.SDKDEC": panic(fmt.Errorf("field SDKDEC of message A is not mutable")) + case "A.BYTES": + panic(fmt.Errorf("field BYTES of message A is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -425,6 +444,8 @@ func (x *fastReflection_A) NewField(fd protoreflect.FieldDescriptor) protoreflec case "A.COINS": list := []*v1beta1.Coin{} return protoreflect.ValueOfList(&_A_8_list{list: &list}) + case "A.BYTES": + return protoreflect.ValueOfBytes(nil) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: A")) @@ -524,6 +545,10 @@ func (x *fastReflection_A) ProtoMethods() *protoiface.Methods { n += 1 + l + runtime.Sov(uint64(l)) } } + l = len(x.BYTES) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -553,6 +578,13 @@ func (x *fastReflection_A) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.BYTES) > 0 { + i -= len(x.BYTES) + copy(dAtA[i:], x.BYTES) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.BYTES))) + i-- + dAtA[i] = 0x4a + } if len(x.COINS) > 0 { for iNdEx := len(x.COINS) - 1; iNdEx >= 0; iNdEx-- { encoded, err := options.Marshal(x.COINS[iNdEx]) @@ -876,6 +908,40 @@ func (x *fastReflection_A) ProtoMethods() *protoiface.Methods { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err } iNdEx = postIndex + case 9: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field BYTES", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.BYTES = append(x.BYTES[:0], dAtA[iNdEx:postIndex]...) + if x.BYTES == nil { + x.BYTES = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -2104,6 +2170,7 @@ type A struct { SDKDEC string `protobuf:"bytes,6,opt,name=SDKDEC,proto3" json:"SDKDEC,omitempty"` COIN *v1beta1.Coin `protobuf:"bytes,7,opt,name=COIN,proto3" json:"COIN,omitempty"` COINS []*v1beta1.Coin `protobuf:"bytes,8,rep,name=COINS,proto3" json:"COINS,omitempty"` + BYTES []byte `protobuf:"bytes,9,opt,name=BYTES,proto3" json:"BYTES,omitempty"` } func (x *A) Reset() { @@ -2182,6 +2249,13 @@ func (x *A) GetCOINS() []*v1beta1.Coin { return nil } +func (x *A) GetBYTES() []byte { + if x != nil { + return x.BYTES + } + return nil +} + // B contains fields that are not parseable by SIGN_MODE_TEXTUAL, some fields // may be moved to A at some point. type B struct { @@ -2308,7 +2382,7 @@ var file__1_proto_rawDesc = []byte{ 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8f, 0x02, 0x0a, 0x01, 0x41, 0x12, 0x16, 0x0a, 0x06, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x02, 0x0a, 0x01, 0x41, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x12, 0x16, 0x0a, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x12, 0x14, 0x0a, 0x05, @@ -2325,34 +2399,36 @@ var file__1_proto_rawDesc = []byte{ 0x6e, 0x52, 0x04, 0x43, 0x4f, 0x49, 0x4e, 0x12, 0x2f, 0x0a, 0x05, 0x43, 0x4f, 0x49, 0x4e, 0x53, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, - 0x6e, 0x52, 0x05, 0x43, 0x4f, 0x49, 0x4e, 0x53, 0x22, 0xd4, 0x02, 0x0a, 0x01, 0x42, 0x12, 0x14, - 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x49, - 0x4e, 0x54, 0x33, 0x32, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x53, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, - 0x49, 0x4e, 0x54, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x49, 0x4e, 0x54, - 0x36, 0x34, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x12, 0x52, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x36, 0x34, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x46, - 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x08, 0x53, 0x46, - 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, - 0x32, 0x18, 0x06, 0x20, 0x01, 0x28, 0x07, 0x52, 0x07, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, - 0x12, 0x14, 0x0a, 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x18, 0x07, 0x20, 0x01, 0x28, 0x02, 0x52, - 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, - 0x36, 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x10, 0x52, 0x08, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, - 0x36, 0x34, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x06, 0x52, 0x07, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x12, 0x16, 0x0a, 0x06, - 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x44, 0x4f, - 0x55, 0x42, 0x4c, 0x45, 0x12, 0x1d, 0x0a, 0x03, 0x4d, 0x41, 0x50, 0x18, 0x0b, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0b, 0x2e, 0x42, 0x2e, 0x4d, 0x41, 0x50, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, - 0x4d, 0x41, 0x50, 0x1a, 0x3a, 0x0a, 0x08, 0x4d, 0x41, 0x50, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x18, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x02, 0x2e, 0x42, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, - 0x1f, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x07, - 0x0a, 0x03, 0x4f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x77, 0x6f, 0x10, 0x01, - 0x42, 0x33, 0x42, 0x06, 0x31, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x27, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x74, 0x78, 0x2f, 0x74, 0x65, - 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, - 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6e, 0x52, 0x05, 0x43, 0x4f, 0x49, 0x4e, 0x53, 0x12, 0x14, 0x0a, 0x05, 0x42, 0x59, 0x54, 0x45, + 0x53, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x42, 0x59, 0x54, 0x45, 0x53, 0x22, 0xd4, + 0x02, 0x0a, 0x01, 0x42, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x49, + 0x4e, 0x54, 0x33, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x11, 0x52, 0x06, 0x53, 0x49, 0x4e, 0x54, + 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x49, 0x4e, 0x47, + 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x12, 0x52, 0x06, 0x53, 0x49, 0x4e, 0x47, 0x36, 0x34, + 0x12, 0x1a, 0x0a, 0x08, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0f, 0x52, 0x08, 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x12, 0x18, 0x0a, 0x07, + 0x46, 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x18, 0x06, 0x20, 0x01, 0x28, 0x07, 0x52, 0x07, 0x46, + 0x49, 0x58, 0x45, 0x44, 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x12, 0x1a, 0x0a, 0x08, + 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x10, 0x52, 0x08, + 0x53, 0x46, 0x49, 0x58, 0x45, 0x44, 0x36, 0x34, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x49, 0x58, 0x45, + 0x44, 0x36, 0x34, 0x18, 0x09, 0x20, 0x01, 0x28, 0x06, 0x52, 0x07, 0x46, 0x49, 0x58, 0x45, 0x44, + 0x36, 0x34, 0x12, 0x16, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x01, 0x52, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x12, 0x1d, 0x0a, 0x03, 0x4d, 0x41, + 0x50, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x42, 0x2e, 0x4d, 0x41, 0x50, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x4d, 0x41, 0x50, 0x1a, 0x3a, 0x0a, 0x08, 0x4d, 0x41, 0x50, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x02, 0x2e, 0x42, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x1f, 0x0a, 0x0b, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x07, 0x0a, + 0x03, 0x54, 0x77, 0x6f, 0x10, 0x01, 0x42, 0x33, 0x42, 0x06, 0x31, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x27, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, + 0x2f, 0x74, 0x78, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/tx/textual/internal/testpb/buf.lock b/tx/textual/internal/testpb/buf.lock index a7e9b6df8b..f5ea8b2486 100644 --- a/tx/textual/internal/testpb/buf.lock +++ b/tx/textual/internal/testpb/buf.lock @@ -4,14 +4,8 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-proto - branch: main commit: 1935555c206d4afb9e94615dfd0fad31 - digest: b1-TNqW6xj2Pjha5Uoj9a-5uOeRo4mwswKfyqMcN3I_gZ0= - create_time: 2021-12-02T22:04:00.31049Z - remote: buf.build owner: cosmos repository: gogo-proto - branch: main commit: bee5511075b7499da6178d9e4aaa628b - digest: b1-rrBIustouD-S80cVoZ_rM0qJsmei9AgbXy9GPQu6vxg= - create_time: 2021-12-02T20:01:17.069307Z diff --git a/tx/textual/valuerenderer/bytes.go b/tx/textual/valuerenderer/bytes.go new file mode 100644 index 0000000000..23ece74c94 --- /dev/null +++ b/tx/textual/valuerenderer/bytes.go @@ -0,0 +1,34 @@ +package valuerenderer + +import ( + "context" + "encoding/base64" + "io" + + "google.golang.org/protobuf/reflect/protoreflect" +) + +//bytesValueRenderer implements ValueRenderer for bytes +type bytesValueRenderer struct { +} + +var _ ValueRenderer = bytesValueRenderer{} + +func (vr bytesValueRenderer) Format(ctx context.Context, v protoreflect.Value, w io.Writer) error { + _, err := w.Write([]byte(base64.StdEncoding.EncodeToString(v.Bytes()))) + return err +} + +func (vr bytesValueRenderer) Parse(_ context.Context, r io.Reader) (protoreflect.Value, error) { + formatted, err := io.ReadAll(r) + if err != nil { + return protoreflect.ValueOfBytes([]byte{}), err + } + + data, err := base64.StdEncoding.DecodeString(string(formatted)) + if err != nil { + return protoreflect.ValueOfBytes([]byte{}), err + } + + return protoreflect.ValueOfBytes(data), nil +} diff --git a/tx/textual/valuerenderer/bytes_test.go b/tx/textual/valuerenderer/bytes_test.go new file mode 100644 index 0000000000..6356528274 --- /dev/null +++ b/tx/textual/valuerenderer/bytes_test.go @@ -0,0 +1,45 @@ +package valuerenderer_test + +import ( + "context" + "encoding/hex" + "encoding/json" + "io/ioutil" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" +) + +func TestFormatBytes(t *testing.T) { + var testcases []bytesTest + raw, err := ioutil.ReadFile("../internal/testdata/bytes.json") + require.NoError(t, err) + + err = json.Unmarshal(raw, &testcases) + require.NoError(t, err) + + for _, tc := range testcases { + data, err := hex.DecodeString(tc.hex) + require.NoError(t, err) + + r, err := valueRendererOf(data) + require.NoError(t, err) + + b := new(strings.Builder) + err = r.Format(context.Background(), protoreflect.ValueOfBytes(data), b) + require.NoError(t, err) + require.Equal(t, tc.expRes, b.String()) + } +} + +type bytesTest struct { + hex string + expRes string +} + +func (t *bytesTest) UnmarshalJSON(b []byte) error { + a := []interface{}{&t.hex, &t.expRes} + return json.Unmarshal(b, &a) +} diff --git a/tx/textual/valuerenderer/valuerenderer.go b/tx/textual/valuerenderer/valuerenderer.go index 3c51a396b8..a22e181f95 100644 --- a/tx/textual/valuerenderer/valuerenderer.go +++ b/tx/textual/valuerenderer/valuerenderer.go @@ -39,6 +39,8 @@ func (r Textual) GetValueRenderer(fd protoreflect.FieldDescriptor) (ValueRendere return vr, nil } + case fd.Kind() == protoreflect.BytesKind: + return bytesValueRenderer{}, nil // Integers case fd.Kind() == protoreflect.Uint32Kind || diff --git a/tx/textual/valuerenderer/valuerenderer_test.go b/tx/textual/valuerenderer/valuerenderer_test.go index 41924d4ed5..36b399f2b0 100644 --- a/tx/textual/valuerenderer/valuerenderer_test.go +++ b/tx/textual/valuerenderer/valuerenderer_test.go @@ -95,6 +95,7 @@ func TestGetADR050ValueRenderer(t *testing.T) { {"uint64", uint64(1), false}, {"sdk.Int", math.NewInt(1), false}, {"sdk.Dec", math.LegacyNewDec(1), false}, + {"[]byte", []byte{1}, false}, {"float32", float32(1), true}, {"float64", float64(1), true}, } @@ -128,6 +129,8 @@ func valueRendererOf(v interface{}) (valuerenderer.ValueRenderer, error) { return textual.GetValueRenderer(a.ByName(protoreflect.Name("INT32"))) case int64: return textual.GetValueRenderer(a.ByName(protoreflect.Name("INT64"))) + case []byte: + return textual.GetValueRenderer(a.ByName(protoreflect.Name("BYTES"))) case math.Int: return textual.GetValueRenderer(a.ByName(protoreflect.Name("SDKINT"))) case math.LegacyDec: