diff --git a/ante/evm/04_validate.go b/ante/evm/04_validate.go index 6d2e10186..d7f8e632f 100644 --- a/ante/evm/04_validate.go +++ b/ante/evm/04_validate.go @@ -24,10 +24,9 @@ func ValidateMsg( txData evmtypes.TxData, from sdktypes.AccAddress, ) error { - if from != nil { - return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "invalid from address; expected nil; got: %q", from.String()) + if txData == nil { + return errorsmod.Wrap(errortypes.ErrInvalidRequest, "transaction is nil") } - return checkDisabledCreateCall( txData, &evmParams.AccessControl, diff --git a/ante/evm/05_signature_verification.go b/ante/evm/05_signature_verification.go index 674a3540b..d5490419a 100644 --- a/ante/evm/05_signature_verification.go +++ b/ante/evm/05_signature_verification.go @@ -83,16 +83,8 @@ func SignatureVerification( } } - sender, err := signer.Sender(ethTx) - if err != nil { - return errorsmod.Wrapf( - errortypes.ErrorInvalidSigner, - "couldn't retrieve sender address from the ethereum transaction: %s", - err.Error(), - ) + if err := msg.VerifySender(signer); err != nil { + return errorsmod.Wrapf(errortypes.ErrorInvalidSigner, "signature verification failed: %s", err.Error()) } - - // set up the sender to the transaction field if not already - msg.From = sender.Hex() return nil } diff --git a/ante/evm/mono_decorator.go b/ante/evm/mono_decorator.go index 3fd295b29..ccd0a3194 100644 --- a/ante/evm/mono_decorator.go +++ b/ante/evm/mono_decorator.go @@ -156,7 +156,7 @@ func (md MonoDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, ne } // 7. can transfer - coreMsg, err := ethMsg.AsMessage(decUtils.Signer, decUtils.BaseFee) + coreMsg, err := ethMsg.AsMessage(decUtils.BaseFee) if err != nil { return ctx, errorsmod.Wrapf( err, diff --git a/ante/evm/mono_decorator_test.go b/ante/evm/mono_decorator_test.go index f6c9bb02c..6be08e33a 100644 --- a/ante/evm/mono_decorator_test.go +++ b/ante/evm/mono_decorator_test.go @@ -117,10 +117,9 @@ func signMsgEthereumTx(t *testing.T, privKey *ethsecp256k1.PrivKey, args *evmsdk t.Helper() msg := evmsdktypes.NewTx(args) fromAddr := common.BytesToAddress(privKey.PubKey().Address().Bytes()) - msg.From = fromAddr.Hex() + msg.From = fromAddr.Bytes() ethSigner := ethtypes.LatestSignerForChainID(evmsdktypes.GetEthChainConfig().ChainID) require.NoError(t, msg.Sign(ethSigner, utiltx.NewSigner(privKey))) - msg.From = "" return msg } diff --git a/api/cosmos/evm/vm/v1/tx.pulsar.go b/api/cosmos/evm/vm/v1/tx.pulsar.go index fd2faebbe..904d9782c 100644 --- a/api/cosmos/evm/vm/v1/tx.pulsar.go +++ b/api/cosmos/evm/vm/v1/tx.pulsar.go @@ -21,11 +21,12 @@ import ( ) var ( - md_MsgEthereumTx protoreflect.MessageDescriptor - fd_MsgEthereumTx_data protoreflect.FieldDescriptor - fd_MsgEthereumTx_size protoreflect.FieldDescriptor - fd_MsgEthereumTx_hash protoreflect.FieldDescriptor - fd_MsgEthereumTx_from protoreflect.FieldDescriptor + md_MsgEthereumTx protoreflect.MessageDescriptor + fd_MsgEthereumTx_data protoreflect.FieldDescriptor + fd_MsgEthereumTx_size protoreflect.FieldDescriptor + fd_MsgEthereumTx_hash protoreflect.FieldDescriptor + fd_MsgEthereumTx_deprecated_from protoreflect.FieldDescriptor + fd_MsgEthereumTx_from protoreflect.FieldDescriptor ) func init() { @@ -34,6 +35,7 @@ func init() { fd_MsgEthereumTx_data = md_MsgEthereumTx.Fields().ByName("data") fd_MsgEthereumTx_size = md_MsgEthereumTx.Fields().ByName("size") fd_MsgEthereumTx_hash = md_MsgEthereumTx.Fields().ByName("hash") + fd_MsgEthereumTx_deprecated_from = md_MsgEthereumTx.Fields().ByName("deprecated_from") fd_MsgEthereumTx_from = md_MsgEthereumTx.Fields().ByName("from") } @@ -120,8 +122,14 @@ func (x *fastReflection_MsgEthereumTx) Range(f func(protoreflect.FieldDescriptor return } } - if x.From != "" { - value := protoreflect.ValueOfString(x.From) + if x.DeprecatedFrom != "" { + value := protoreflect.ValueOfString(x.DeprecatedFrom) + if !f(fd_MsgEthereumTx_deprecated_from, value) { + return + } + } + if len(x.From) != 0 { + value := protoreflect.ValueOfBytes(x.From) if !f(fd_MsgEthereumTx_from, value) { return } @@ -147,8 +155,10 @@ func (x *fastReflection_MsgEthereumTx) Has(fd protoreflect.FieldDescriptor) bool return x.Size != float64(0) || math.Signbit(x.Size) case "cosmos.evm.vm.v1.MsgEthereumTx.hash": return x.Hash != "" + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": + return x.DeprecatedFrom != "" case "cosmos.evm.vm.v1.MsgEthereumTx.from": - return x.From != "" + return len(x.From) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgEthereumTx")) @@ -171,8 +181,10 @@ func (x *fastReflection_MsgEthereumTx) Clear(fd protoreflect.FieldDescriptor) { x.Size = float64(0) case "cosmos.evm.vm.v1.MsgEthereumTx.hash": x.Hash = "" + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": + x.DeprecatedFrom = "" case "cosmos.evm.vm.v1.MsgEthereumTx.from": - x.From = "" + x.From = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgEthereumTx")) @@ -198,9 +210,12 @@ func (x *fastReflection_MsgEthereumTx) Get(descriptor protoreflect.FieldDescript case "cosmos.evm.vm.v1.MsgEthereumTx.hash": value := x.Hash return protoreflect.ValueOfString(value) + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": + value := x.DeprecatedFrom + return protoreflect.ValueOfString(value) case "cosmos.evm.vm.v1.MsgEthereumTx.from": value := x.From - return protoreflect.ValueOfString(value) + return protoreflect.ValueOfBytes(value) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgEthereumTx")) @@ -227,8 +242,10 @@ func (x *fastReflection_MsgEthereumTx) Set(fd protoreflect.FieldDescriptor, valu x.Size = value.Float() case "cosmos.evm.vm.v1.MsgEthereumTx.hash": x.Hash = value.Interface().(string) + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": + x.DeprecatedFrom = value.Interface().(string) case "cosmos.evm.vm.v1.MsgEthereumTx.from": - x.From = value.Interface().(string) + x.From = value.Bytes() default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgEthereumTx")) @@ -258,6 +275,8 @@ func (x *fastReflection_MsgEthereumTx) Mutable(fd protoreflect.FieldDescriptor) panic(fmt.Errorf("field size of message cosmos.evm.vm.v1.MsgEthereumTx is not mutable")) case "cosmos.evm.vm.v1.MsgEthereumTx.hash": panic(fmt.Errorf("field hash of message cosmos.evm.vm.v1.MsgEthereumTx is not mutable")) + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": + panic(fmt.Errorf("field deprecated_from of message cosmos.evm.vm.v1.MsgEthereumTx is not mutable")) case "cosmos.evm.vm.v1.MsgEthereumTx.from": panic(fmt.Errorf("field from of message cosmos.evm.vm.v1.MsgEthereumTx is not mutable")) default: @@ -280,8 +299,10 @@ func (x *fastReflection_MsgEthereumTx) NewField(fd protoreflect.FieldDescriptor) return protoreflect.ValueOfFloat64(float64(0)) case "cosmos.evm.vm.v1.MsgEthereumTx.hash": return protoreflect.ValueOfString("") - case "cosmos.evm.vm.v1.MsgEthereumTx.from": + case "cosmos.evm.vm.v1.MsgEthereumTx.deprecated_from": return protoreflect.ValueOfString("") + case "cosmos.evm.vm.v1.MsgEthereumTx.from": + return protoreflect.ValueOfBytes(nil) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgEthereumTx")) @@ -362,6 +383,10 @@ func (x *fastReflection_MsgEthereumTx) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } + l = len(x.DeprecatedFrom) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } l = len(x.From) if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) @@ -400,6 +425,13 @@ func (x *fastReflection_MsgEthereumTx) ProtoMethods() *protoiface.Methods { copy(dAtA[i:], x.From) i = runtime.EncodeVarint(dAtA, i, uint64(len(x.From))) i-- + dAtA[i] = 0x2a + } + if len(x.DeprecatedFrom) > 0 { + i -= len(x.DeprecatedFrom) + copy(dAtA[i:], x.DeprecatedFrom) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DeprecatedFrom))) + i-- dAtA[i] = 0x22 } if len(x.Hash) > 0 { @@ -559,7 +591,7 @@ func (x *fastReflection_MsgEthereumTx) ProtoMethods() *protoiface.Methods { iNdEx = postIndex case 4: if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DeprecatedFrom", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -587,7 +619,41 @@ func (x *fastReflection_MsgEthereumTx) ProtoMethods() *protoiface.Methods { if postIndex > l { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF } - x.From = string(dAtA[iNdEx:postIndex]) + x.DeprecatedFrom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field From", 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.From = append(x.From[:0], dAtA[iNdEx:postIndex]...) + if x.From == nil { + x.From = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex @@ -6702,10 +6768,12 @@ type MsgEthereumTx struct { Size float64 `protobuf:"fixed64,2,opt,name=size,proto3" json:"size,omitempty"` // hash of the transaction in hex format Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` - // from is the ethereum signer address in hex format. This address value is - // checked against the address derived from the signature (V, R, S) using the + // Deprecated: Do not use. + DeprecatedFrom string `protobuf:"bytes,4,opt,name=deprecated_from,json=deprecatedFrom,proto3" json:"deprecated_from,omitempty"` + // from is the bytes of ethereum signer address. This address value is checked + // against the address derived from the signature (V, R, S) using the // secp256k1 elliptic curve - From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + From []byte `protobuf:"bytes,5,opt,name=from,proto3" json:"from,omitempty"` } func (x *MsgEthereumTx) Reset() { @@ -6749,13 +6817,21 @@ func (x *MsgEthereumTx) GetHash() string { return "" } -func (x *MsgEthereumTx) GetFrom() string { +// Deprecated: Do not use. +func (x *MsgEthereumTx) GetDeprecatedFrom() string { if x != nil { - return x.From + return x.DeprecatedFrom } return "" } +func (x *MsgEthereumTx) GetFrom() []byte { + if x != nil { + return x.From + } + return nil +} + // LegacyTx is the transaction data of regular Ethereum transactions. // NOTE: All non-protected transactions (i.e non EIP155 signed) will fail if the // AllowUnprotectedTxs parameter is disabled. @@ -7400,7 +7476,7 @@ var file_cosmos_evm_vm_v1_tx_proto_rawDesc = []byte{ 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xb6, 0x01, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, + 0xe3, 0x01, 0x0a, 0x0d, 0x4d, 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x04, 0x73, @@ -7408,168 +7484,171 @@ var file_cosmos_evm_vm_v1_tx_proto_rawDesc = []byte{ 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xf2, 0xde, 0x1f, 0x07, 0x72, 0x6c, 0x70, 0x3a, 0x22, 0x2d, 0x22, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x04, 0x68, 0x61, 0x73, - 0x68, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x21, 0x88, 0xa0, 0x1f, 0x00, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x45, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x22, 0xa9, 0x02, 0x0a, 0x08, 0x4c, 0x65, 0x67, - 0x61, 0x63, 0x79, 0x54, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x67, - 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, - 0x69, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x42, 0x0c, 0xe2, 0xde, 0x1f, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, - 0x67, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x74, 0x6f, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x23, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, - 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, - 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, - 0x12, 0x0c, 0x0a, 0x01, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, - 0x0a, 0x01, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x26, 0x88, 0xa0, - 0x1f, 0x00, 0xca, 0xb4, 0x2d, 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, - 0x13, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x4c, 0x65, 0x67, 0x61, - 0x63, 0x79, 0x54, 0x78, 0x22, 0xdf, 0x03, 0x0a, 0x0c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x78, 0x12, 0x4a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, + 0x68, 0x12, 0x2b, 0x0a, 0x0f, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, + 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x3a, 0x21, 0x88, 0xa0, 0x1f, 0x00, 0x8a, 0xe7, 0xb0, 0x2a, 0x18, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x54, 0x78, 0x22, 0xa9, 0x02, 0x0a, 0x08, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, + 0x54, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, + 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, + 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, + 0x12, 0x1e, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xe2, + 0xde, 0x1f, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, 0x67, 0x61, 0x73, + 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, + 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x23, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x06, 0x41, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, + 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, 0x12, 0x0c, 0x0a, + 0x01, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x73, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x26, 0x88, 0xa0, 0x1f, 0x00, 0xca, + 0xb4, 0x2d, 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, 0x13, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x54, + 0x78, 0x22, 0xdf, 0x03, 0x0a, 0x0c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x78, 0x12, 0x4a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, + 0xde, 0x1f, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0xea, 0xde, 0x1f, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, - 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0xea, 0xde, 0x1f, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, - 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, 0x15, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, - 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, - 0x1e, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xe2, 0xde, - 0x1f, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, - 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, - 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x06, 0x41, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, - 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, - 0x25, 0xc8, 0xde, 0x1f, 0x00, 0xea, 0xde, 0x1f, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0xaa, 0xdf, 0x1f, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, - 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, 0x12, 0x0c, - 0x0a, 0x01, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, - 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x2a, 0x88, 0xa0, 0x1f, 0x00, - 0xca, 0xb4, 0x2d, 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x78, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x46, 0x65, 0x65, 0x54, 0x78, 0x12, 0x4a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0xea, - 0xde, 0x1f, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, - 0x5f, 0x74, 0x69, 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, - 0x70, 0x43, 0x61, 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, - 0x63, 0x61, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, 0x15, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, - 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, - 0x1e, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xe2, 0xde, - 0x1f, 0x08, 0x47, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, - 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, - 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, - 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, - 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x06, 0x41, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, - 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, - 0x25, 0xc8, 0xde, 0x1f, 0x00, 0xea, 0xde, 0x1f, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, - 0x69, 0x73, 0x74, 0xaa, 0xdf, 0x1f, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, - 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, 0x12, 0x0c, - 0x0a, 0x01, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, - 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x2a, 0x88, 0xa0, 0x1f, 0x00, - 0xca, 0xb4, 0x2d, 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, - 0x63, 0x46, 0x65, 0x65, 0x54, 0x78, 0x22, 0x22, 0x0a, 0x1a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x75, 0x6d, 0x54, 0x78, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0xa4, 0x01, 0x0a, 0x15, 0x4d, - 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, - 0x6f, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x6d, 0x5f, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x3a, 0x04, 0x88, 0xa0, 0x1f, - 0x00, 0x22, 0xba, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, - 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6e, 0x74, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x03, + 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xe2, 0xde, 0x1f, 0x08, 0x47, + 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x74, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x39, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xda, 0xde, 0x1f, + 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, 0x0a, 0x08, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x32, 0x82, 0xe7, 0xb0, 0x2a, - 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x1f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x4d, - 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, - 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd6, 0x01, 0x0a, 0x16, 0x4d, 0x73, - 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, - 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x0b, - 0x70, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, - 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x42, - 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x3a, 0x39, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x26, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, - 0x6c, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xdc, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x7d, 0x0a, 0x0a, - 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x1a, 0x27, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x22, 0x1d, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x2f, - 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5f, 0x74, 0x78, 0x12, 0x5c, 0x0a, 0x0c, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x29, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, 0x25, 0xc8, 0xde, + 0x1f, 0x00, 0xea, 0xde, 0x1f, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0xaa, 0xdf, 0x1f, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x0c, 0x0a, + 0x01, 0x76, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, 0x12, 0x0c, 0x0a, 0x01, 0x72, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x73, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x2a, 0x88, 0xa0, 0x1f, 0x00, 0xca, 0xb4, 0x2d, + 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x78, 0x22, 0x9d, 0x04, 0x0a, 0x0c, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x46, + 0x65, 0x65, 0x54, 0x78, 0x12, 0x4a, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x2f, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, + 0x74, 0xe2, 0xde, 0x1f, 0x07, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0xea, 0xde, 0x1f, 0x07, + 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x44, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x74, 0x69, + 0x70, 0x5f, 0x63, 0x61, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, + 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x09, 0x67, 0x61, 0x73, 0x54, 0x69, 0x70, 0x43, 0x61, + 0x70, 0x12, 0x39, 0x0a, 0x0b, 0x67, 0x61, 0x73, 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x63, 0x61, 0x70, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, + 0x74, 0x52, 0x09, 0x67, 0x61, 0x73, 0x46, 0x65, 0x65, 0x43, 0x61, 0x70, 0x12, 0x1e, 0x0a, 0x03, + 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x0c, 0xe2, 0xde, 0x1f, 0x08, 0x47, + 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x39, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x23, 0xda, 0xde, 0x1f, + 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0xe2, 0xde, 0x1f, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x60, 0x0a, 0x08, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x42, 0x25, 0xc8, 0xde, + 0x1f, 0x00, 0xea, 0xde, 0x1f, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0xaa, 0xdf, 0x1f, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0xa8, 0xe7, + 0xb0, 0x2a, 0x01, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x0c, 0x0a, + 0x01, 0x76, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x76, 0x12, 0x0c, 0x0a, 0x01, 0x72, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x73, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x01, 0x73, 0x3a, 0x2a, 0x88, 0xa0, 0x1f, 0x00, 0xca, 0xb4, 0x2d, + 0x06, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x8a, 0xe7, 0xb0, 0x2a, 0x17, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x46, 0x65, + 0x65, 0x54, 0x78, 0x22, 0x22, 0x0a, 0x1a, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, + 0x78, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0xa4, 0x01, 0x0a, 0x15, 0x4d, 0x73, 0x67, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x29, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, + 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, + 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x72, + 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x6d, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, + 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x3a, 0x04, 0x88, 0xa0, 0x1f, 0x00, 0x22, 0xba, + 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, + 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x32, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x1f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd6, 0x01, 0x0a, 0x16, 0x4d, 0x73, 0x67, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x0b, 0x70, 0x72, 0x65, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x13, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, - 0x12, 0x28, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, - 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, - 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, - 0xb0, 0x2a, 0x01, 0x42, 0xaa, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, - 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6d, 0x76, 0x31, 0xa2, - 0x02, 0x03, 0x43, 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, - 0x76, 0x6d, 0x2e, 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x43, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x56, 0x6d, 0x3a, 0x3a, 0x56, 0x31, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x31, 0x2e, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x42, 0x09, 0xc8, 0xde, + 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6c, 0x6c, 0x73, 0x3a, 0x39, 0x82, 0xe7, 0xb0, 0x2a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x26, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x22, + 0x20, 0x0a, 0x1e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, + 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x32, 0xdc, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x7d, 0x0a, 0x0a, 0x45, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, + 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x22, 0x1d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5f, 0x74, 0x78, 0x12, 0x5c, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x29, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x13, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x28, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, + 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x73, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x65, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, + 0x42, 0xaa, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, + 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, + 0x6d, 0x2f, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6d, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, + 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, + 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, + 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x56, 0x6d, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/encoding/config_test.go b/encoding/config_test.go index 39ecd38bd..5dd94d18f 100644 --- a/encoding/config_test.go +++ b/encoding/config_test.go @@ -26,7 +26,7 @@ func TestTxEncoding(t *testing.T) { Input: []byte{}, } msg := evmtypes.NewTx(ðTxParams) - msg.From = addr.Hex() + msg.From = addr.Bytes() ethSigner := ethtypes.LatestSignerForChainID(big.NewInt(1)) err := msg.Sign(ethSigner, signer) diff --git a/evmd/cmd/evmd/cmd/root.go b/evmd/cmd/evmd/cmd/root.go index 8d994543f..dc715e02d 100644 --- a/evmd/cmd/evmd/cmd/root.go +++ b/evmd/cmd/evmd/cmd/root.go @@ -35,11 +35,12 @@ import ( "github.com/cosmos/cosmos-sdk/client/pruning" "github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/snapshot" + "github.com/cosmos/cosmos-sdk/server" sdkserver "github.com/cosmos/cosmos-sdk/server" servertypes "github.com/cosmos/cosmos-sdk/server/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" - sdkmempool "github.com/cosmos/cosmos-sdk/types/mempool" + "github.com/cosmos/cosmos-sdk/types/mempool" sdktestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" "github.com/cosmos/cosmos-sdk/types/tx/signing" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" @@ -316,10 +317,19 @@ func newApp( // Set up the required mempool and ABCI proposal handlers for Cosmos EVM baseappOptions = append(baseappOptions, func(app *baseapp.BaseApp) { - mempool := sdkmempool.NoOpMempool{} - app.SetMempool(mempool) - - handler := baseapp.NewDefaultProposalHandler(mempool, app) + var mpool mempool.Mempool + if maxTxs := cast.ToInt(appOpts.Get(server.FlagMempoolMaxTxs)); maxTxs >= 0 { + // Setup Mempool and Proposal Handlers + mpool = mempool.NewPriorityMempool(mempool.PriorityNonceMempoolConfig[int64]{ + TxPriority: mempool.NewDefaultTxPriority(), + SignerExtractor: evmd.NewEthSignerExtractionAdapter(mempool.NewDefaultSignerExtractionAdapter()), + MaxTx: maxTxs, + }) + } else { + mpool = mempool.NoOpMempool{} + } + app.SetMempool(mpool) + handler := baseapp.NewDefaultProposalHandler(mpool, app) app.SetPrepareProposal(handler.PrepareProposalHandler()) app.SetProcessProposal(handler.ProcessProposalHandler()) }) diff --git a/evmd/signer.go b/evmd/signer.go new file mode 100644 index 000000000..d1c569673 --- /dev/null +++ b/evmd/signer.go @@ -0,0 +1,43 @@ +package evmd + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + mempool "github.com/cosmos/cosmos-sdk/types/mempool" + authante "github.com/cosmos/cosmos-sdk/x/auth/ante" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +var _ mempool.SignerExtractionAdapter = EthSignerExtractionAdapter{} + +// EthSignerExtractionAdapter is the default implementation of SignerExtractionAdapter. It extracts the signers +// from a cosmos-sdk tx via GetSignaturesV2. +type EthSignerExtractionAdapter struct { + fallback mempool.SignerExtractionAdapter +} + +// NewEthSignerExtractionAdapter constructs a new EthSignerExtractionAdapter instance +func NewEthSignerExtractionAdapter(fallback mempool.SignerExtractionAdapter) EthSignerExtractionAdapter { + return EthSignerExtractionAdapter{fallback} +} + +// GetSigners implements the Adapter interface +// NOTE: only the first item is used by the mempool +func (s EthSignerExtractionAdapter) GetSigners(tx sdk.Tx) ([]mempool.SignerData, error) { + if txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx); ok { + opts := txWithExtensions.GetExtensionOptions() + if len(opts) > 0 && opts[0].GetTypeUrl() == "/cosmos.evm.vm.v1.ExtensionOptionsEthereumTx" { + for _, msg := range tx.GetMsgs() { + if ethMsg, ok := msg.(*evmtypes.MsgEthereumTx); ok { + return []mempool.SignerData{ + mempool.NewSignerData( + ethMsg.GetFrom(), + ethMsg.AsTransaction().Nonce(), + ), + }, nil + } + } + } + } + + return s.fallback.GetSigners(tx) +} diff --git a/evmd/signer_test.go b/evmd/signer_test.go new file mode 100644 index 000000000..bbbe77ae8 --- /dev/null +++ b/evmd/signer_test.go @@ -0,0 +1,79 @@ +package evmd_test + +import ( + "math/big" + "testing" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + mempool "github.com/cosmos/cosmos-sdk/types/mempool" + "github.com/cosmos/evm/evmd" + "github.com/cosmos/evm/x/vm/types" + "github.com/stretchr/testify/require" + protov2 "google.golang.org/protobuf/proto" +) + +type mockFallback struct { + called bool +} + +func (m *mockFallback) GetSigners(tx sdk.Tx) ([]mempool.SignerData, error) { + m.called = true + return []mempool.SignerData{mempool.NewSignerData(sdk.AccAddress("fallback"), 1)}, nil +} + +type mockHasExtOptions struct { + msg sdk.Msg +} + +func (m *mockHasExtOptions) GetMsgs() []sdk.Msg { return []sdk.Msg{m.msg} } +func (m *mockHasExtOptions) GetMsgsV2() ([]protov2.Message, error) { + return []protov2.Message{}, nil +} +func (m *mockHasExtOptions) GetExtensionOptions() []*codectypes.Any { + return []*codectypes.Any{ + { + TypeUrl: "/cosmos.evm.vm.v1.ExtensionOptionsEthereumTx", + Value: []byte{}, + }, + } +} +func (m *mockHasExtOptions) GetNonCriticalExtensionOptions() []*codectypes.Any { return nil } + +func TestGetSigners(t *testing.T) { + ethAddr := sdk.AccAddress("ethsigner") + evmTx := &types.EvmTxArgs{ + ChainID: big.NewInt(100), + Nonce: 1, + Amount: big.NewInt(10), + GasLimit: 100000, + GasPrice: big.NewInt(150), + GasFeeCap: big.NewInt(200), + } + ethMsg := types.NewTx(evmTx) + ethMsg.From = ethAddr.Bytes() + txWithEth := &mockHasExtOptions{ + msg: ethMsg, + } + fallback := &mockFallback{} + adapter := evmd.NewEthSignerExtractionAdapter(fallback) + signers, err := adapter.GetSigners(txWithEth) + require.NoError(t, err) + require.Equal(t, []mempool.SignerData{ + mempool.NewSignerData( + ethMsg.GetFrom(), + ethMsg.AsTransaction().Nonce(), + ), + }, signers) + require.False(t, fallback.called) + + fallback = &mockFallback{} + txWithEth = &mockHasExtOptions{} + adapter = evmd.NewEthSignerExtractionAdapter(fallback) + signers, err = adapter.GetSigners(txWithEth) + require.NoError(t, err) + fallbackSigners, err := new(mockFallback).GetSigners(txWithEth) + require.NoError(t, err) + require.Equal(t, fallbackSigners, signers) + require.True(t, fallback.called) +} diff --git a/evmd/tests/integration/create_app.go b/evmd/tests/integration/create_app.go index 852929229..9ef4cb193 100644 --- a/evmd/tests/integration/create_app.go +++ b/evmd/tests/integration/create_app.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/evm/evmd" "github.com/cosmos/evm/evmd/cmd/evmd/config" testconfig "github.com/cosmos/evm/testutil/config" + "github.com/cosmos/evm/testutil/constants" feemarkettypes "github.com/cosmos/evm/x/feemarket/types" ibctesting "github.com/cosmos/ibc-go/v10/testing" @@ -54,7 +55,7 @@ func SetupEvmd() (ibctesting.TestingApp, map[string]json.RawMessage) { nil, true, simutils.EmptyAppOptions{}, - 9001, + constants.ExampleEIP155ChainID, testconfig.EvmAppOptions, ) // disable base fee for testing diff --git a/precompiles/testutil/contracts/contracts.go b/precompiles/testutil/contracts/contracts.go index e039c9b69..09f4d3ebc 100644 --- a/precompiles/testutil/contracts/contracts.go +++ b/precompiles/testutil/contracts/contracts.go @@ -82,7 +82,7 @@ func Call(ctx sdk.Context, app evm.EvmApp, args CallArgs) (res abci.ExecTxResult Input: input, Accesses: args.AccessList, }) - msg.From = addr.Hex() + msg.From = addr.Bytes() res, err = integration.DeliverEthTx(app, args.PrivKey, msg) if err != nil { diff --git a/proto/cosmos/evm/vm/v1/tx.proto b/proto/cosmos/evm/vm/v1/tx.proto index 7a29cb2fc..7ee8d3004 100644 --- a/proto/cosmos/evm/vm/v1/tx.proto +++ b/proto/cosmos/evm/vm/v1/tx.proto @@ -46,10 +46,11 @@ message MsgEthereumTx { // hash of the transaction in hex format string hash = 3 [ (gogoproto.moretags) = "rlp:\"-\"", (amino.dont_omitempty) = true ]; - // from is the ethereum signer address in hex format. This address value is - // checked against the address derived from the signature (V, R, S) using the + string deprecated_from = 4 [ deprecated = true ]; + // from is the bytes of ethereum signer address. This address value is checked + // against the address derived from the signature (V, R, S) using the // secp256k1 elliptic curve - string from = 4; + bytes from = 5; } // LegacyTx is the transaction data of regular Ethereum transactions. diff --git a/rpc/backend/blocks.go b/rpc/backend/blocks.go index c40a841e6..9c9b723aa 100644 --- a/rpc/backend/blocks.go +++ b/rpc/backend/blocks.go @@ -388,11 +388,10 @@ func (b *Backend) RPCBlockFromTendermintBlock( continue } - tx := ethMsg.AsTransaction() height := uint64(block.Height) //#nosec G115 -- checked for int overflow already index := uint64(txIndex) //#nosec G115 -- checked for int overflow already rpcTx, err := rpctypes.NewRPCTransaction( - tx, + ethMsg, common.BytesToHash(block.Hash()), height, index, @@ -400,7 +399,7 @@ func (b *Backend) RPCBlockFromTendermintBlock( b.EvmChainID, ) if err != nil { - b.Logger.Debug("NewTransactionFromData for receipt failed", "hash", tx.Hash().Hex(), "error", err.Error()) + b.Logger.Debug("NewTransactionFromData for receipt failed", "hash", ethMsg.Hash, "error", err.Error()) continue } ethRPCTxs = append(ethRPCTxs, rpcTx) @@ -588,7 +587,7 @@ func (b *Backend) formatTxReceipt(ethMsg *evmtypes.MsgEthereumTx, blockMsgs []*e return nil, err } - from, err := ethMsg.GetSender(chainID.ToInt()) + from, err := ethMsg.GetSenderLegacy(ethtypes.LatestSignerForChainID(chainID.ToInt())) if err != nil { return nil, err } diff --git a/rpc/backend/call_tx.go b/rpc/backend/call_tx.go index edd4084ab..dc87a599b 100644 --- a/rpc/backend/call_tx.go +++ b/rpc/backend/call_tx.go @@ -118,7 +118,7 @@ func (b *Backend) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { } ethereumTx := &evmtypes.MsgEthereumTx{} - if err := ethereumTx.FromEthereumTx(tx); err != nil { + if err := ethereumTx.FromSignedEthereumTx(tx, ethtypes.LatestSignerForChainID(b.EvmChainID)); err != nil { b.Logger.Error("transaction converting failed", "error", err.Error()) return common.Hash{}, err } diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index cded70a40..9711a2960 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -195,7 +195,7 @@ func (b *Backend) GetTransactionReceipt(hash common.Hash) (map[string]interface{ return nil, err } - from, err := ethMsg.GetSender(chainID.ToInt()) + from, err := ethMsg.GetSenderLegacy(ethtypes.LatestSignerForChainID(chainID.ToInt())) if err != nil { return nil, err } diff --git a/rpc/backend/utils.go b/rpc/backend/utils.go index 7018e8499..39a750581 100644 --- a/rpc/backend/utils.go +++ b/rpc/backend/utils.go @@ -91,7 +91,7 @@ func (b *Backend) getAccountNonce(accAddr common.Address, pending bool, height i break } - sender, err := ethMsg.GetSender(b.EvmChainID) + sender, err := ethMsg.GetSenderLegacy(ethtypes.LatestSignerForChainID(b.EvmChainID)) if err != nil { continue } diff --git a/rpc/types/utils.go b/rpc/types/utils.go index a4260d423..86dd29bb4 100644 --- a/rpc/types/utils.go +++ b/rpc/types/utils.go @@ -158,31 +158,34 @@ func NewTransactionFromMsg( baseFee *big.Int, chainID *big.Int, ) (*RPCTransaction, error) { - tx := msg.AsTransaction() - return NewRPCTransaction(tx, blockHash, blockNumber, index, baseFee, chainID) + return NewRPCTransaction(msg, blockHash, blockNumber, index, baseFee, chainID) } // NewTransactionFromData returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). func NewRPCTransaction( - tx *ethtypes.Transaction, + msg *evmtypes.MsgEthereumTx, blockHash common.Hash, blockNumber, index uint64, baseFee, chainID *big.Int, ) (*RPCTransaction, error) { + tx := msg.AsTransaction() // Determine the signer. For replay-protected transactions, use the most permissive // signer, because we assume that signers are backwards-compatible with old - // transactions. For non-protected transactions, the homestead signer signer is used - // because the return value of ChainId is zero for those transactions. + // transactions. For non-protected transactions, the frontier signer is used + // because the latest signer will reject the unprotected transactions. var signer ethtypes.Signer if tx.Protected() { signer = ethtypes.LatestSignerForChainID(tx.ChainId()) } else { - signer = ethtypes.HomesteadSigner{} + signer = ethtypes.FrontierSigner{} + } + from, err := msg.GetSenderLegacy(signer) + if err != nil { + return nil, err } - from, _ := ethtypes.Sender(signer, tx) // #nosec G703 v, r, s := tx.RawSignatureValues() result := &RPCTransaction{ Type: hexutil.Uint64(tx.Type()), diff --git a/tests/integration/ante/test_bench_evm_ante.go b/tests/integration/ante/test_bench_evm_ante.go index 5b3e6a089..fc7919d6d 100644 --- a/tests/integration/ante/test_bench_evm_ante.go +++ b/tests/integration/ante/test_bench_evm_ante.go @@ -57,7 +57,7 @@ func RunBenchmarkEthGasConsumeDecorator(b *testing.B, create network.CreateEvmAp addr := testutiltx.GenerateAddress() args.Accesses = ðtypes.AccessList{{Address: addr, StorageKeys: nil}} tx := evmtypes.NewTx(args) - tx.From = addr.Hex() + tx.From = addr.Bytes() cacheCtx, _ := ctx.CacheContext() // Create new stateDB for each test case from the cached context diff --git a/tests/integration/ante/test_evm_ante.go b/tests/integration/ante/test_evm_ante.go index 3e63b5092..a5f8e1334 100644 --- a/tests/integration/ante/test_evm_ante.go +++ b/tests/integration/ante/test_evm_ante.go @@ -621,7 +621,7 @@ func (s *EvmAnteTestSuite) TestAnteHandler() { tx, err := s.GetTxFactory().GenerateSignedEthTx(privKey, ethContractCreationTxParams) s.Require().NoError(err) msg := tx.GetMsgs()[0].(*evmtypes.MsgEthereumTx) - msg.From = addr.Hex() + msg.From = addr.Bytes() return tx }, true, false, false, }, @@ -1248,7 +1248,7 @@ func (s *EvmAnteTestSuite) TestEthSigVerificationDecorator() { GasPrice: big.NewInt(1), } signedTx := evmtypes.NewTx(ethContractCreationTxParams) - signedTx.From = addr.Hex() + signedTx.From = addr.Bytes() err := signedTx.Sign(ethSigner, utiltx.NewSigner(privKey)) s.Require().NoError(err) @@ -1259,7 +1259,7 @@ func (s *EvmAnteTestSuite) TestEthSigVerificationDecorator() { GasPrice: big.NewInt(1), } unprotectedTx := evmtypes.NewTx(unprotectedEthTxParams) - unprotectedTx.From = addr.Hex() + unprotectedTx.From = addr.Bytes() err = unprotectedTx.Sign(types.HomesteadSigner{}, utiltx.NewSigner(privKey)) s.Require().NoError(err) diff --git a/tests/integration/ante/test_evm_unit_07_can_transfer.go b/tests/integration/ante/test_evm_unit_07_can_transfer.go index 95537d617..5cccaf6d7 100644 --- a/tests/integration/ante/test_evm_unit_07_can_transfer.go +++ b/tests/integration/ante/test_evm_unit_07_can_transfer.go @@ -4,8 +4,6 @@ import ( "fmt" "math/big" - gethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/cosmos/evm/ante/evm" testconstants "github.com/cosmos/evm/testutil/constants" "github.com/cosmos/evm/testutil/integration/evm/factory" @@ -74,11 +72,8 @@ func (s *EvmUnitAnteTestSuite) TestCanTransfer() { s.Run(fmt.Sprintf("%v_%v_%v", evmtypes.GetTxTypeName(s.EthTxType), s.ChainID, tc.name), func() { baseFeeResp, err := grpcHandler.GetEvmBaseFee() s.Require().NoError(err) - ethCfg := unitNetwork.GetEVMChainConfig() evmParams, err := grpcHandler.GetEvmParams() s.Require().NoError(err) - ctx := unitNetwork.GetContext() - signer := gethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()), uint64(ctx.BlockTime().Unix())) //#nosec G115 -- int overflow is not a concern here txArgs, err := txFactory.GenerateDefaultTxTypeArgs(senderKey.Addr, s.EthTxType) s.Require().NoError(err) txArgs.Amount = big.NewInt(100) @@ -86,10 +81,10 @@ func (s *EvmUnitAnteTestSuite) TestCanTransfer() { tc.malleate(&txArgs) msg := evmtypes.NewTx(&txArgs) - msg.From = senderKey.Addr.String() + msg.From = senderKey.Addr.Bytes() signMsg, err := txFactory.SignMsgEthereumTx(senderKey.Priv, *msg) s.Require().NoError(err) - coreMsg, err := signMsg.AsMessage(signer, baseFeeResp.BaseFee.BigInt()) + coreMsg, err := signMsg.AsMessage(baseFeeResp.BaseFee.BigInt()) s.Require().NoError(err) // Function under test diff --git a/tests/integration/indexer/test_kv_indexer.go b/tests/integration/indexer/test_kv_indexer.go index c8806bacf..93a62d8db 100644 --- a/tests/integration/indexer/test_kv_indexer.go +++ b/tests/integration/indexer/test_kv_indexer.go @@ -39,7 +39,7 @@ func TestKVIndexer(t *testing.T, create network.CreateEvmApp, options ...network GasLimit: 21000, } tx := types.NewTx(ðTxParams) - tx.From = from.Hex() + tx.From = from.Bytes() require.NoError(t, tx.Sign(ethSigner, signer)) txHash := tx.AsTransaction().Hash() diff --git a/tests/integration/precompiles/distribution/test_distribution.go b/tests/integration/precompiles/distribution/test_distribution.go index 70d096e9f..58587a21d 100644 --- a/tests/integration/precompiles/distribution/test_distribution.go +++ b/tests/integration/precompiles/distribution/test_distribution.go @@ -268,9 +268,7 @@ func (s *PrecompileTestSuite) TestRun() { cfg, err := s.network.App.GetEVMKeeper().EVMConfig(ctx, proposerAddress) s.Require().NoError(err, "failed to instantiate EVM config") - ethChainID := s.network.GetEIP155ChainID() - signer := gethtypes.LatestSignerForChainID(ethChainID) - msg, err := signedMsg.AsMessage(signer, baseFee) + msg, err := signedMsg.AsMessage(baseFee) s.Require().NoError(err, "failed to instantiate Ethereum message") // Instantiate EVM diff --git a/tests/integration/rpc/backend/test_backend_suite.go b/tests/integration/rpc/backend/test_backend_suite.go index 5f3065fcd..24015623d 100644 --- a/tests/integration/rpc/backend/test_backend_suite.go +++ b/tests/integration/rpc/backend/test_backend_suite.go @@ -19,7 +19,6 @@ import ( rpcbackend "github.com/cosmos/evm/rpc/backend" "github.com/cosmos/evm/rpc/backend/mocks" rpctypes "github.com/cosmos/evm/rpc/types" - "github.com/cosmos/evm/testutil/config" "github.com/cosmos/evm/testutil/constants" "github.com/cosmos/evm/testutil/integration/evm/network" utiltx "github.com/cosmos/evm/testutil/tx" @@ -55,7 +54,7 @@ var ChainID = constants.ExampleChainID func (s *TestSuite) SetupTest() { ctx := server.NewDefaultContext() ctx.Viper.Set("telemetry.global-labels", []interface{}{}) - ctx.Viper.Set("evm.evm-chain-id", config.EVMChainID) + ctx.Viper.Set("evm.evm-chain-id", ChainID.EVMChainID) baseDir := s.T().TempDir() nodeDirName := "node" @@ -96,7 +95,7 @@ func (s *TestSuite) SetupTest() { s.backend.Cfg.JSONRPC.GasCap = 0 s.backend.Cfg.JSONRPC.EVMTimeout = 0 s.backend.Cfg.JSONRPC.AllowInsecureUnlock = true - s.backend.Cfg.EVM.EVMChainID = 262144 + s.backend.Cfg.EVM.EVMChainID = ChainID.EVMChainID s.backend.QueryClient.QueryClient = mocks.NewEVMQueryClient(s.T()) s.backend.QueryClient.FeeMarket = mocks.NewFeeMarketQueryClient(s.T()) s.backend.Ctx = rpctypes.ContextWithHeight(1) @@ -118,7 +117,7 @@ func (s *TestSuite) buildEthereumTx() (*evmtypes.MsgEthereumTx, []byte) { msgEthereumTx := evmtypes.NewTx(ðTxParams) // A valid msg should have empty `From` - msgEthereumTx.From = s.from.Hex() + msgEthereumTx.From = s.from.Bytes() txBuilder := s.backend.ClientCtx.TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgEthereumTx) @@ -142,7 +141,7 @@ func (s *TestSuite) buildEthereumTxWithChainID(eip155ChainID *big.Int) *evmtypes msgEthereumTx := evmtypes.NewTx(ðTxParams) // A valid msg should have empty `From` - msgEthereumTx.From = s.from.Hex() + msgEthereumTx.From = s.from.Bytes() txBuilder := s.backend.ClientCtx.TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgEthereumTx) @@ -172,7 +171,7 @@ func (s *TestSuite) buildFormattedBlock( if tx != nil { if fullTx { rpcTx, err := rpctypes.NewRPCTransaction( - tx.AsTransaction(), + tx, common.BytesToHash(header.Hash()), uint64(header.Height), //nolint:gosec // G115 // won't exceed uint64 uint64(0), @@ -200,7 +199,7 @@ func (s *TestSuite) buildFormattedBlock( func (s *TestSuite) generateTestKeyring(clientDir string) (keyring.Keyring, error) { buf := bufio.NewReader(os.Stdin) - encCfg := encoding.MakeConfig(config.EVMChainID) + encCfg := encoding.MakeConfig(ChainID.EVMChainID) return keyring.New(sdk.KeyringServiceName(), keyring.BackendTest, clientDir, buf, encCfg.Codec, []keyring.Option{hd.EthSecp256k1Option()}...) } @@ -209,7 +208,7 @@ func (s *TestSuite) signAndEncodeEthTx(msgEthereumTx *evmtypes.MsgEthereumTx) [] signer := utiltx.NewSigner(priv) ethSigner := ethtypes.LatestSigner(s.backend.ChainConfig()) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() err := msgEthereumTx.Sign(ethSigner, signer) s.Require().NoError(err) diff --git a/tests/integration/rpc/backend/test_blocks.go b/tests/integration/rpc/backend/test_blocks.go index 204e7f0b1..25a71d4a8 100644 --- a/tests/integration/rpc/backend/test_blocks.go +++ b/tests/integration/rpc/backend/test_blocks.go @@ -1099,7 +1099,7 @@ func (s *TestSuite) TestGetEthBlockFromTendermint() { if tc.expTxs { if tc.fullTx { rpcTx, err := ethrpc.NewRPCTransaction( - msgEthereumTx.AsTransaction(), + msgEthereumTx, common.BytesToHash(header.Hash()), uint64(header.Height), //nolint:gosec // G115 // won't exceed uint64 uint64(0), diff --git a/tests/integration/rpc/backend/test_call_tx.go b/tests/integration/rpc/backend/test_call_tx.go index 06cdad25c..99dab737f 100644 --- a/tests/integration/rpc/backend/test_call_tx.go +++ b/tests/integration/rpc/backend/test_call_tx.go @@ -14,6 +14,7 @@ import ( "github.com/cosmos/evm/rpc/backend/mocks" rpctypes "github.com/cosmos/evm/rpc/types" + "github.com/cosmos/evm/testutil/constants" utiltx "github.com/cosmos/evm/testutil/tx" evmtypes "github.com/cosmos/evm/x/vm/types" @@ -292,8 +293,7 @@ func (s *TestSuite) TestSendRawTransaction() { ethTx, bz := s.buildEthereumTx() emptyEvmChainIDTx := s.buildEthereumTxWithChainID(nil) - invalidEvmChainIDTx := s.buildEthereumTxWithChainID(big.NewInt(1)) - + invalidChainID := big.NewInt(1) // Sign the ethTx ethSigner := ethtypes.LatestSigner(s.backend.ChainConfig()) err := ethTx.Sign(ethSigner, s.signer) @@ -334,14 +334,15 @@ func (s *TestSuite) TestSendRawTransaction() { func() []byte { from, priv := utiltx.NewAddrKey() signer := utiltx.NewSigner(priv) - invalidEvmChainIDTx.From = from.String() - err := invalidEvmChainIDTx.Sign(ethSigner, signer) + invalidEvmChainIDTx := s.buildEthereumTxWithChainID(invalidChainID) + invalidEvmChainIDTx.From = from.Bytes() + err := invalidEvmChainIDTx.Sign(ethtypes.LatestSignerForChainID(invalidChainID), signer) s.Require().NoError(err) bytes, _ := rlp.EncodeToBytes(invalidEvmChainIDTx.AsTransaction()) return bytes }, common.Hash{}, - fmt.Errorf("incorrect chain-id; expected %d, got %d", 262144, big.NewInt(1)).Error(), + fmt.Errorf("incorrect chain-id; expected %d, got %d", constants.ExampleChainID.EVMChainID, invalidChainID).Error(), false, }, { @@ -402,7 +403,8 @@ func (s *TestSuite) TestSendRawTransaction() { if tc.expPass { s.Require().Equal(tc.expHash, hash) } else { - s.Require().Errorf(err, tc.expError) + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expError) } }) } diff --git a/tests/integration/rpc/backend/test_chain_info.go b/tests/integration/rpc/backend/test_chain_info.go index c143299ae..3a0f4b576 100644 --- a/tests/integration/rpc/backend/test_chain_info.go +++ b/tests/integration/rpc/backend/test_chain_info.go @@ -14,7 +14,7 @@ import ( "github.com/cosmos/evm/rpc/backend/mocks" rpc "github.com/cosmos/evm/rpc/types" - "github.com/cosmos/evm/testutil/config" + "github.com/cosmos/evm/testutil/constants" utiltx "github.com/cosmos/evm/testutil/tx" evmtypes "github.com/cosmos/evm/x/vm/types" @@ -156,7 +156,7 @@ func (s *TestSuite) TestBaseFee() { } func (s *TestSuite) TestChainID() { - expChainID := (*hexutil.Big)(big.NewInt(config.EVMChainID)) + expChainID := (*hexutil.Big)(big.NewInt(int64(constants.ExampleChainID.EVMChainID))) //nolint:gosec // G115 testCases := []struct { name string registerMock func() diff --git a/tests/integration/rpc/backend/test_evm_query_client.go b/tests/integration/rpc/backend/test_evm_query_client.go index aca529548..6741180ba 100644 --- a/tests/integration/rpc/backend/test_evm_query_client.go +++ b/tests/integration/rpc/backend/test_evm_query_client.go @@ -17,7 +17,7 @@ import ( "github.com/cosmos/evm/rpc/backend/mocks" rpc "github.com/cosmos/evm/rpc/types" - "github.com/cosmos/evm/testutil/config" + "github.com/cosmos/evm/testutil/constants" utiltx "github.com/cosmos/evm/testutil/tx" evmtypes "github.com/cosmos/evm/x/vm/types" @@ -39,26 +39,26 @@ var _ evmtypes.QueryClient = &mocks.EVMQueryClient{} func RegisterTraceTransactionWithPredecessors(queryClient *mocks.EVMQueryClient, msgEthTx *evmtypes.MsgEthereumTx, predecessors []*evmtypes.MsgEthereumTx) { data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} queryClient.On("TraceTx", rpc.ContextWithHeight(1), - &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, Predecessors: predecessors, ChainId: config.EVMChainID, BlockMaxGas: -1}). + &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, Predecessors: predecessors, ChainId: int64(constants.ExampleChainID.EVMChainID), BlockMaxGas: -1}). //nolint:gosec // G115 Return(&evmtypes.QueryTraceTxResponse{Data: data}, nil) } func RegisterTraceTransaction(queryClient *mocks.EVMQueryClient, msgEthTx *evmtypes.MsgEthereumTx) { data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} - queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: config.EVMChainID, BlockMaxGas: -1}). - Return(&evmtypes.QueryTraceTxResponse{Data: data}, nil) + queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: int64(constants.ExampleChainID.EVMChainID), BlockMaxGas: -1}). //nolint:gosec // G115 + Return(&evmtypes.QueryTraceTxResponse{Data: data}, nil) } func RegisterTraceTransactionError(queryClient *mocks.EVMQueryClient, msgEthTx *evmtypes.MsgEthereumTx) { - queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: config.EVMChainID}). - Return(nil, errortypes.ErrInvalidRequest) + queryClient.On("TraceTx", rpc.ContextWithHeight(1), &evmtypes.QueryTraceTxRequest{Msg: msgEthTx, BlockNumber: 1, ChainId: int64(constants.ExampleChainID.EVMChainID)}). //nolint:gosec // G115 + Return(nil, errortypes.ErrInvalidRequest) } // TraceBlock func RegisterTraceBlock(queryClient *mocks.EVMQueryClient, txs []*evmtypes.MsgEthereumTx) { data := []byte{0x7b, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x7d} queryClient.On("TraceBlock", rpc.ContextWithHeight(1), - &evmtypes.QueryTraceBlockRequest{Txs: txs, BlockNumber: 1, TraceConfig: &evmtypes.TraceConfig{}, ChainId: config.EVMChainID, BlockMaxGas: -1}). + &evmtypes.QueryTraceBlockRequest{Txs: txs, BlockNumber: 1, TraceConfig: &evmtypes.TraceConfig{}, ChainId: int64(constants.ExampleChainID.EVMChainID), BlockMaxGas: -1}). //nolint:gosec // G115 Return(&evmtypes.QueryTraceBlockResponse{Data: data}, nil) } diff --git a/tests/integration/rpc/backend/test_tracing.go b/tests/integration/rpc/backend/test_tracing.go index 172b98340..a6744e55c 100644 --- a/tests/integration/rpc/backend/test_tracing.go +++ b/tests/integration/rpc/backend/test_tracing.go @@ -37,7 +37,7 @@ func (s *TestSuite) TestTraceTransaction() { txEncoder := s.backend.ClientCtx.TxConfig.TxEncoder() - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() _ = msgEthereumTx.Sign(ethSigner, s.signer) baseDenom := evmtypes.GetEVMCoinDenom() @@ -45,7 +45,7 @@ func (s *TestSuite) TestTraceTransaction() { tx, _ := msgEthereumTx.BuildTx(s.backend.ClientCtx.TxConfig.NewTxBuilder(), baseDenom) txBz, _ := txEncoder(tx) - msgEthereumTx2.From = from.String() + msgEthereumTx2.From = from.Bytes() _ = msgEthereumTx2.Sign(ethSigner, s.signer) tx2, _ := msgEthereumTx.BuildTx(s.backend.ClientCtx.TxConfig.NewTxBuilder(), baseDenom) diff --git a/tests/integration/rpc/backend/test_tx_info.go b/tests/integration/rpc/backend/test_tx_info.go index 91c6befaf..104403138 100644 --- a/tests/integration/rpc/backend/test_tx_info.go +++ b/tests/integration/rpc/backend/test_tx_info.go @@ -45,7 +45,7 @@ func (s *TestSuite) TestGetTransactionByHash() { }, } - rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) + rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx, common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) testCases := []struct { name string @@ -132,7 +132,7 @@ func (s *TestSuite) TestGetTransactionByHash() { func (s *TestSuite) TestGetTransactionsByHashPending() { msgEthereumTx, bz := s.buildEthereumTx() - rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) + rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx, common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) testCases := []struct { name string @@ -192,7 +192,7 @@ func (s *TestSuite) TestGetTransactionsByHashPending() { func (s *TestSuite) TestGetTxByEthHash() { msgEthereumTx, bz := s.buildEthereumTx() - rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx.AsTransaction(), common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) + rpcTransaction, _ := rpctypes.NewRPCTransaction(msgEthereumTx, common.Hash{}, 0, 0, big.NewInt(1), s.backend.EvmChainID) testCases := []struct { name string diff --git a/tests/integration/x/vm/state_transition_benchmark.go b/tests/integration/x/vm/state_transition_benchmark.go index 1a5503420..a8d70a915 100644 --- a/tests/integration/x/vm/state_transition_benchmark.go +++ b/tests/integration/x/vm/state_transition_benchmark.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" ethtypes "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" "github.com/stretchr/testify/require" utiltx "github.com/cosmos/evm/testutil/tx" @@ -50,7 +49,7 @@ func newSignedEthTx( addr sdk.Address, krSigner keyring.Signer, ethSigner ethtypes.Signer, -) (*ethtypes.Transaction, error) { +) (*evmtypes.MsgEthereumTx, error) { var ethTx *ethtypes.Transaction switch txData := txData.(type) { case *ethtypes.AccessListTx: @@ -76,7 +75,11 @@ func newSignedEthTx( return nil, err } - return ethTx, nil + var msg evmtypes.MsgEthereumTx + if err := msg.FromEthereumTx(ethTx); err != nil { + return nil, err + } + return &msg, nil } func newEthMsgTx( @@ -130,30 +133,26 @@ func newEthMsgTx( return nil, nil, err } - msg.From = address.Hex() + msg.From = address.Bytes() return msg, baseFee, msg.Sign(ethSigner, krSigner) } func newNativeMessage( nonce uint64, - blockHeight int64, address common.Address, - cfg *params.ChainConfig, krSigner keyring.Signer, ethSigner ethtypes.Signer, txType byte, data []byte, accessList ethtypes.AccessList, ) (*core.Message, error) { - msgSigner := ethtypes.MakeSigner(cfg, big.NewInt(blockHeight), 10000000) - msg, baseFee, err := newEthMsgTx(nonce, address, krSigner, ethSigner, txType, data, accessList) if err != nil { return nil, err } - m, err := msg.AsMessage(msgSigner, baseFee) + m, err := msg.AsMessage(baseFee) if err != nil { return nil, err } @@ -263,9 +262,7 @@ func BenchmarkApplyMessage(b *testing.B) { krSigner := utiltx.NewSigner(suite.Keyring.GetPrivKey(0)) m, err := newNativeMessage( suite.Network.App.GetEVMKeeper().GetNonce(suite.Network.GetContext(), addr), - suite.Network.GetContext().BlockHeight(), addr, - ethCfg, krSigner, signer, ethtypes.AccessListTxType, @@ -298,9 +295,7 @@ func BenchmarkApplyMessageWithLegacyTx(b *testing.B) { krSigner := utiltx.NewSigner(suite.Keyring.GetPrivKey(0)) m, err := newNativeMessage( suite.Network.App.GetEVMKeeper().GetNonce(suite.Network.GetContext(), addr), - suite.Network.GetContext().BlockHeight(), addr, - ethCfg, krSigner, signer, ethtypes.AccessListTxType, @@ -333,9 +328,7 @@ func BenchmarkApplyMessageWithDynamicFeeTx(b *testing.B) { krSigner := utiltx.NewSigner(suite.Keyring.GetPrivKey(0)) m, err := newNativeMessage( suite.Network.App.GetEVMKeeper().GetNonce(suite.Network.GetContext(), addr), - suite.Network.GetContext().BlockHeight(), addr, - ethCfg, krSigner, signer, ethtypes.DynamicFeeTxType, diff --git a/tests/integration/x/vm/test_benchmark.go b/tests/integration/x/vm/test_benchmark.go index a268af7e6..dea5051ce 100644 --- a/tests/integration/x/vm/test_benchmark.go +++ b/tests/integration/x/vm/test_benchmark.go @@ -63,7 +63,7 @@ func DoBenchmark(b *testing.B, txBuilder TxBuilder) { krSigner := utiltx.NewSigner(suite.Keyring.GetPrivKey(0)) msg := txBuilder(suite, contractAddr) - msg.From = suite.Keyring.GetAddr(0).Hex() + msg.From = suite.Keyring.GetAddr(0).Bytes() err := msg.Sign(ethtypes.LatestSignerForChainID(types.GetEthChainConfig().ChainID), krSigner) require.NoError(b, err) @@ -191,7 +191,7 @@ func BenchmarkMessageCall(b *testing.B) { } msg := types.NewTx(ethTxParams) - msg.From = suite.Keyring.GetAddr(0).Hex() + msg.From = suite.Keyring.GetAddr(0).Bytes() krSigner := utiltx.NewSigner(suite.Keyring.GetPrivKey(0)) err = msg.Sign(ethtypes.LatestSignerForChainID(ethCfg.ChainID), krSigner) require.NoError(b, err) diff --git a/tests/integration/x/vm/test_fees.go b/tests/integration/x/vm/test_fees.go index 1cc86e2f9..2517488e1 100644 --- a/tests/integration/x/vm/test_fees.go +++ b/tests/integration/x/vm/test_fees.go @@ -35,7 +35,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasFeeCap *big.Int gasTipCap *big.Int cost *sdkmath.Int - from string + from []byte accessList *ethtypes.AccessList expectPass bool EnableFeemarket bool @@ -46,7 +46,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasPrice: &oneInt, cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, }, @@ -56,7 +56,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 99, gasPrice: &oneInt, cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, }, @@ -66,7 +66,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 1, gasPrice: &oneInt, cost: &negInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, }, @@ -76,7 +76,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 100, gasPrice: &oneInt, cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, }, @@ -86,7 +86,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasPrice: &fiveInt, cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, }, @@ -96,7 +96,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 20, gasPrice: &fiveInt, cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, }, @@ -106,7 +106,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasPrice: &fiveInt, cost: &fiftyInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, }, @@ -116,7 +116,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasPrice: &fiveInt, cost: &hundredInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, }, @@ -126,7 +126,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasFeeCap: big.NewInt(1), cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, EnableFeemarket: true, @@ -137,7 +137,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 99, gasFeeCap: big.NewInt(1), cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, EnableFeemarket: true, @@ -148,7 +148,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 1, gasFeeCap: big.NewInt(1), cost: &negInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, EnableFeemarket: true, @@ -159,7 +159,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 100, gasFeeCap: big.NewInt(1), cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, EnableFeemarket: true, @@ -170,7 +170,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasFeeCap: big.NewInt(5), cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, EnableFeemarket: true, @@ -181,7 +181,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 20, gasFeeCap: big.NewInt(5), cost: &oneInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, EnableFeemarket: true, @@ -192,7 +192,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasFeeCap: big.NewInt(5), cost: &fiftyInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: true, EnableFeemarket: true, @@ -203,7 +203,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { gasLimit: 10, gasFeeCap: big.NewInt(5), cost: &hundredInt, - from: addr.String(), + from: addr.Bytes(), accessList: ðtypes.AccessList{}, expectPass: false, EnableFeemarket: true, @@ -219,7 +219,7 @@ func (s *KeeperTestSuite) TestCheckSenderBalance() { for i, tc := range testCases { s.Run(tc.name, func() { - to := common.HexToAddress(tc.from) + to := common.HexToAddress(tc.to) var amount, gasPrice, gasFeeCap, gasTipCap *big.Int if tc.cost != nil { @@ -296,7 +296,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { expectPassVerify bool expectPassDeduct bool EnableFeemarket bool - from string + from []byte malleate func() }{ { @@ -307,7 +307,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "Equal balance", @@ -317,7 +317,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "Higher gas limit, not enough balance", @@ -327,7 +327,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: false, - from: addr.String(), + from: addr.Bytes(), }, { name: "Higher gas price, enough balance", @@ -337,7 +337,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "Higher gas price, not enough balance", @@ -347,7 +347,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: false, - from: addr.String(), + from: addr.Bytes(), }, // This case is expected to be true because the fees can be deducted, but the tx // execution is going to fail because there is no more balance to pay the cost @@ -359,7 +359,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), }, // testcases with EnableFeemarket enabled. { @@ -372,7 +372,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { expectPassVerify: false, expectPassDeduct: true, EnableFeemarket: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "empty tip fee is valid to deduct", @@ -384,7 +384,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { expectPassVerify: true, expectPassDeduct: true, EnableFeemarket: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "effectiveTip equal to gasTipCap", @@ -395,7 +395,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { expectPassVerify: true, expectPassDeduct: true, EnableFeemarket: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "effectiveTip equal to (gasFeeCap - baseFee)", @@ -407,7 +407,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { expectPassVerify: true, expectPassDeduct: true, EnableFeemarket: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "Invalid from address", @@ -417,7 +417,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: true, expectPassDeduct: false, - from: "abcdef", + from: []byte("abcdef"), }, { name: "Enough balance - with access list", @@ -432,7 +432,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { }, expectPassVerify: true, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), }, { name: "gasLimit < intrinsicGas during IsCheckTx", @@ -442,7 +442,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { accessList: ðtypes.AccessList{}, expectPassVerify: false, expectPassDeduct: true, - from: addr.String(), + from: addr.Bytes(), malleate: func() { s.Network.WithIsCheckTxCtx(true) }, @@ -536,7 +536,7 @@ func (s *KeeperTestSuite) TestVerifyFeeAndDeductTxCostsFromUserBalance() { s.Require().Nil(fees, "invalid test %d passed. fees value must be nil - '%s'", i, tc.name) } - err = s.Network.App.GetEVMKeeper().DeductTxCostsFromUserBalance(s.Network.GetContext(), fees, common.HexToAddress(tx.From)) + err = s.Network.App.GetEVMKeeper().DeductTxCostsFromUserBalance(s.Network.GetContext(), fees, common.BytesToAddress(tx.From)) if tc.expectPassDeduct { s.Require().NoError(err, "valid test %d failed - '%s'", i, tc.name) } else { diff --git a/tests/integration/x/vm/test_state_transition.go b/tests/integration/x/vm/test_state_transition.go index 1486ab502..52cf0558e 100644 --- a/tests/integration/x/vm/test_state_transition.go +++ b/tests/integration/x/vm/test_state_transition.go @@ -274,9 +274,7 @@ func (s *KeeperTestSuite) TestGetEthIntrinsicGas() { nonce := s.Network.App.GetEVMKeeper().GetNonce(ctx, addr) m, err := newNativeMessage( nonce, - ctx.BlockHeight(), addr, - ethCfg, krSigner, signer, gethtypes.AccessListTxType, @@ -595,8 +593,8 @@ func (s *KeeperTestSuite) TestApplyTransaction() { s.Require().NoError(err) initialBalance := s.Network.App.GetBankKeeper().GetBalance(ctx, s.Keyring.GetAccAddr(0), "aatom") - ethTx := tx.GetMsgs()[0].(*types.MsgEthereumTx).AsTransaction() - res, err := s.Network.App.GetEVMKeeper().ApplyTransaction(ctx, ethTx) + ethMsg := tx.GetMsgs()[0].(*types.MsgEthereumTx) + res, err := s.Network.App.GetEVMKeeper().ApplyTransaction(ctx, ethMsg) s.Require().NoError(err) s.Require().Equal(res.GasUsed, uint64(3e6)) // Half of the gas should be refunded based on the protocol refund cap. diff --git a/tests/integration/x/vm/test_statedb.go b/tests/integration/x/vm/test_statedb.go index 2acb9d5f5..d6db2c83a 100644 --- a/tests/integration/x/vm/test_statedb.go +++ b/tests/integration/x/vm/test_statedb.go @@ -664,7 +664,7 @@ func (s *KeeperTestSuite) TestAddLog() { Input: []byte("test"), } msg := types.NewTx(ethTxParams) - msg.From = addr.Hex() + msg.From = addr.Bytes() tx := s.CreateTestTx(msg, privKey) msg, _ = tx.GetMsgs()[0].(*types.MsgEthereumTx) @@ -680,7 +680,7 @@ func (s *KeeperTestSuite) TestAddLog() { Input: []byte("test"), } msg2 := types.NewTx(ethTx2Params) - msg2.From = addr.Hex() + msg2.From = addr.Bytes() ethTx3Params := &types.EvmTxArgs{ ChainID: big.NewInt(testconstants.ExampleEIP155ChainID), @@ -693,7 +693,7 @@ func (s *KeeperTestSuite) TestAddLog() { Input: []byte("test"), } msg3 := types.NewTx(ethTx3Params) - msg3.From = addr.Hex() + msg3.From = addr.Bytes() tx3 := s.CreateTestTx(msg3, privKey) msg3, _ = tx3.GetMsgs()[0].(*types.MsgEthereumTx) @@ -710,7 +710,7 @@ func (s *KeeperTestSuite) TestAddLog() { Input: []byte("test"), } msg4 := types.NewTx(ethTx4Params) - msg4.From = addr.Hex() + msg4.From = addr.Bytes() testCases := []struct { name string diff --git a/tests/integration/x/vm/utils.go b/tests/integration/x/vm/utils.go index 0c3a61909..c22b8b1ee 100644 --- a/tests/integration/x/vm/utils.go +++ b/tests/integration/x/vm/utils.go @@ -80,7 +80,7 @@ func (s *KeeperTestSuite) DeployTestContract(t require.TestingT, ctx sdk.Context } krSigner := utiltx.NewSigner(s.Keyring.GetPrivKey(0)) - erc20DeployTx.From = addr.Hex() + erc20DeployTx.From = addr.Bytes() err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), krSigner) require.NoError(t, err) rsp, err := s.Network.App.GetEVMKeeper().EthereumTx(ctx, erc20DeployTx) @@ -137,7 +137,7 @@ func (s *KeeperTestSuite) TransferERC20Token(t require.TestingT, contractAddr, f addr := s.Keyring.GetAddr(0) krSigner := utiltx.NewSigner(s.Keyring.GetPrivKey(0)) - ercTransferTx.From = addr.Hex() + ercTransferTx.From = addr.Bytes() err = ercTransferTx.Sign(ethtypes.LatestSignerForChainID(chainID), krSigner) require.NoError(t, err) rsp, err := s.Network.App.GetEVMKeeper().EthereumTx(ctx, ercTransferTx) @@ -196,7 +196,7 @@ func (s *KeeperTestSuite) DeployTestMessageCall(t require.TestingT) common.Addre } krSigner := utiltx.NewSigner(s.Keyring.GetPrivKey(0)) - erc20DeployTx.From = addr.Hex() + erc20DeployTx.From = addr.Bytes() err = erc20DeployTx.Sign(ethtypes.LatestSignerForChainID(chainID), krSigner) require.NoError(t, err) rsp, err := s.Network.App.GetEVMKeeper().EthereumTx(ctx, erc20DeployTx) diff --git a/testutil/config/config.go b/testutil/config/config.go index 304459a4b..5ada238f6 100644 --- a/testutil/config/config.go +++ b/testutil/config/config.go @@ -24,9 +24,9 @@ var ChainsCoinInfo = map[uint64]evmtypes.EvmCoinInfo{ Decimals: evmtypes.EighteenDecimals, }, EVMChainID: { - Denom: "atest", - ExtendedDenom: "atest", - DisplayDenom: "test", + Denom: ExampleChainDenom, + ExtendedDenom: ExampleChainDenom, + DisplayDenom: ExampleDisplayDenom, Decimals: evmtypes.EighteenDecimals, }, } diff --git a/testutil/config/config_testing.go b/testutil/config/config_testing.go index c10693116..e37568c2b 100644 --- a/testutil/config/config_testing.go +++ b/testutil/config/config_testing.go @@ -48,6 +48,12 @@ var TestChainsCoinInfo = map[uint64]evmtypes.EvmCoinInfo{ DisplayDenom: ExampleChainDenom, Decimals: evmtypes.EighteenDecimals, }, + EVMChainID: { + Denom: ExampleChainDenom, + ExtendedDenom: ExampleChainDenom, + DisplayDenom: ExampleDisplayDenom, + Decimals: evmtypes.EighteenDecimals, + }, } // EvmAppOptions allows to setup the global configuration diff --git a/testutil/integration/contract.go b/testutil/integration/contract.go index 532b447d9..8797d3234 100644 --- a/testutil/integration/contract.go +++ b/testutil/integration/contract.go @@ -86,7 +86,7 @@ func DeployContract( Input: data, Accesses: ðtypes.AccessList{}, }) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() res, err := DeliverEthTx(app, priv, msgEthereumTx) if err != nil { @@ -120,7 +120,7 @@ func DeployContractWithFactory( GasLimit: uint64(100000), GasPrice: big.NewInt(1000000000), }) - msgEthereumTx.From = from.String() + msgEthereumTx.From = from.Bytes() res, err := DeliverEthTx(exampleApp, priv, msgEthereumTx) if err != nil { diff --git a/testutil/integration/evm/factory/helpers.go b/testutil/integration/evm/factory/helpers.go index 50ec06b35..e03d21d2c 100644 --- a/testutil/integration/evm/factory/helpers.go +++ b/testutil/integration/evm/factory/helpers.go @@ -14,7 +14,7 @@ import ( // buildMsgEthereumTx builds an Ethereum transaction from the given arguments and populates the From field. func buildMsgEthereumTx(txArgs evmtypes.EvmTxArgs, fromAddr common.Address) evmtypes.MsgEthereumTx { msgEthereumTx := evmtypes.NewTx(&txArgs) - msgEthereumTx.From = fromAddr.String() + msgEthereumTx.From = fromAddr.Bytes() return *msgEthereumTx } diff --git a/testutil/tx/eth.go b/testutil/tx/eth.go index 0f65bf8d4..6bbb41bd8 100644 --- a/testutil/tx/eth.go +++ b/testutil/tx/eth.go @@ -52,9 +52,6 @@ func PrepareEthTx( return nil, err } } - - msg.From = "" - txGasLimit += msg.GetGas() txFee = txFee.Add(sdk.Coin{Denom: baseDenom, Amount: sdkmath.NewIntFromBigInt(msg.GetFee())}) } @@ -137,8 +134,7 @@ func CreateEthTx( Accesses: ðtypes.AccessList{}, } msgEthereumTx := evmtypes.NewTx(evmTxParams) - msgEthereumTx.From = fromAddr.String() - + msgEthereumTx.From = fromAddr.Bytes() // If we are creating multiple eth Tx's with different senders, we need to sign here rather than later. if privKey != nil { signer := ethtypes.LatestSignerForChainID(evmtypes.GetEthChainConfig().ChainID) diff --git a/x/vm/client/cli/tx.go b/x/vm/client/cli/tx.go index ced8284b6..8c9e0528f 100644 --- a/x/vm/client/cli/tx.go +++ b/x/vm/client/cli/tx.go @@ -3,10 +3,12 @@ package cli import ( "bufio" "fmt" + "math/big" "os" "strings" "github.com/ethereum/go-ethereum/common/hexutil" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -20,6 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/input" "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" + errortypes "github.com/cosmos/cosmos-sdk/types/errors" types2 "github.com/cosmos/cosmos-sdk/x/bank/types" ) @@ -47,22 +50,27 @@ func NewRawTxCmd() *cobra.Command { Short: "Build cosmos transaction from raw ethereum transaction", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } data, err := hexutil.Decode(args[0]) if err != nil { return errors.Wrap(err, "failed to decode ethereum tx hex bytes") } - msg := &types.MsgEthereumTx{} - if err := msg.UnmarshalBinary(data); err != nil { - return err + // verify that the chain-id entered is a base 10 integer + chainIDInt, ok := new(big.Int).SetString(clientCtx.ChainID, 10) + if !ok { + return errors.Wrapf(errortypes.ErrInvalidChainID, "epoch %s must be base-10 integer format", clientCtx.ChainID) } - if err := msg.ValidateBasic(); err != nil { + msg := &types.MsgEthereumTx{} + if err := msg.UnmarshalBinary(data, ethtypes.LatestSignerForChainID(chainIDInt)); err != nil { return err } - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { + if err := msg.ValidateBasic(); err != nil { return err } diff --git a/x/vm/keeper/msg_server.go b/x/vm/keeper/msg_server.go index 51ec2893a..2d070d0a1 100644 --- a/x/vm/keeper/msg_server.go +++ b/x/vm/keeper/msg_server.go @@ -30,7 +30,6 @@ var _ types.MsgServer = &Keeper{} func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - sender := msg.From tx := msg.AsTransaction() txIndex := k.GetTxIndexTransient(ctx) @@ -43,7 +42,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t labels = append(labels, telemetry.NewLabel("execution", "call")) } - response, err := k.ApplyTransaction(ctx, tx) + response, err := k.ApplyTransaction(ctx, msg) if err != nil { return nil, errorsmod.Wrap(err, "failed to apply transaction") } @@ -122,7 +121,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, sender), + sdk.NewAttribute(sdk.AttributeKeySender, types.HexAddress(msg.From)), sdk.NewAttribute(types.AttributeKeyTxType, fmt.Sprintf("%d", tx.Type())), ), }) diff --git a/x/vm/keeper/state_transition.go b/x/vm/keeper/state_transition.go index 041ef2342..b3feca661 100644 --- a/x/vm/keeper/state_transition.go +++ b/x/vm/keeper/state_transition.go @@ -147,7 +147,7 @@ func (k Keeper) GetHashFn(ctx sdk.Context) vm.GetHashFunc { // returning. // // For relevant discussion see: https://github.com/cosmos/cosmos-sdk/discussions/9072 -func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*types.MsgEthereumTxResponse, error) { +func (k *Keeper) ApplyTransaction(ctx sdk.Context, msgEth *types.MsgEthereumTx) (*types.MsgEthereumTxResponse, error) { var ( bloom *big.Int bloomReceipt ethtypes.Bloom @@ -157,11 +157,12 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t if err != nil { return nil, errorsmod.Wrap(err, "failed to load evm config") } - txConfig := k.TxConfig(ctx, tx.Hash()) + ethTx := msgEth.AsTransaction() + txConfig := k.TxConfig(ctx, ethTx.Hash()) // get the signer according to the chain rules from the config and block height signer := ethtypes.MakeSigner(types.GetEthChainConfig(), big.NewInt(ctx.BlockHeight()), uint64(ctx.BlockTime().Unix())) //#nosec G115 -- int overflow is not a concern here - msg, err := core.TransactionToMessage(tx, signer, cfg.BaseFee) + msg, err := core.TransactionToMessage(ethTx, signer, cfg.BaseFee) if err != nil { return nil, errorsmod.Wrap(err, "failed to return ethereum transaction as core message") } @@ -205,7 +206,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t } receipt := ðtypes.Receipt{ - Type: tx.Type(), + Type: ethTx.Type(), PostState: nil, CumulativeGasUsed: cumulativeGasUsed, Bloom: bloomReceipt, @@ -218,7 +219,7 @@ func (k *Keeper) ApplyTransaction(ctx sdk.Context, tx *ethtypes.Transaction) (*t TransactionIndex: txConfig.TxIndex, } - signerAddr, err := signer.Sender(tx) + signerAddr, err := signer.Sender(ethTx) if err != nil { return nil, errorsmod.Wrap(err, "failed to extract sender address from ethereum transaction") } diff --git a/x/vm/types/msg.go b/x/vm/types/msg.go index d05c77bcb..99d5e1e6f 100644 --- a/x/vm/types/msg.go +++ b/x/vm/types/msg.go @@ -1,6 +1,7 @@ package types import ( + "bytes" "errors" "fmt" "math/big" @@ -11,7 +12,6 @@ import ( protov2 "google.golang.org/protobuf/proto" evmapi "github.com/cosmos/evm/api/cosmos/evm/vm/v1" - "github.com/cosmos/evm/types" errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" @@ -148,6 +148,21 @@ func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) error { return nil } +// FromSignedEthereumTx populates the message fields from the given signed ethereum transaction, and set From field. +func (msg *MsgEthereumTx) FromSignedEthereumTx(tx *ethtypes.Transaction, signer ethtypes.Signer) error { + if err := msg.FromEthereumTx(tx); err != nil { + return err + } + + from, err := ethtypes.Sender(signer, tx) + if err != nil { + return err + } + + msg.From = from.Bytes() + return nil +} + // Route returns the route value of an MsgEthereumTx. func (msg MsgEthereumTx) Route() string { return RouterKey } @@ -157,10 +172,12 @@ func (msg MsgEthereumTx) Type() string { return TypeMsgEthereumTx } // ValidateBasic implements the sdk.Msg interface. It performs basic validation // checks of a Transaction. If returns an error if validation fails. func (msg MsgEthereumTx) ValidateBasic() error { - if msg.From != "" { - if err := types.ValidateAddress(msg.From); err != nil { - return errorsmod.Wrap(err, "invalid from address") - } + if len(msg.DeprecatedFrom) != 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "deprecated From field is not empty") + } + + if len(msg.From) == 0 { + return errorsmod.Wrapf(errortypes.ErrInvalidRequest, "sender address is missing") } // Validate Size_ field, should be kept empty @@ -207,6 +224,39 @@ func (msg *MsgEthereumTx) GetMsgsV2() ([]protov2.Message, error) { return nil, errors.New("not implemented") } +// GetSigners returns the expected signers for an Ethereum transaction message. +// For such a message, there should exist only a single 'signer'. +func (msg *MsgEthereumTx) GetSigners() []sdk.AccAddress { + if len(msg.From) == 0 { + return nil + } + return []sdk.AccAddress{msg.GetFrom()} +} + +// GetSender convert the From field to common.Address +// From should always be set, which is validated in ValidateBasic +func (msg *MsgEthereumTx) GetSender() common.Address { + return common.BytesToAddress(msg.From) +} + +// GetSenderLegacy fallbacks to old behavior if From is empty, should be used by json-rpc +func (msg *MsgEthereumTx) GetSenderLegacy(signer ethtypes.Signer) (common.Address, error) { + if len(msg.From) > 0 { + return msg.GetSender(), nil + } + sender, err := msg.recoverSender(signer) + if err != nil { + return common.Address{}, err + } + msg.From = sender.Bytes() + return sender, nil +} + +// recoverSender recovers the sender address from the transaction signature. +func (msg *MsgEthereumTx) recoverSender(signer ethtypes.Signer) (common.Address, error) { + return ethtypes.Sender(signer, msg.AsTransaction()) +} + // GetSignBytes returns the Amino bytes of an Ethereum transaction message used // for signing. // @@ -275,11 +325,7 @@ func (msg MsgEthereumTx) GetEffectiveFee(baseFee *big.Int) *big.Int { // GetFrom loads the ethereum sender address from the sigcache and returns an // sdk.AccAddress from its bytes func (msg *MsgEthereumTx) GetFrom() sdk.AccAddress { - if msg.From == "" { - return nil - } - - return common.HexToAddress(msg.From).Bytes() + return sdk.AccAddress(msg.From) } // AsTransaction creates an Ethereum Transaction type from the msg fields @@ -292,22 +338,50 @@ func (msg MsgEthereumTx) AsTransaction() *ethtypes.Transaction { return ethtypes.NewTx(txData.AsEthereumData()) } +func bigMin(x, y *big.Int) *big.Int { + if x.Cmp(y) > 0 { + return y + } + return x +} + // AsMessage creates an Ethereum core.Message from the msg fields -func (msg MsgEthereumTx) AsMessage(signer ethtypes.Signer, baseFee *big.Int) (*core.Message, error) { - tx := msg.AsTransaction() - return core.TransactionToMessage(tx, signer, baseFee) +func (msg MsgEthereumTx) AsMessage(baseFee *big.Int) (*core.Message, error) { + txData, err := UnpackTxData(msg.Data) + if err != nil { + return nil, err + } + + gasPrice, gasFeeCap, gasTipCap := txData.GetGasPrice(), txData.GetGasFeeCap(), txData.GetGasTipCap() + if baseFee != nil { + gasPrice = bigMin(gasPrice.Add(gasTipCap, baseFee), gasFeeCap) + } + ethMsg := core.Message{ + From: msg.GetSender(), + To: txData.GetTo(), + Nonce: txData.GetNonce(), + Value: txData.GetValue(), + GasLimit: txData.GetGas(), + GasPrice: gasPrice, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Data: txData.GetData(), + AccessList: txData.GetAccessList(), + } + return ðMsg, nil } -// GetSender extracts the sender address from the signature values using the latest signer for the given chainID. -func (msg *MsgEthereumTx) GetSender(chainID *big.Int) (common.Address, error) { - signer := ethtypes.LatestSignerForChainID(chainID) - from, err := signer.Sender(msg.AsTransaction()) +// VerifySender verify the sender address against the signature values using the latest signer for the given chainID. +func (msg *MsgEthereumTx) VerifySender(signer ethtypes.Signer) error { + from, err := msg.recoverSender(signer) if err != nil { - return common.Address{}, err + return err } - msg.From = from.Hex() - return from, nil + if !bytes.Equal(msg.From, from.Bytes()) { + return fmt.Errorf("sender verification failed. got %s, expected %s", from.String(), HexAddress(msg.From)) + } + return nil } // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces @@ -316,12 +390,12 @@ func (msg MsgEthereumTx) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error } // UnmarshalBinary decodes the canonical encoding of transactions. -func (msg *MsgEthereumTx) UnmarshalBinary(b []byte) error { +func (msg *MsgEthereumTx) UnmarshalBinary(b []byte, signer ethtypes.Signer) error { tx := ðtypes.Transaction{} if err := tx.UnmarshalBinary(b); err != nil { return err } - return msg.FromEthereumTx(tx) + return msg.FromSignedEthereumTx(tx, signer) } // BuildTx builds the canonical cosmos tx from ethereum msg @@ -349,9 +423,6 @@ func (msg *MsgEthereumTx) BuildTx(b client.TxBuilder, evmDenom string) (signing. builder.SetExtensionOptions(option) - // A valid msg should have empty `From` - msg.From = "" - err = builder.SetMsgs(msg) if err != nil { return nil, err diff --git a/x/vm/types/msg_test.go b/x/vm/types/msg_test.go index 7e020d7a6..58c4ed303 100644 --- a/x/vm/types/msg_test.go +++ b/x/vm/types/msg_test.go @@ -27,8 +27,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -const invalidAddress = "0x0000" - type MsgsTestSuite struct { suite.Suite @@ -75,7 +73,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Constructor() { suite.Require().Equal(msg.Type(), types.TypeMsgEthereumTx) // suite.Require().NotNil(msg.To()) suite.Require().Equal(msg.GetMsgs(), []sdk.Msg{msg}) - suite.Require().Panics(func() { msg.GetSignBytes() }) + suite.Require().Empty(msg.GetSigners()) evmTx2 := &types.EvmTxArgs{ Nonce: 0, @@ -185,6 +183,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass with recipient - AccessList Tx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -197,6 +196,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "pass with recipient - DynamicFee Tx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -269,18 +269,6 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { expectPass: false, errMsg: "gas limit must not be zero", }, - { - msg: "nil gas price - Legacy Tx", - to: suite.to.Hex(), - amount: hundredInt, - gasLimit: 1000, - gasPrice: nil, - gasFeeCap: nil, - gasTipCap: nil, - chainID: validChainID, - expectPass: false, - errMsg: "gas price cannot be nil", - }, { msg: "negative gas price - Legacy Tx", to: suite.to.Hex(), @@ -309,7 +297,6 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "invalid from address - Legacy Tx", to: suite.to.Hex(), - from: invalidAddress, amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -317,7 +304,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasTipCap: nil, chainID: validChainID, expectPass: false, - errMsg: "invalid from address", + errMsg: "sender address is missing", }, { msg: "out of bound gas fee - Legacy Tx", @@ -335,6 +322,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil amount - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: nil, gasLimit: 1000, gasPrice: hundredInt, @@ -347,6 +335,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative amount - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: minusOneInt, gasLimit: 1000, gasPrice: hundredInt, @@ -360,6 +349,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas limit - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 0, gasPrice: zeroInt, @@ -373,6 +363,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil gas price - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: nil, @@ -386,6 +377,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "negative gas price - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: minusOneInt, @@ -399,6 +391,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "zero gas price - AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -416,15 +409,15 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { gasPrice: zeroInt, gasFeeCap: nil, gasTipCap: nil, - from: invalidAddress, accessList: ðtypes.AccessList{}, chainID: validChainID, expectPass: false, - errMsg: "invalid from address", + errMsg: "sender address is missing", }, { msg: "chain ID not set on AccessListTx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -438,6 +431,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { { msg: "nil tx.Data - AccessList Tx", to: suite.to.Hex(), + from: suite.from.Hex(), amount: hundredInt, gasLimit: 1000, gasPrice: zeroInt, @@ -463,7 +457,9 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_ValidateBasic() { Accesses: tc.accessList, } tx := types.NewTx(evmTx) - tx.From = tc.from + if tc.from != "" { + tx.From = common.HexToAddress(tc.from).Bytes() + } // apply nil assignment here to test ValidateBasic function instead of NewTx if strings.Contains(tc.msg, "nil tx.Data") { @@ -557,7 +553,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Accesses: ðtypes.AccessList{}, }, ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { @@ -570,7 +566,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Input: []byte("test"), }, ethtypes.NewEIP155Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { @@ -583,7 +579,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Input: []byte("test"), }, ethtypes.HomesteadSigner{}, - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { @@ -596,7 +592,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Input: []byte("test"), }, ethtypes.FrontierSigner{}, - func(tx *types.MsgEthereumTx) { tx.From = suite.from.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.from.Bytes() }, true, }, { @@ -610,7 +606,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Accesses: ðtypes.AccessList{}, }, ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = "" }, + func(tx *types.MsgEthereumTx) { tx.From = []byte{} }, false, }, { @@ -624,7 +620,7 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { Accesses: ðtypes.AccessList{}, }, ethtypes.NewEIP2930Signer(suite.chainID), - func(tx *types.MsgEthereumTx) { tx.From = suite.to.Hex() }, + func(tx *types.MsgEthereumTx) { tx.From = suite.to.Bytes() }, false, }, } @@ -635,10 +631,9 @@ func (suite *MsgsTestSuite) TestMsgEthereumTx_Sign() { err := tx.Sign(tc.ethSigner, suite.signer) if tc.expectPass { suite.Require().NoError(err, "valid test %d failed: %s", i, tc.msg) - - sender, err := tx.GetSender(suite.chainID) + sender, err := tx.GetSenderLegacy(ethtypes.LatestSignerForChainID(suite.chainID)) suite.Require().NoError(err, tc.msg) - suite.Require().Equal(tx.From, sender.Hex(), tc.msg) + suite.Require().Equal(tx.From, sender.Bytes(), tc.msg) } else { suite.Require().Error(err, "invalid test %d passed: %s", i, tc.msg) } @@ -890,7 +885,7 @@ func (suite *MsgsTestSuite) TestTransactionCoding() { suite.T().Fatalf("could not sign transaction: %v", err) } // RLP - parsedTx, err := encodeDecodeBinary(tx) + parsedTx, err := encodeDecodeBinary(tx, signer.ChainID()) if err != nil { suite.T().Fatal(err) } @@ -899,13 +894,13 @@ func (suite *MsgsTestSuite) TestTransactionCoding() { } } -func encodeDecodeBinary(tx *ethtypes.Transaction) (*types.MsgEthereumTx, error) { +func encodeDecodeBinary(tx *ethtypes.Transaction, chainID *big.Int) (*types.MsgEthereumTx, error) { data, err := tx.MarshalBinary() if err != nil { return nil, fmt.Errorf("rlp encoding failed: %v", err) } parsedTx := &types.MsgEthereumTx{} - if err := parsedTx.UnmarshalBinary(data); err != nil { + if err := parsedTx.UnmarshalBinary(data, ethtypes.LatestSignerForChainID(chainID)); err != nil { return nil, fmt.Errorf("rlp decoding failed: %v", err) } return parsedTx, nil diff --git a/x/vm/types/tx.pb.go b/x/vm/types/tx.pb.go index d609deec7..8b1f695b6 100644 --- a/x/vm/types/tx.pb.go +++ b/x/vm/types/tx.pb.go @@ -42,11 +42,12 @@ type MsgEthereumTx struct { // size is the encoded storage size of the transaction (DEPRECATED) Size_ float64 `protobuf:"fixed64,2,opt,name=size,proto3" json:"-"` // hash of the transaction in hex format - Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty" rlp:"-"` - // from is the ethereum signer address in hex format. This address value is - // checked against the address derived from the signature (V, R, S) using the + Hash string `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty" rlp:"-"` + DeprecatedFrom string `protobuf:"bytes,4,opt,name=deprecated_from,json=deprecatedFrom,proto3" json:"deprecated_from,omitempty"` // Deprecated: Do not use. + // from is the bytes of ethereum signer address. This address value is checked + // against the address derived from the signature (V, R, S) using the // secp256k1 elliptic curve - From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + From []byte `protobuf:"bytes,5,opt,name=from,proto3" json:"from,omitempty"` } func (m *MsgEthereumTx) Reset() { *m = MsgEthereumTx{} } @@ -550,76 +551,78 @@ func init() { func init() { proto.RegisterFile("cosmos/evm/vm/v1/tx.proto", fileDescriptor_77a8ac5e8c9c4850) } var fileDescriptor_77a8ac5e8c9c4850 = []byte{ - // 1103 bytes of a gzipped FileDescriptorProto + // 1128 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xdf, 0x6b, 0x23, 0x45, - 0x1c, 0xef, 0x26, 0x9b, 0x5f, 0x93, 0xa8, 0xe7, 0x5e, 0x6b, 0xb7, 0xe1, 0x2e, 0x9b, 0x5b, 0xbd, - 0x33, 0x57, 0xe8, 0xae, 0x57, 0x41, 0x68, 0x7c, 0x6a, 0xae, 0x3d, 0xa9, 0xb4, 0x58, 0xd6, 0xdc, - 0x8b, 0x08, 0x75, 0xba, 0x99, 0x6e, 0x16, 0xb3, 0x3b, 0xeb, 0xce, 0x24, 0x24, 0x82, 0x20, 0xf7, - 0x24, 0x3e, 0x09, 0x3e, 0x0b, 0x3e, 0xf8, 0xa0, 0x3e, 0xf5, 0xe1, 0xf0, 0xc1, 0xbf, 0xe0, 0xf0, - 0xe9, 0x50, 0x10, 0x11, 0xc9, 0x49, 0x2a, 0x14, 0xfa, 0xe8, 0x5f, 0x20, 0x33, 0xb3, 0x49, 0x36, - 0x4d, 0xfa, 0xc3, 0x82, 0x42, 0x08, 0x33, 0xf3, 0xfd, 0x7c, 0x67, 0xbe, 0xdf, 0xcf, 0xe7, 0xb3, - 0xb3, 0x0b, 0x96, 0x6c, 0x4c, 0x3c, 0x4c, 0x4c, 0xd4, 0xf1, 0x4c, 0xf6, 0xbb, 0x67, 0xd2, 0xae, - 0x11, 0x84, 0x98, 0x62, 0xe5, 0x9a, 0x08, 0x19, 0xa8, 0xe3, 0x19, 0xec, 0x77, 0xaf, 0xf8, 0x22, - 0xf4, 0x5c, 0x1f, 0x9b, 0xfc, 0x5f, 0x80, 0x8a, 0xc5, 0xa9, 0x7c, 0x06, 0x17, 0xb1, 0xc5, 0x28, - 0xe6, 0x11, 0x87, 0x05, 0x3c, 0xe2, 0x44, 0x81, 0xe8, 0xd0, 0x3d, 0x3e, 0x33, 0xa3, 0x63, 0x44, - 0x68, 0xde, 0xc1, 0x0e, 0x16, 0xeb, 0x6c, 0x14, 0xad, 0xde, 0x70, 0x30, 0x76, 0x5a, 0xc8, 0x84, - 0x81, 0x6b, 0x42, 0xdf, 0xc7, 0x14, 0x52, 0x17, 0xfb, 0xc3, 0x9c, 0xa5, 0x28, 0xca, 0x67, 0xfb, - 0xed, 0x03, 0x13, 0xfa, 0x3d, 0x11, 0xd2, 0x7f, 0x90, 0xc0, 0x73, 0x3b, 0xc4, 0xd9, 0xa4, 0x4d, - 0x14, 0xa2, 0xb6, 0x57, 0xef, 0x2a, 0x15, 0x20, 0x37, 0x20, 0x85, 0xaa, 0x54, 0x96, 0x2a, 0xf9, - 0xd5, 0x79, 0x43, 0xe4, 0x1a, 0xc3, 0x5c, 0x63, 0xdd, 0xef, 0x59, 0x1c, 0xa1, 0x94, 0x80, 0x4c, - 0xdc, 0x8f, 0x91, 0x9a, 0x28, 0x4b, 0x15, 0xa9, 0x06, 0x4e, 0xfa, 0x9a, 0xb4, 0xf2, 0xed, 0xf1, - 0xe1, 0xb2, 0x64, 0xf1, 0x75, 0xe5, 0x15, 0x20, 0x37, 0x21, 0x69, 0xaa, 0xc9, 0xb2, 0x54, 0xc9, - 0xd5, 0xae, 0xfd, 0xdd, 0xd7, 0x32, 0x61, 0x2b, 0xa8, 0xea, 0x2b, 0x7a, 0x84, 0x62, 0x51, 0x45, - 0x01, 0xf2, 0x41, 0x88, 0x3d, 0x55, 0x66, 0x28, 0x8b, 0x8f, 0xab, 0xb7, 0x3e, 0xfb, 0x5a, 0x9b, - 0xfb, 0xfc, 0xf8, 0x70, 0x59, 0x8d, 0xb1, 0x37, 0x51, 0xa6, 0xfe, 0x5d, 0x02, 0x64, 0xb7, 0x91, - 0x03, 0xed, 0x5e, 0xbd, 0xab, 0xcc, 0x83, 0x94, 0x8f, 0x7d, 0x1b, 0xf1, 0xa2, 0x65, 0x4b, 0x4c, - 0x94, 0x37, 0x40, 0xce, 0x81, 0x8c, 0x44, 0xd7, 0x16, 0x45, 0xe6, 0x6a, 0x4b, 0xbf, 0xf7, 0xb5, - 0x05, 0xb1, 0x27, 0x69, 0x7c, 0x68, 0xb8, 0xd8, 0xf4, 0x20, 0x6d, 0x1a, 0x5b, 0x3e, 0xb5, 0xb2, - 0x0e, 0x24, 0xbb, 0x0c, 0xaa, 0x94, 0x40, 0xd2, 0x81, 0x84, 0x97, 0x2d, 0xd7, 0x0a, 0x83, 0xbe, - 0x96, 0x7d, 0x0b, 0x92, 0x6d, 0xd7, 0x73, 0xa9, 0xc5, 0x02, 0xca, 0xf3, 0x20, 0x41, 0x71, 0x54, - 0x6f, 0x82, 0x62, 0x65, 0x0d, 0xa4, 0x3a, 0xb0, 0xd5, 0x46, 0x6a, 0x8a, 0x9f, 0xf1, 0xf2, 0x99, - 0x67, 0x0c, 0xfa, 0x5a, 0x7a, 0xdd, 0xc3, 0x6d, 0x9f, 0x5a, 0x22, 0x83, 0x35, 0xcf, 0xc9, 0x4e, - 0x97, 0xa5, 0x4a, 0x21, 0xa2, 0xb5, 0x00, 0xa4, 0x8e, 0x9a, 0xe1, 0x0b, 0x52, 0x87, 0xcd, 0x42, - 0x35, 0x2b, 0x66, 0x21, 0x9b, 0x11, 0x35, 0x27, 0x66, 0xa4, 0x7a, 0x87, 0xd1, 0xf4, 0xd3, 0xe3, - 0x95, 0x74, 0xbd, 0xbb, 0x01, 0x29, 0x64, 0x84, 0x5d, 0x8f, 0x11, 0x36, 0xa4, 0x47, 0x7f, 0x96, - 0x04, 0x85, 0x75, 0xdb, 0x46, 0x84, 0x6c, 0xbb, 0x84, 0xd6, 0xbb, 0xca, 0xdb, 0x20, 0x6b, 0x37, - 0xa1, 0xeb, 0xef, 0xb9, 0x0d, 0x4e, 0x59, 0xae, 0x66, 0x9e, 0x57, 0x74, 0xe6, 0x3e, 0x03, 0x6f, - 0x6d, 0x9c, 0xf4, 0xb5, 0x8c, 0x2d, 0x86, 0x56, 0x34, 0x68, 0x8c, 0xb9, 0x4f, 0x9c, 0xc9, 0x7d, - 0xf2, 0x5f, 0x73, 0x2f, 0x9f, 0xcf, 0x7d, 0x6a, 0x9a, 0xfb, 0xf4, 0x95, 0xb9, 0xcf, 0xc4, 0xb8, - 0xff, 0x00, 0x64, 0x21, 0x27, 0x0a, 0x11, 0x35, 0x5b, 0x4e, 0x56, 0xf2, 0xab, 0x37, 0x8d, 0xd3, - 0x4f, 0xb9, 0x21, 0xa8, 0xac, 0xb7, 0x83, 0x16, 0xaa, 0xdd, 0x7e, 0xd2, 0xd7, 0xe6, 0x4e, 0xfa, - 0x1a, 0x80, 0x23, 0x7e, 0xbf, 0x7f, 0xa6, 0x81, 0x31, 0xdb, 0xc2, 0xea, 0xa3, 0x5d, 0x85, 0xba, - 0xb9, 0x09, 0x75, 0xc1, 0x84, 0xba, 0xf9, 0xa1, 0xba, 0xcb, 0xd3, 0xea, 0x2e, 0xc6, 0xd4, 0x8d, - 0x0b, 0xaa, 0x7f, 0x25, 0x83, 0xc2, 0x46, 0xcf, 0x87, 0x9e, 0x6b, 0x3f, 0x40, 0xe8, 0x7f, 0x51, - 0x78, 0x0d, 0xe4, 0x99, 0xc2, 0xd4, 0x0d, 0xf6, 0x6c, 0x18, 0x5c, 0xac, 0x31, 0xf3, 0x43, 0xdd, - 0x0d, 0xee, 0xc3, 0x60, 0x98, 0x7a, 0x80, 0x10, 0x4f, 0x95, 0x2f, 0x93, 0xfa, 0x00, 0x21, 0x96, - 0x1a, 0xf9, 0x23, 0x75, 0xbe, 0x3f, 0xd2, 0xd3, 0xfe, 0xc8, 0x5c, 0xd9, 0x1f, 0xd9, 0x33, 0xfc, - 0x91, 0xfb, 0xef, 0xfc, 0x01, 0x26, 0xfc, 0x91, 0x9f, 0xf0, 0x47, 0xe1, 0x92, 0xfe, 0x88, 0xdb, - 0x41, 0xd7, 0x41, 0x71, 0xb3, 0x4b, 0x91, 0x4f, 0x5c, 0xec, 0xbf, 0x13, 0xf0, 0x77, 0xc3, 0xf8, - 0x2e, 0xad, 0xca, 0x6c, 0x27, 0xfd, 0x1b, 0x09, 0x2c, 0x4c, 0xdc, 0xb1, 0x16, 0x22, 0x01, 0xf6, - 0x09, 0x67, 0x82, 0x5f, 0xe4, 0x92, 0xb8, 0xa2, 0xf9, 0xb5, 0x7d, 0x17, 0xc8, 0x2d, 0xec, 0x10, - 0x35, 0xc1, 0x59, 0x58, 0x98, 0x66, 0x61, 0x1b, 0x3b, 0x16, 0x87, 0x28, 0xd7, 0x40, 0x32, 0x44, - 0x94, 0x3b, 0xa4, 0x60, 0xb1, 0xa1, 0xb2, 0x04, 0xb2, 0x1d, 0x6f, 0x0f, 0x85, 0x21, 0x0e, 0xa3, - 0x7b, 0x34, 0xd3, 0xf1, 0x36, 0xd9, 0x94, 0x85, 0x98, 0x37, 0xda, 0x04, 0x35, 0x84, 0xca, 0x56, - 0xc6, 0x81, 0xe4, 0x21, 0x41, 0x8d, 0xa8, 0xcc, 0x1f, 0x25, 0xf0, 0xc2, 0x0e, 0x71, 0x1e, 0x06, - 0x0d, 0x48, 0xd1, 0x2e, 0x0c, 0xa1, 0x47, 0xd8, 0x6d, 0x03, 0xdb, 0xb4, 0x89, 0x43, 0x97, 0xf6, - 0x22, 0xbb, 0xab, 0x3f, 0x3f, 0x5e, 0x99, 0x8f, 0x8a, 0x5a, 0x6f, 0x34, 0x42, 0x44, 0xc8, 0xbb, - 0x34, 0x74, 0x7d, 0xc7, 0x1a, 0x43, 0x95, 0x37, 0x41, 0x3a, 0xe0, 0x3b, 0x70, 0x6b, 0xe7, 0x57, - 0xd5, 0xe9, 0x36, 0xc4, 0x09, 0xb5, 0x1c, 0xd3, 0x51, 0x68, 0x15, 0xa5, 0x54, 0x57, 0x1f, 0x1d, - 0x1f, 0x2e, 0x8f, 0x37, 0x63, 0xfc, 0x6b, 0x31, 0xfe, 0xbb, 0xa6, 0x78, 0x67, 0xc5, 0x0b, 0xd5, - 0x97, 0xc0, 0xe2, 0xa9, 0xa5, 0x21, 0xc9, 0xfa, 0xaf, 0x12, 0x78, 0x69, 0x87, 0x38, 0x16, 0x72, - 0x5c, 0x42, 0x51, 0xb8, 0x1b, 0x22, 0xd7, 0x27, 0x14, 0xb6, 0x5a, 0x57, 0x6f, 0x6f, 0x0b, 0xe4, - 0x83, 0xf1, 0x36, 0x91, 0x54, 0x37, 0x66, 0xf4, 0x38, 0x02, 0xc5, 0xfb, 0x8c, 0xe7, 0x56, 0xd7, - 0xa6, 0x9b, 0xbd, 0x33, 0xa3, 0xd9, 0x19, 0xd5, 0xeb, 0x65, 0x50, 0x9a, 0x1d, 0x19, 0xb6, 0xbe, - 0xfa, 0x47, 0x02, 0x24, 0x77, 0x88, 0xa3, 0x7c, 0x02, 0x40, 0xec, 0x43, 0x44, 0x9b, 0x2e, 0x74, - 0xc2, 0x9e, 0xc5, 0x57, 0x2f, 0x00, 0x8c, 0xa8, 0xbd, 0xfd, 0xe8, 0x97, 0xbf, 0xbe, 0x4c, 0x68, - 0xfa, 0x4d, 0x73, 0xfa, 0x63, 0x2c, 0x42, 0xef, 0xd1, 0xae, 0xf2, 0x3e, 0x28, 0x4c, 0xb8, 0xea, - 0xd6, 0xcc, 0xfd, 0xe3, 0x90, 0xe2, 0xdd, 0x0b, 0x21, 0xa3, 0x87, 0xe8, 0x23, 0x70, 0x7d, 0x96, - 0xb6, 0x95, 0x99, 0x3b, 0xcc, 0x40, 0x16, 0x5f, 0xbb, 0x2c, 0x72, 0x78, 0x64, 0x31, 0xf5, 0x29, - 0x13, 0xb2, 0x56, 0x7d, 0x32, 0x28, 0x49, 0x4f, 0x07, 0x25, 0xe9, 0xcf, 0x41, 0x49, 0xfa, 0xe2, - 0xa8, 0x34, 0xf7, 0xf4, 0xa8, 0x34, 0xf7, 0xdb, 0x51, 0x69, 0xee, 0xbd, 0xb2, 0xe3, 0xd2, 0x66, - 0x7b, 0xdf, 0xb0, 0xb1, 0x67, 0x9e, 0x56, 0x93, 0xf6, 0x02, 0x44, 0xf6, 0xd3, 0xfc, 0xbb, 0xef, - 0xf5, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xda, 0x47, 0xa5, 0xd7, 0x07, 0x0b, 0x00, 0x00, + 0x1c, 0xef, 0x26, 0x9b, 0x5f, 0x93, 0x78, 0x77, 0xee, 0xb5, 0x76, 0x1b, 0xee, 0xb2, 0xb9, 0xd5, + 0x3b, 0x73, 0x95, 0x66, 0xbd, 0x0a, 0x42, 0xe3, 0x53, 0x73, 0x6d, 0xa5, 0xd2, 0x62, 0x59, 0x73, + 0x2f, 0x22, 0xc4, 0xe9, 0xee, 0x74, 0xb3, 0x98, 0xdd, 0x59, 0x77, 0x26, 0x21, 0x11, 0x04, 0xb9, + 0x27, 0xf1, 0x49, 0xf0, 0x59, 0xf0, 0xc1, 0x07, 0xf5, 0xa9, 0x0f, 0xf7, 0xe4, 0x5f, 0x70, 0xf8, + 0x74, 0x28, 0x88, 0x88, 0xe4, 0xa4, 0x15, 0x0a, 0x7d, 0xf4, 0x2f, 0x90, 0x99, 0xd9, 0x34, 0x9b, + 0x26, 0xfd, 0x61, 0x41, 0x21, 0x84, 0x99, 0xf9, 0x7e, 0xbe, 0xdf, 0x99, 0xef, 0xe7, 0xf3, 0xd9, + 0xd9, 0x05, 0x0b, 0x16, 0x26, 0x1e, 0x26, 0x06, 0xea, 0x7a, 0x06, 0xfb, 0x3d, 0x30, 0x68, 0xaf, + 0x1a, 0x84, 0x98, 0x62, 0xe5, 0x86, 0x08, 0x55, 0x51, 0xd7, 0xab, 0xb2, 0xdf, 0x83, 0xe2, 0x8b, + 0xd0, 0x73, 0x7d, 0x6c, 0xf0, 0x7f, 0x01, 0x2a, 0x16, 0x27, 0xf2, 0x19, 0x5c, 0xc4, 0xe6, 0xa3, + 0x98, 0x47, 0x1c, 0x16, 0xf0, 0x88, 0x13, 0x05, 0xa2, 0x4d, 0x9b, 0x7c, 0x66, 0x44, 0xdb, 0x88, + 0xd0, 0xac, 0x83, 0x1d, 0x2c, 0xd6, 0xd9, 0x28, 0x5a, 0xbd, 0xe5, 0x60, 0xec, 0xb4, 0x91, 0x01, + 0x03, 0xd7, 0x80, 0xbe, 0x8f, 0x29, 0xa4, 0x2e, 0xf6, 0x87, 0x39, 0x0b, 0x51, 0x94, 0xcf, 0x76, + 0x3b, 0x7b, 0x06, 0xf4, 0xfb, 0x22, 0xa4, 0x1f, 0x4a, 0xe0, 0x85, 0x6d, 0xe2, 0xac, 0xd3, 0x16, + 0x0a, 0x51, 0xc7, 0x6b, 0xf4, 0x94, 0x0a, 0x90, 0x6d, 0x48, 0xa1, 0x2a, 0x95, 0xa5, 0x4a, 0x7e, + 0x79, 0xb6, 0x2a, 0x72, 0xab, 0xc3, 0xdc, 0xea, 0xaa, 0xdf, 0x37, 0x39, 0x42, 0x29, 0x01, 0x99, + 0xb8, 0x9f, 0x20, 0x35, 0x51, 0x96, 0x2a, 0x52, 0x1d, 0x1c, 0x0f, 0x34, 0x69, 0xe9, 0xbb, 0xa3, + 0xfd, 0x45, 0xc9, 0xe4, 0xeb, 0xca, 0x2b, 0x40, 0x6e, 0x41, 0xd2, 0x52, 0x93, 0x65, 0xa9, 0x92, + 0xab, 0xdf, 0xf8, 0x7b, 0xa0, 0x65, 0xc2, 0x76, 0x50, 0xd3, 0x97, 0xf4, 0x08, 0xc5, 0xa2, 0xca, + 0x6b, 0xe0, 0xba, 0x8d, 0x82, 0x10, 0x59, 0x90, 0x22, 0xbb, 0xb9, 0x17, 0x62, 0x4f, 0x95, 0x79, + 0x42, 0x42, 0x95, 0xcc, 0x6b, 0xa3, 0xd0, 0x46, 0x88, 0x3d, 0x45, 0x01, 0x32, 0x47, 0xa4, 0xca, + 0x52, 0xa5, 0x60, 0xf2, 0x71, 0xed, 0xce, 0xe7, 0xdf, 0x68, 0x33, 0x5f, 0x1c, 0xed, 0x2f, 0xaa, + 0x31, 0xaa, 0xc7, 0x7a, 0xd2, 0xbf, 0x4f, 0x80, 0xec, 0x16, 0x72, 0xa0, 0xd5, 0x6f, 0xf4, 0x94, + 0x59, 0x90, 0xf2, 0xb1, 0x6f, 0x21, 0xde, 0xa1, 0x6c, 0x8a, 0x89, 0xf2, 0x26, 0xc8, 0x39, 0x90, + 0x31, 0xee, 0x5a, 0xa2, 0xa3, 0x5c, 0x7d, 0xe1, 0xf7, 0x81, 0x36, 0x27, 0x6a, 0x12, 0xfb, 0xa3, + 0xaa, 0x8b, 0x0d, 0x0f, 0xd2, 0x56, 0x75, 0xd3, 0xa7, 0x66, 0xd6, 0x81, 0x64, 0x87, 0x41, 0x95, + 0x12, 0x48, 0x3a, 0x90, 0xf0, 0x1e, 0xe5, 0x7a, 0xe1, 0x60, 0xa0, 0x65, 0xdf, 0x86, 0x64, 0xcb, + 0xf5, 0x5c, 0x6a, 0xb2, 0x80, 0x72, 0x0d, 0x24, 0x28, 0x16, 0x1d, 0x99, 0x09, 0x8a, 0x95, 0x15, + 0x90, 0xea, 0xc2, 0x76, 0x07, 0xf1, 0x16, 0x72, 0xf5, 0x97, 0xcf, 0xdc, 0xe3, 0x60, 0xa0, 0xa5, + 0x57, 0x3d, 0xdc, 0xf1, 0xa9, 0x29, 0x32, 0x58, 0xf3, 0x5c, 0x99, 0xb4, 0x68, 0x9e, 0x6b, 0x50, + 0x00, 0x52, 0x57, 0xcd, 0xf0, 0x05, 0xa9, 0xcb, 0x66, 0xa1, 0x9a, 0x15, 0xb3, 0x90, 0xcd, 0x88, + 0x9a, 0x13, 0x33, 0x52, 0xbb, 0xc7, 0x68, 0xfa, 0xe9, 0xc9, 0x52, 0xba, 0xd1, 0x5b, 0x83, 0x14, + 0x32, 0xc2, 0x6e, 0xc6, 0x08, 0x1b, 0xd2, 0xa3, 0x3f, 0x4f, 0x82, 0xc2, 0xaa, 0x65, 0x21, 0x42, + 0xb6, 0x5c, 0x42, 0x1b, 0x3d, 0xe5, 0x1d, 0x90, 0xb5, 0x5a, 0xd0, 0xf5, 0x9b, 0xae, 0xcd, 0x29, + 0xcb, 0xd5, 0x8d, 0xf3, 0x0e, 0x9d, 0x79, 0xc8, 0xc0, 0x9b, 0x6b, 0xc7, 0x03, 0x2d, 0x63, 0x89, + 0xa1, 0x19, 0x0d, 0xec, 0x11, 0xf7, 0x89, 0x33, 0xb9, 0x4f, 0xfe, 0x6b, 0xee, 0xe5, 0xf3, 0xb9, + 0x4f, 0x4d, 0x72, 0x9f, 0xbe, 0x32, 0xf7, 0x99, 0x18, 0xf7, 0x1f, 0x82, 0x2c, 0xe4, 0x44, 0x21, + 0xa2, 0x66, 0xcb, 0xc9, 0x4a, 0x7e, 0xf9, 0x76, 0xf5, 0xf4, 0x95, 0x50, 0x15, 0x54, 0x36, 0x3a, + 0x41, 0x1b, 0xd5, 0xef, 0x3e, 0x1d, 0x68, 0x33, 0xc7, 0x03, 0x0d, 0xc0, 0x13, 0x7e, 0x7f, 0x78, + 0xae, 0x81, 0x11, 0xdb, 0xe2, 0xb9, 0x38, 0xa9, 0x2a, 0xd4, 0xcd, 0x8d, 0xa9, 0x0b, 0xc6, 0xd4, + 0xcd, 0x0f, 0xd5, 0x5d, 0x9c, 0x54, 0x77, 0x3e, 0xa6, 0x6e, 0x5c, 0x50, 0xfd, 0x6b, 0x19, 0x14, + 0xd6, 0xfa, 0x3e, 0xf4, 0x5c, 0x6b, 0x03, 0xa1, 0xff, 0x45, 0xe1, 0x15, 0x90, 0x67, 0x0a, 0x53, + 0x37, 0x68, 0x5a, 0x30, 0xb8, 0x58, 0x63, 0xe6, 0x87, 0x86, 0x1b, 0x3c, 0x84, 0xc1, 0x30, 0x75, + 0x0f, 0x21, 0x9e, 0x2a, 0x5f, 0x26, 0x75, 0x03, 0x21, 0x96, 0x1a, 0xf9, 0x23, 0x75, 0xbe, 0x3f, + 0xd2, 0x93, 0xfe, 0xc8, 0x5c, 0xd9, 0x1f, 0xd9, 0x33, 0xfc, 0x91, 0xfb, 0xef, 0xfc, 0x01, 0xc6, + 0xfc, 0x91, 0x1f, 0xf3, 0x47, 0xe1, 0x92, 0xfe, 0x88, 0xdb, 0x41, 0xd7, 0x41, 0x71, 0xbd, 0x47, + 0x91, 0x4f, 0x5c, 0xec, 0xbf, 0x1b, 0xf0, 0x17, 0xc9, 0xe8, 0x2e, 0xad, 0xc9, 0xac, 0x92, 0xfe, + 0xad, 0x04, 0xe6, 0xc6, 0xee, 0x58, 0x13, 0x91, 0x00, 0xfb, 0x84, 0x33, 0xc1, 0x6f, 0x7d, 0x6e, + 0xa4, 0xe8, 0x8e, 0xbf, 0x0f, 0xe4, 0x36, 0x76, 0x88, 0x9a, 0xe0, 0x2c, 0xcc, 0x4d, 0xb2, 0xb0, + 0x85, 0x1d, 0x93, 0x43, 0x94, 0x1b, 0x20, 0x19, 0x22, 0xca, 0x1d, 0x52, 0x30, 0xd9, 0x50, 0x59, + 0x00, 0xd9, 0xae, 0xd7, 0x44, 0x61, 0x88, 0xc3, 0xe8, 0x1e, 0xcd, 0x74, 0xbd, 0x75, 0x36, 0x65, + 0x21, 0xe6, 0x8d, 0x0e, 0x41, 0xb6, 0x50, 0xd9, 0xcc, 0x38, 0x90, 0x3c, 0x22, 0xc8, 0x8e, 0x8e, + 0xf9, 0xa3, 0x04, 0xae, 0x6f, 0x13, 0xe7, 0x51, 0x60, 0x43, 0x8a, 0x76, 0x60, 0x08, 0x3d, 0xc2, + 0x6e, 0x1b, 0xd8, 0xa1, 0x2d, 0x1c, 0xba, 0xb4, 0x1f, 0xd9, 0x5d, 0xfd, 0xf9, 0xc9, 0xd2, 0x6c, + 0x74, 0xa8, 0x55, 0xdb, 0x0e, 0x11, 0x21, 0xef, 0xd1, 0xd0, 0xf5, 0x1d, 0x73, 0x04, 0x55, 0xde, + 0x02, 0xe9, 0x80, 0x57, 0xe0, 0xd6, 0xce, 0x2f, 0xab, 0x93, 0x6d, 0x88, 0x1d, 0xea, 0x39, 0xa6, + 0xa3, 0xd0, 0x2a, 0x4a, 0xa9, 0x2d, 0x3f, 0x3e, 0xda, 0x5f, 0x1c, 0x15, 0x63, 0xfc, 0x6b, 0x31, + 0xfe, 0x7b, 0x86, 0x78, 0x67, 0xc5, 0x0f, 0xaa, 0x2f, 0x80, 0xf9, 0x53, 0x4b, 0x43, 0x92, 0xf5, + 0x5f, 0x25, 0xf0, 0xd2, 0x36, 0x71, 0x4c, 0xe4, 0xb8, 0x84, 0xa2, 0x70, 0x27, 0x44, 0xae, 0x4f, + 0x28, 0x6c, 0xb7, 0xaf, 0xde, 0xde, 0x26, 0xc8, 0x07, 0xa3, 0x32, 0x91, 0x54, 0xb7, 0xa6, 0xf4, + 0x78, 0x02, 0x8a, 0xf7, 0x19, 0xcf, 0xad, 0xad, 0x4c, 0x36, 0x7b, 0x6f, 0x4a, 0xb3, 0x53, 0x4e, + 0xaf, 0x97, 0x41, 0x69, 0x7a, 0x64, 0xd8, 0xfa, 0xf2, 0x1f, 0x09, 0x90, 0xdc, 0x26, 0x8e, 0xf2, + 0x29, 0x00, 0xb1, 0xaf, 0x16, 0x6d, 0xf2, 0xa0, 0x63, 0xf6, 0x2c, 0xbe, 0x7a, 0x01, 0xe0, 0x84, + 0xda, 0xbb, 0x8f, 0x7f, 0xf9, 0xeb, 0xab, 0x84, 0xa6, 0xdf, 0x36, 0x26, 0xbf, 0xdc, 0x22, 0x74, + 0x93, 0xf6, 0x94, 0x0f, 0x40, 0x61, 0xcc, 0x55, 0x77, 0xa6, 0xd6, 0x8f, 0x43, 0x8a, 0xf7, 0x2f, + 0x84, 0x9c, 0x3c, 0x44, 0x1f, 0x83, 0x9b, 0xd3, 0xb4, 0xad, 0x4c, 0xad, 0x30, 0x05, 0x59, 0x7c, + 0xfd, 0xb2, 0xc8, 0xe1, 0x96, 0xc5, 0xd4, 0x67, 0x4c, 0xc8, 0x7a, 0xed, 0xe9, 0x41, 0x49, 0x7a, + 0x76, 0x50, 0x92, 0xfe, 0x3c, 0x28, 0x49, 0x5f, 0x1e, 0x96, 0x66, 0x9e, 0x1d, 0x96, 0x66, 0x7e, + 0x3b, 0x2c, 0xcd, 0xbc, 0x5f, 0x76, 0x5c, 0xda, 0xea, 0xec, 0x56, 0x2d, 0xec, 0x19, 0xa7, 0xd5, + 0xa4, 0xfd, 0x00, 0x91, 0xdd, 0x34, 0xff, 0x48, 0x7c, 0xe3, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x8a, 0x31, 0x4a, 0xe9, 0x34, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -813,6 +816,13 @@ func (m *MsgEthereumTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.From) i = encodeVarintTx(dAtA, i, uint64(len(m.From))) i-- + dAtA[i] = 0x2a + } + if len(m.DeprecatedFrom) > 0 { + i -= len(m.DeprecatedFrom) + copy(dAtA[i:], m.DeprecatedFrom) + i = encodeVarintTx(dAtA, i, uint64(len(m.DeprecatedFrom))) + i-- dAtA[i] = 0x22 } if len(m.Hash) > 0 { @@ -1427,6 +1437,10 @@ func (m *MsgEthereumTx) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.DeprecatedFrom) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } l = len(m.From) if l > 0 { n += 1 + l + sovTx(uint64(l)) @@ -1794,7 +1808,7 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DeprecatedFrom", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1822,7 +1836,41 @@ func (m *MsgEthereumTx) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.From = string(dAtA[iNdEx:postIndex]) + m.DeprecatedFrom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = append(m.From[:0], dAtA[iNdEx:postIndex]...) + if m.From == nil { + m.From = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/vm/types/tx_args.go b/x/vm/types/tx_args.go index e0ad56cb1..c4acdc11d 100644 --- a/x/vm/types/tx_args.go +++ b/x/vm/types/tx_args.go @@ -72,7 +72,8 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { var ( chainID, value, gasPrice, maxFeePerGas, maxPriorityFeePerGas sdkmath.Int gas, nonce uint64 - from, to string + from []byte + to string ) // Set sender address or use zero address if none specified. @@ -155,7 +156,7 @@ func (args *TransactionArgs) ToTransaction() *MsgEthereumTx { } if args.From != nil { - from = args.From.Hex() + from = args.From.Bytes() } msg := MsgEthereumTx{ diff --git a/x/vm/types/utils.go b/x/vm/types/utils.go index dd345b27b..dd819d54b 100644 --- a/x/vm/types/utils.go +++ b/x/vm/types/utils.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "encoding/hex" "fmt" "math/big" "sort" @@ -138,6 +139,14 @@ func EffectiveGasPrice(baseFee, feeCap, tipCap *big.Int) *big.Int { return feeCap } +// HexAddress encode ethereum address without checksum, faster to run for state machine +func HexAddress(a []byte) string { + var buf [common.AddressLength*2 + 2]byte + copy(buf[:2], "0x") + hex.Encode(buf[2:], a) + return string(buf[:]) +} + // SortedKVStoreKeys returns a slice of *KVStoreKey sorted by their map key. func SortedKVStoreKeys(keys map[string]*storetypes.KVStoreKey) []*storetypes.KVStoreKey { names := make([]string, 0, len(keys))