Co-authored-by: son trinh <trinhleson2000@gmail.com>
This commit is contained in:
parent
029d6e5106
commit
7d801cc3c9
@ -61,6 +61,7 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
|
||||
* (client) [#19870](https://github.com/cosmos/cosmos-sdk/pull/19870) Add new query command `wait-tx`. Alias `event-query-tx-for` to `wait-tx` for backward compatibility.
|
||||
* (crypto/keyring) [#20212](https://github.com/cosmos/cosmos-sdk/pull/20212) Expose the db keyring used in the keystore.
|
||||
* (genutil) [#19971](https://github.com/cosmos/cosmos-sdk/pull/19971) Allow manually setting the consensus key type in genesis
|
||||
* (client/tx) [#20870](https://github.com/cosmos/cosmos-sdk/pull/20870) Add `timeout-timestamp` field for tx body defines time based timeout.Add `WithTimeoutTimestamp` to tx factory. Increased gas cost for processing newly added timeout timestamp field in tx body.
|
||||
|
||||
### Improvements
|
||||
|
||||
@ -199,12 +200,13 @@ Every module contains its own CHANGELOG.md. Please refer to the module you are i
|
||||
|
||||
### Client Breaking Changes
|
||||
|
||||
* (runtime) [#19040](https://github.com/cosmos/cosmos-sdk/pull/19040) Simplify app config implementation and deprecate `/cosmos/app/v1alpha1/config` query.
|
||||
* (runtime) [#19040](https://github.com/cosmos/cosmos-sdk/pull/19040) Simplify app config implementation and deprecate `/cosmos/app/v1alpha1/config` query.
|
||||
|
||||
### CLI Breaking Changes
|
||||
|
||||
* (perf)[#20490](https://github.com/cosmos/cosmos-sdk/pull/20490) Sims: Replace runsim command with Go stdlib testing. CLI: `Commit` default true, `Lean`, `SimulateEveryOperation`, `PrintAllInvariants`, `DBBackend` params removed
|
||||
* (server) [#18303](https://github.com/cosmos/cosmos-sdk/pull/18303) `appd export` has moved with other genesis commands, use `appd genesis export` instead.
|
||||
* (client/tx) [#20870](https://github.com/cosmos/cosmos-sdk/pull/20870) Removed `timeout-height` flag replace with `timeout-timestamp` flag for a time based timeout.
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ transactions in your application:
|
||||
anteDecorators := []sdk.AnteDecorator{
|
||||
ante.NewSetUpContextDecorator(),
|
||||
// ...
|
||||
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, app.UnorderedTxManager),
|
||||
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.TxManager, options.Environment),
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
protoiface "google.golang.org/protobuf/runtime/protoiface"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
io "io"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
@ -2768,6 +2769,7 @@ var (
|
||||
fd_TxBody_memo protoreflect.FieldDescriptor
|
||||
fd_TxBody_timeout_height protoreflect.FieldDescriptor
|
||||
fd_TxBody_unordered protoreflect.FieldDescriptor
|
||||
fd_TxBody_timeout_timestamp protoreflect.FieldDescriptor
|
||||
fd_TxBody_extension_options protoreflect.FieldDescriptor
|
||||
fd_TxBody_non_critical_extension_options protoreflect.FieldDescriptor
|
||||
)
|
||||
@ -2779,6 +2781,7 @@ func init() {
|
||||
fd_TxBody_memo = md_TxBody.Fields().ByName("memo")
|
||||
fd_TxBody_timeout_height = md_TxBody.Fields().ByName("timeout_height")
|
||||
fd_TxBody_unordered = md_TxBody.Fields().ByName("unordered")
|
||||
fd_TxBody_timeout_timestamp = md_TxBody.Fields().ByName("timeout_timestamp")
|
||||
fd_TxBody_extension_options = md_TxBody.Fields().ByName("extension_options")
|
||||
fd_TxBody_non_critical_extension_options = md_TxBody.Fields().ByName("non_critical_extension_options")
|
||||
}
|
||||
@ -2872,6 +2875,12 @@ func (x *fastReflection_TxBody) Range(f func(protoreflect.FieldDescriptor, proto
|
||||
return
|
||||
}
|
||||
}
|
||||
if x.TimeoutTimestamp != nil {
|
||||
value := protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect())
|
||||
if !f(fd_TxBody_timeout_timestamp, value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if len(x.ExtensionOptions) != 0 {
|
||||
value := protoreflect.ValueOfList(&_TxBody_1023_list{list: &x.ExtensionOptions})
|
||||
if !f(fd_TxBody_extension_options, value) {
|
||||
@ -2907,6 +2916,8 @@ func (x *fastReflection_TxBody) Has(fd protoreflect.FieldDescriptor) bool {
|
||||
return x.TimeoutHeight != uint64(0)
|
||||
case "cosmos.tx.v1beta1.TxBody.unordered":
|
||||
return x.Unordered != false
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
return x.TimeoutTimestamp != nil
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
return len(x.ExtensionOptions) != 0
|
||||
case "cosmos.tx.v1beta1.TxBody.non_critical_extension_options":
|
||||
@ -2935,6 +2946,8 @@ func (x *fastReflection_TxBody) Clear(fd protoreflect.FieldDescriptor) {
|
||||
x.TimeoutHeight = uint64(0)
|
||||
case "cosmos.tx.v1beta1.TxBody.unordered":
|
||||
x.Unordered = false
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
x.TimeoutTimestamp = nil
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
x.ExtensionOptions = nil
|
||||
case "cosmos.tx.v1beta1.TxBody.non_critical_extension_options":
|
||||
@ -2970,6 +2983,9 @@ func (x *fastReflection_TxBody) Get(descriptor protoreflect.FieldDescriptor) pro
|
||||
case "cosmos.tx.v1beta1.TxBody.unordered":
|
||||
value := x.Unordered
|
||||
return protoreflect.ValueOfBool(value)
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
value := x.TimeoutTimestamp
|
||||
return protoreflect.ValueOfMessage(value.ProtoReflect())
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
if len(x.ExtensionOptions) == 0 {
|
||||
return protoreflect.ValueOfList(&_TxBody_1023_list{})
|
||||
@ -3012,6 +3028,8 @@ func (x *fastReflection_TxBody) Set(fd protoreflect.FieldDescriptor, value proto
|
||||
x.TimeoutHeight = value.Uint()
|
||||
case "cosmos.tx.v1beta1.TxBody.unordered":
|
||||
x.Unordered = value.Bool()
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
x.TimeoutTimestamp = value.Message().Interface().(*timestamppb.Timestamp)
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
lv := value.List()
|
||||
clv := lv.(*_TxBody_1023_list)
|
||||
@ -3046,6 +3064,11 @@ func (x *fastReflection_TxBody) Mutable(fd protoreflect.FieldDescriptor) protore
|
||||
}
|
||||
value := &_TxBody_1_list{list: &x.Messages}
|
||||
return protoreflect.ValueOfList(value)
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
if x.TimeoutTimestamp == nil {
|
||||
x.TimeoutTimestamp = new(timestamppb.Timestamp)
|
||||
}
|
||||
return protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect())
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
if x.ExtensionOptions == nil {
|
||||
x.ExtensionOptions = []*anypb.Any{}
|
||||
@ -3086,6 +3109,9 @@ func (x *fastReflection_TxBody) NewField(fd protoreflect.FieldDescriptor) protor
|
||||
return protoreflect.ValueOfUint64(uint64(0))
|
||||
case "cosmos.tx.v1beta1.TxBody.unordered":
|
||||
return protoreflect.ValueOfBool(false)
|
||||
case "cosmos.tx.v1beta1.TxBody.timeout_timestamp":
|
||||
m := new(timestamppb.Timestamp)
|
||||
return protoreflect.ValueOfMessage(m.ProtoReflect())
|
||||
case "cosmos.tx.v1beta1.TxBody.extension_options":
|
||||
list := []*anypb.Any{}
|
||||
return protoreflect.ValueOfList(&_TxBody_1023_list{list: &list})
|
||||
@ -3177,6 +3203,10 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods {
|
||||
if x.Unordered {
|
||||
n += 2
|
||||
}
|
||||
if x.TimeoutTimestamp != nil {
|
||||
l = options.Size(x.TimeoutTimestamp)
|
||||
n += 1 + l + runtime.Sov(uint64(l))
|
||||
}
|
||||
if len(x.ExtensionOptions) > 0 {
|
||||
for _, e := range x.ExtensionOptions {
|
||||
l = options.Size(e)
|
||||
@ -3254,6 +3284,20 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods {
|
||||
dAtA[i] = 0xfa
|
||||
}
|
||||
}
|
||||
if x.TimeoutTimestamp != nil {
|
||||
encoded, err := options.Marshal(x.TimeoutTimestamp)
|
||||
if err != nil {
|
||||
return protoiface.MarshalOutput{
|
||||
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
|
||||
Buf: input.Buf,
|
||||
}, err
|
||||
}
|
||||
i -= len(encoded)
|
||||
copy(dAtA[i:], encoded)
|
||||
i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded)))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
if x.Unordered {
|
||||
i--
|
||||
if x.Unordered {
|
||||
@ -3446,6 +3490,42 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods {
|
||||
}
|
||||
}
|
||||
x.Unordered = bool(v != 0)
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType)
|
||||
}
|
||||
var msglen 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++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
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
|
||||
}
|
||||
if x.TimeoutTimestamp == nil {
|
||||
x.TimeoutTimestamp = ×tamppb.Timestamp{}
|
||||
}
|
||||
if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.TimeoutTimestamp); err != nil {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 1023:
|
||||
if wireType != 2 {
|
||||
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtensionOptions", wireType)
|
||||
@ -8471,10 +8551,6 @@ type TxBody struct {
|
||||
Memo string `protobuf:"bytes,2,opt,name=memo,proto3" json:"memo,omitempty"`
|
||||
// timeout_height is the block height after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
TimeoutHeight uint64 `protobuf:"varint,3,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty"`
|
||||
// unordered, when set to true, indicates that the transaction signer(s)
|
||||
// intend for the transaction to be evaluated and executed in an un-ordered
|
||||
@ -8482,10 +8558,17 @@ type TxBody struct {
|
||||
// incremented, which allows for fire-and-forget as well as concurrent
|
||||
// transaction execution.
|
||||
//
|
||||
// Note, when set to true, the existing 'timeout_height' value must be set and
|
||||
// will be used to correspond to a height in which the transaction is deemed
|
||||
// Note, when set to true, the existing 'timeout_height' value must
|
||||
// be set and will be used to correspond to a time_stamp in which the transaction is deemed
|
||||
// valid.
|
||||
Unordered bool `protobuf:"varint,4,opt,name=unordered,proto3" json:"unordered,omitempty"`
|
||||
// timeout_timestamp is the block time after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
TimeoutTimestamp *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"`
|
||||
// extension_options are arbitrary options that can be added by chains
|
||||
// when the default options are not sufficient. If any of these are present
|
||||
// and can't be handled, the transaction will be rejected
|
||||
@ -8544,6 +8627,13 @@ func (x *TxBody) GetUnordered() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *TxBody) GetTimeoutTimestamp() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.TimeoutTimestamp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *TxBody) GetExtensionOptions() []*anypb.Any {
|
||||
if x != nil {
|
||||
return x.ExtensionOptions
|
||||
@ -9059,128 +9149,119 @@ var file_cosmos_tx_v1beta1_tx_proto_rawDesc = []byte{
|
||||
0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x69, 0x6e, 0x67, 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, 0x8d, 0x01, 0x0a, 0x02, 0x54, 0x78, 0x12, 0x2d, 0x0a,
|
||||
0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f,
|
||||
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e,
|
||||
0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x38, 0x0a, 0x09,
|
||||
0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61, 0x75,
|
||||
0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x05, 0x54, 0x78, 0x52, 0x61, 0x77, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x26,
|
||||
0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, 0x79, 0x74, 0x65,
|
||||
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x44,
|
||||
0x6f, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65,
|
||||
0x73, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62,
|
||||
0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
|
||||
0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x87, 0x02, 0x0a, 0x10,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75, 0x78,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x02, 0x54, 0x78, 0x12, 0x2d,
|
||||
0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x38, 0x0a,
|
||||
0x09, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61,
|
||||
0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x05, 0x54, 0x78, 0x52, 0x61, 0x77,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
|
||||
0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 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, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69,
|
||||
0x63, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12,
|
||||
0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65,
|
||||
0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e,
|
||||
0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e,
|
||||
0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69, 0x70,
|
||||
0x3a, 0x13, 0xd2, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b,
|
||||
0x20, 0x30, 0x2e, 0x34, 0x36, 0x22, 0xb3, 0x02, 0x0a, 0x06, 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79,
|
||||
0x12, 0x30, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
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, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75,
|
||||
0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x75, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x09, 0x75, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x11, 0x65,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x18, 0xff, 0x07, 0x20, 0x03, 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, 0x10, 0x65,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
|
||||
0x5a, 0x0a, 0x1e, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f,
|
||||
0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x18, 0xff, 0x0f, 0x20, 0x03, 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, 0x1b,
|
||||
0x6e, 0x6f, 0x6e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xb7, 0x01, 0x0a, 0x08,
|
||||
0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d,
|
||||
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x03, 0x66, 0x65,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x52,
|
||||
0x03, 0x66, 0x65, 0x65, 0x12, 0x3f, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x15, 0x18, 0x01, 0xda, 0xb4, 0x2d,
|
||||
0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x36,
|
||||
0x52, 0x03, 0x74, 0x69, 0x70, 0x22, 0x97, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b,
|
||||
0x65, 0x79, 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, 0x09,
|
||||
0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x6d, 0x6f, 0x64,
|
||||
0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x65, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22,
|
||||
0xe0, 0x02, 0x0a, 0x08, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x06,
|
||||
0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65,
|
||||
0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x75,
|
||||
0x6c, 0x74, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f,
|
||||
0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x48, 0x00, 0x52, 0x05,
|
||||
0x6d, 0x75, 0x6c, 0x74, 0x69, 0x1a, 0x41, 0x0a, 0x06, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12,
|
||||
0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e,
|
||||
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f,
|
||||
0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x90, 0x01, 0x0a, 0x05, 0x4d, 0x75, 0x6c,
|
||||
0x74, 0x69, 0x12, 0x4b, 0x0a, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72,
|
||||
0x79, 0x70, 0x74, 0x6f, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x69, 0x67, 0x2e, 0x76, 0x31,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42, 0x69, 0x74,
|
||||
0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x12,
|
||||
0x3a, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e,
|
||||
0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x42, 0x05, 0x0a, 0x03, 0x73,
|
||||
0x75, 0x6d, 0x22, 0x81, 0x02, 0x0a, 0x03, 0x46, 0x65, 0x65, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d,
|
||||
0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67,
|
||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65,
|
||||
0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61,
|
||||
0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61,
|
||||
0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d,
|
||||
0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d,
|
||||
0x69, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 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, 0x05, 0x70, 0x61, 0x79,
|
||||
0x65, 0x72, 0x12, 0x32, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x04, 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, 0x07, 0x67,
|
||||
0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x22, 0xc9, 0x01, 0x0a, 0x03, 0x54, 0x69, 0x70, 0x12, 0x79,
|
||||
0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, 0x79, 0x74,
|
||||
0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61,
|
||||
0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x44, 0x6f, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65,
|
||||
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74,
|
||||
0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f,
|
||||
0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74,
|
||||
0x68, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68,
|
||||
0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68,
|
||||
0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61,
|
||||
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x87, 0x02, 0x0a,
|
||||
0x10, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75,
|
||||
0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73,
|
||||
0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02,
|
||||
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, 0x09, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64,
|
||||
0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62,
|
||||
0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
|
||||
0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69,
|
||||
0x70, 0x3a, 0x13, 0xd2, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64,
|
||||
0x6b, 0x20, 0x30, 0x2e, 0x34, 0x36, 0x22, 0x86, 0x03, 0x0a, 0x06, 0x54, 0x78, 0x42, 0x6f, 0x64,
|
||||
0x79, 0x12, 0x30, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 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, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f,
|
||||
0x75, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x75, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x09, 0x75, 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x11,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
|
||||
0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x42, 0x08, 0xc8, 0xde, 0x1f, 0x01, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x10, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
|
||||
0x42, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x18, 0xff, 0x07, 0x20, 0x03, 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, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x1e, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x69,
|
||||
0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xff, 0x0f, 0x20, 0x03, 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, 0x1b, 0x6e, 0x6f, 0x6e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45,
|
||||
0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
|
||||
0xb7, 0x01, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x0c,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76,
|
||||
0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x28,
|
||||
0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f,
|
||||
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e,
|
||||
0x46, 0x65, 0x65, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, 0x3f, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74,
|
||||
0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x15, 0x18,
|
||||
0x01, 0xda, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20,
|
||||
0x30, 0x2e, 0x34, 0x36, 0x52, 0x03, 0x74, 0x69, 0x70, 0x22, 0x97, 0x01, 0x0a, 0x0a, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 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, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a,
|
||||
0x09, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6d,
|
||||
0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65,
|
||||
0x6e, 0x63, 0x65, 0x22, 0xe0, 0x02, 0x0a, 0x08, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x12, 0x3c, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x69,
|
||||
0x6e, 0x67, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x39,
|
||||
0x0a, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
|
||||
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69,
|
||||
0x48, 0x00, 0x52, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x1a, 0x41, 0x0a, 0x06, 0x53, 0x69, 0x6e,
|
||||
0x67, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x90, 0x01, 0x0a,
|
||||
0x05, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x12, 0x4b, 0x0a, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72, 0x72,
|
||||
0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x69,
|
||||
0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63,
|
||||
0x74, 0x42, 0x69, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72,
|
||||
0x72, 0x61, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
|
||||
0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x42,
|
||||
0x05, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x22, 0x81, 0x02, 0x0a, 0x03, 0x46, 0x65, 0x65, 0x12, 0x79,
|
||||
0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa,
|
||||
@ -9188,38 +9269,54 @@ var file_cosmos_tx_v1beta1_tx_proto_rawDesc = []byte{
|
||||
0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f,
|
||||
0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c,
|
||||
0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a,
|
||||
0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x69, 0x70,
|
||||
0x70, 0x65, 0x72, 0x18, 0x02, 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, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x3a, 0x15, 0x18, 0x01, 0xd2,
|
||||
0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e,
|
||||
0x34, 0x36, 0x22, 0xe3, 0x01, 0x0a, 0x0d, 0x41, 0x75, 0x78, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72,
|
||||
0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
|
||||
0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73,
|
||||
0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61,
|
||||
0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18,
|
||||
0x03, 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,
|
||||
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x08, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x5f, 0x64, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75, 0x78, 0x52,
|
||||
0x07, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e,
|
||||
0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64,
|
||||
0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
|
||||
0x73, 0x69, 0x67, 0x3a, 0x13, 0xd2, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d,
|
||||
0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x36, 0x42, 0xb4, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d,
|
||||
0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x18, 0x04, 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, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x22, 0xc9, 0x01, 0x0a, 0x03, 0x54,
|
||||
0x69, 0x70, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65,
|
||||
0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8,
|
||||
0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d,
|
||||
0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a,
|
||||
0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73,
|
||||
0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a,
|
||||
0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x18, 0x02, 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, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x3a,
|
||||
0x15, 0x18, 0x01, 0xd2, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64,
|
||||
0x6b, 0x20, 0x30, 0x2e, 0x34, 0x36, 0x22, 0xe3, 0x01, 0x0a, 0x0d, 0x41, 0x75, 0x78, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 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, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x08,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x5f, 0x64, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
|
||||
0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74,
|
||||
0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63,
|
||||
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f,
|
||||
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x3b, 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x54,
|
||||
0x58, 0xaa, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54, 0x78, 0x2e, 0x56, 0x31,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54,
|
||||
0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50,
|
||||
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62,
|
||||
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74,
|
||||
0x41, 0x75, 0x78, 0x52, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x12, 0x37, 0x0a, 0x04,
|
||||
0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76,
|
||||
0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52,
|
||||
0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x3a, 0x13, 0xd2, 0xb4, 0x2d, 0x0f, 0x63, 0x6f, 0x73,
|
||||
0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x30, 0x2e, 0x34, 0x36, 0x42, 0xb4, 0x01, 0x0a,
|
||||
0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76,
|
||||
0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50,
|
||||
0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2,
|
||||
0x02, 0x03, 0x43, 0x54, 0x58, 0xaa, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54,
|
||||
0x78, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d,
|
||||
0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d,
|
||||
0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13,
|
||||
0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -9250,9 +9347,10 @@ var file_cosmos_tx_v1beta1_tx_proto_goTypes = []interface{}{
|
||||
(*ModeInfo_Single)(nil), // 11: cosmos.tx.v1beta1.ModeInfo.Single
|
||||
(*ModeInfo_Multi)(nil), // 12: cosmos.tx.v1beta1.ModeInfo.Multi
|
||||
(*anypb.Any)(nil), // 13: google.protobuf.Any
|
||||
(*v1beta12.Coin)(nil), // 14: cosmos.base.v1beta1.Coin
|
||||
(v1beta1.SignMode)(0), // 15: cosmos.tx.signing.v1beta1.SignMode
|
||||
(*v1beta11.CompactBitArray)(nil), // 16: cosmos.crypto.multisig.v1beta1.CompactBitArray
|
||||
(*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp
|
||||
(*v1beta12.Coin)(nil), // 15: cosmos.base.v1beta1.Coin
|
||||
(v1beta1.SignMode)(0), // 16: cosmos.tx.signing.v1beta1.SignMode
|
||||
(*v1beta11.CompactBitArray)(nil), // 17: cosmos.crypto.multisig.v1beta1.CompactBitArray
|
||||
}
|
||||
var file_cosmos_tx_v1beta1_tx_proto_depIdxs = []int32{
|
||||
4, // 0: cosmos.tx.v1beta1.Tx.body:type_name -> cosmos.tx.v1beta1.TxBody
|
||||
@ -9260,27 +9358,28 @@ var file_cosmos_tx_v1beta1_tx_proto_depIdxs = []int32{
|
||||
13, // 2: cosmos.tx.v1beta1.SignDocDirectAux.public_key:type_name -> google.protobuf.Any
|
||||
9, // 3: cosmos.tx.v1beta1.SignDocDirectAux.tip:type_name -> cosmos.tx.v1beta1.Tip
|
||||
13, // 4: cosmos.tx.v1beta1.TxBody.messages:type_name -> google.protobuf.Any
|
||||
13, // 5: cosmos.tx.v1beta1.TxBody.extension_options:type_name -> google.protobuf.Any
|
||||
13, // 6: cosmos.tx.v1beta1.TxBody.non_critical_extension_options:type_name -> google.protobuf.Any
|
||||
6, // 7: cosmos.tx.v1beta1.AuthInfo.signer_infos:type_name -> cosmos.tx.v1beta1.SignerInfo
|
||||
8, // 8: cosmos.tx.v1beta1.AuthInfo.fee:type_name -> cosmos.tx.v1beta1.Fee
|
||||
9, // 9: cosmos.tx.v1beta1.AuthInfo.tip:type_name -> cosmos.tx.v1beta1.Tip
|
||||
13, // 10: cosmos.tx.v1beta1.SignerInfo.public_key:type_name -> google.protobuf.Any
|
||||
7, // 11: cosmos.tx.v1beta1.SignerInfo.mode_info:type_name -> cosmos.tx.v1beta1.ModeInfo
|
||||
11, // 12: cosmos.tx.v1beta1.ModeInfo.single:type_name -> cosmos.tx.v1beta1.ModeInfo.Single
|
||||
12, // 13: cosmos.tx.v1beta1.ModeInfo.multi:type_name -> cosmos.tx.v1beta1.ModeInfo.Multi
|
||||
14, // 14: cosmos.tx.v1beta1.Fee.amount:type_name -> cosmos.base.v1beta1.Coin
|
||||
14, // 15: cosmos.tx.v1beta1.Tip.amount:type_name -> cosmos.base.v1beta1.Coin
|
||||
3, // 16: cosmos.tx.v1beta1.AuxSignerData.sign_doc:type_name -> cosmos.tx.v1beta1.SignDocDirectAux
|
||||
15, // 17: cosmos.tx.v1beta1.AuxSignerData.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode
|
||||
15, // 18: cosmos.tx.v1beta1.ModeInfo.Single.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode
|
||||
16, // 19: cosmos.tx.v1beta1.ModeInfo.Multi.bitarray:type_name -> cosmos.crypto.multisig.v1beta1.CompactBitArray
|
||||
7, // 20: cosmos.tx.v1beta1.ModeInfo.Multi.mode_infos:type_name -> cosmos.tx.v1beta1.ModeInfo
|
||||
21, // [21:21] is the sub-list for method output_type
|
||||
21, // [21:21] is the sub-list for method input_type
|
||||
21, // [21:21] is the sub-list for extension type_name
|
||||
21, // [21:21] is the sub-list for extension extendee
|
||||
0, // [0:21] is the sub-list for field type_name
|
||||
14, // 5: cosmos.tx.v1beta1.TxBody.timeout_timestamp:type_name -> google.protobuf.Timestamp
|
||||
13, // 6: cosmos.tx.v1beta1.TxBody.extension_options:type_name -> google.protobuf.Any
|
||||
13, // 7: cosmos.tx.v1beta1.TxBody.non_critical_extension_options:type_name -> google.protobuf.Any
|
||||
6, // 8: cosmos.tx.v1beta1.AuthInfo.signer_infos:type_name -> cosmos.tx.v1beta1.SignerInfo
|
||||
8, // 9: cosmos.tx.v1beta1.AuthInfo.fee:type_name -> cosmos.tx.v1beta1.Fee
|
||||
9, // 10: cosmos.tx.v1beta1.AuthInfo.tip:type_name -> cosmos.tx.v1beta1.Tip
|
||||
13, // 11: cosmos.tx.v1beta1.SignerInfo.public_key:type_name -> google.protobuf.Any
|
||||
7, // 12: cosmos.tx.v1beta1.SignerInfo.mode_info:type_name -> cosmos.tx.v1beta1.ModeInfo
|
||||
11, // 13: cosmos.tx.v1beta1.ModeInfo.single:type_name -> cosmos.tx.v1beta1.ModeInfo.Single
|
||||
12, // 14: cosmos.tx.v1beta1.ModeInfo.multi:type_name -> cosmos.tx.v1beta1.ModeInfo.Multi
|
||||
15, // 15: cosmos.tx.v1beta1.Fee.amount:type_name -> cosmos.base.v1beta1.Coin
|
||||
15, // 16: cosmos.tx.v1beta1.Tip.amount:type_name -> cosmos.base.v1beta1.Coin
|
||||
3, // 17: cosmos.tx.v1beta1.AuxSignerData.sign_doc:type_name -> cosmos.tx.v1beta1.SignDocDirectAux
|
||||
16, // 18: cosmos.tx.v1beta1.AuxSignerData.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode
|
||||
16, // 19: cosmos.tx.v1beta1.ModeInfo.Single.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode
|
||||
17, // 20: cosmos.tx.v1beta1.ModeInfo.Multi.bitarray:type_name -> cosmos.crypto.multisig.v1beta1.CompactBitArray
|
||||
7, // 21: cosmos.tx.v1beta1.ModeInfo.Multi.mode_infos:type_name -> cosmos.tx.v1beta1.ModeInfo
|
||||
22, // [22:22] is the sub-list for method output_type
|
||||
22, // [22:22] is the sub-list for method input_type
|
||||
22, // [22:22] is the sub-list for extension type_name
|
||||
22, // [22:22] is the sub-list for extension extendee
|
||||
0, // [0:22] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_cosmos_tx_v1beta1_tx_proto_init() }
|
||||
|
||||
@ -1597,19 +1597,29 @@ func TestABCI_PrepareProposal_ReachedMaxBytes(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedTxs := 8
|
||||
var expectedTxBytes int64
|
||||
|
||||
for i := 0; i < 100; i++ {
|
||||
tx2 := newTxCounter(t, suite.txConfig, int64(i), int64(i))
|
||||
err := pool.Insert(sdk.Context{}, tx2)
|
||||
require.NoError(t, err)
|
||||
|
||||
txBz, err := suite.txConfig.TxEncoder()(tx2)
|
||||
require.NoError(t, err)
|
||||
txDataSize := int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{txBz}))
|
||||
if i < expectedTxs {
|
||||
expectedTxBytes += int64(txDataSize)
|
||||
}
|
||||
}
|
||||
|
||||
reqPrepareProposal := abci.PrepareProposalRequest{
|
||||
MaxTxBytes: 1500,
|
||||
MaxTxBytes: expectedTxBytes,
|
||||
Height: 1,
|
||||
}
|
||||
resPrepareProposal, err := suite.baseApp.PrepareProposal(&reqPrepareProposal)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 8, len(resPrepareProposal.Txs))
|
||||
require.Equal(t, expectedTxs, len(resPrepareProposal.Txs))
|
||||
}
|
||||
|
||||
func TestABCI_PrepareProposal_BadEncoding(t *testing.T) {
|
||||
|
||||
@ -496,10 +496,10 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_NoOpMempoolTxSelection()
|
||||
tx := builder.GetTx()
|
||||
txBz, err := txConfig.TxEncoder()(tx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(txBz, 152)
|
||||
s.Require().Len(txBz, 165)
|
||||
|
||||
txDataSize := int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{txBz}))
|
||||
s.Require().Equal(txDataSize, 155)
|
||||
s.Require().Equal(txDataSize, 168)
|
||||
|
||||
testCases := map[string]struct {
|
||||
ctx sdk.Context
|
||||
@ -532,15 +532,15 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_NoOpMempoolTxSelection()
|
||||
Txs: [][]byte{txBz, txBz, txBz, txBz, txBz},
|
||||
MaxTxBytes: 465,
|
||||
},
|
||||
expectedTxs: 3,
|
||||
expectedTxs: 2,
|
||||
},
|
||||
"large max tx bytes len calculation": {
|
||||
ctx: s.ctx,
|
||||
req: &abci.PrepareProposalRequest{
|
||||
Txs: [][]byte{txBz, txBz, txBz, txBz, txBz},
|
||||
MaxTxBytes: 456,
|
||||
MaxTxBytes: 504,
|
||||
},
|
||||
expectedTxs: 2,
|
||||
expectedTxs: 3,
|
||||
},
|
||||
"max gas and tx bytes": {
|
||||
ctx: s.ctx.WithConsensusParams(cmtproto.ConsensusParams{
|
||||
@ -619,15 +619,15 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
|
||||
testTxs[i].size = int(cmttypes.ComputeProtoSizeForTxs([]cmttypes.Tx{bz}))
|
||||
}
|
||||
|
||||
s.Require().Equal(180, testTxs[0].size)
|
||||
s.Require().Equal(190, testTxs[1].size)
|
||||
s.Require().Equal(181, testTxs[2].size)
|
||||
s.Require().Equal(181, testTxs[3].size)
|
||||
s.Require().Equal(263, testTxs[4].size)
|
||||
s.Require().Equal(273, testTxs[5].size)
|
||||
s.Require().Equal(264, testTxs[6].size)
|
||||
s.Require().Equal(264, testTxs[7].size)
|
||||
s.Require().Equal(264, testTxs[8].size)
|
||||
s.Require().Equal(193, testTxs[0].size)
|
||||
s.Require().Equal(203, testTxs[1].size)
|
||||
s.Require().Equal(194, testTxs[2].size)
|
||||
s.Require().Equal(194, testTxs[3].size)
|
||||
s.Require().Equal(276, testTxs[4].size)
|
||||
s.Require().Equal(286, testTxs[5].size)
|
||||
s.Require().Equal(277, testTxs[6].size)
|
||||
s.Require().Equal(277, testTxs[7].size)
|
||||
s.Require().Equal(277, testTxs[8].size)
|
||||
|
||||
testCases := map[string]struct {
|
||||
ctx sdk.Context
|
||||
@ -640,7 +640,7 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
|
||||
ctx: s.ctx,
|
||||
txInputs: []testTx{testTxs[0], testTxs[1], testTxs[2], testTxs[3]},
|
||||
req: &abci.PrepareProposalRequest{
|
||||
MaxTxBytes: 180 + 181,
|
||||
MaxTxBytes: 193 + 194,
|
||||
},
|
||||
expectedTxs: []int{0, 3},
|
||||
},
|
||||
@ -648,7 +648,7 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
|
||||
ctx: s.ctx,
|
||||
txInputs: []testTx{testTxs[4], testTxs[5], testTxs[6], testTxs[7], testTxs[8]},
|
||||
req: &abci.PrepareProposalRequest{
|
||||
MaxTxBytes: 263 + 264,
|
||||
MaxTxBytes: 276 + 277,
|
||||
},
|
||||
expectedTxs: []int{4, 8},
|
||||
},
|
||||
@ -657,7 +657,7 @@ func (s *ABCIUtilsTestSuite) TestDefaultProposalHandler_PriorityNonceMempoolTxSe
|
||||
ctx: s.ctx,
|
||||
txInputs: []testTx{testTxs[9], testTxs[10], testTxs[11]},
|
||||
req: &abci.PrepareProposalRequest{
|
||||
MaxTxBytes: 263 + 264,
|
||||
MaxTxBytes: 276 + 277,
|
||||
},
|
||||
expectedTxs: []int{9},
|
||||
},
|
||||
|
||||
@ -73,7 +73,7 @@ const (
|
||||
FlagPageKey = "page-key"
|
||||
FlagOffset = "offset"
|
||||
FlagCountTotal = "count-total"
|
||||
FlagTimeoutHeight = "timeout-height"
|
||||
FlagTimeoutTimestamp = "timeout-timestamp"
|
||||
FlagUnordered = "unordered"
|
||||
FlagKeyAlgorithm = "algo"
|
||||
FlagKeyType = "key-type"
|
||||
@ -136,8 +136,8 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
|
||||
f.Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)")
|
||||
f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
|
||||
f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature")
|
||||
f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height")
|
||||
f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-height")
|
||||
f.Int64(FlagTimeoutTimestamp, 0, "Set a block timeout timestamp to prevent the tx from being committed past a certain time")
|
||||
f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-timestamp")
|
||||
f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer")
|
||||
f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction")
|
||||
f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator")
|
||||
|
||||
@ -2,9 +2,11 @@ package tx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1"
|
||||
txsigning "cosmossdk.io/x/tx/signing"
|
||||
@ -58,6 +60,14 @@ func (b *AuxTxBuilder) SetTimeoutHeight(height uint64) {
|
||||
b.auxSignerData.SignDoc.BodyBytes = nil
|
||||
}
|
||||
|
||||
// SetTimeoutTimestamp sets a timeout timestamp in the tx.
|
||||
func (b *AuxTxBuilder) SetTimeoutTimestamp(timestamp time.Time) {
|
||||
b.checkEmptyFields()
|
||||
|
||||
b.body.TimeoutTimestamp = timestamppb.New(timestamp)
|
||||
b.auxSignerData.SignDoc.BodyBytes = nil
|
||||
}
|
||||
|
||||
// SetMsgs sets an array of Msgs in the tx.
|
||||
func (b *AuxTxBuilder) SetMsgs(msgs ...sdk.Msg) error {
|
||||
anys := make([]*anypb.Any, len(msgs))
|
||||
@ -209,9 +219,10 @@ func (b *AuxTxBuilder) GetSignBytes() ([]byte, error) {
|
||||
})
|
||||
|
||||
auxBody := &txv1beta1.TxBody{
|
||||
Messages: body.Messages,
|
||||
Memo: body.Memo,
|
||||
TimeoutHeight: body.TimeoutHeight,
|
||||
Messages: body.Messages,
|
||||
Memo: body.Memo,
|
||||
TimeoutHeight: body.TimeoutHeight,
|
||||
TimeoutTimestamp: body.TimeoutTimestamp,
|
||||
// AuxTxBuilder has no concern with extension options, so we set them to nil.
|
||||
// This preserves pre-PR#16025 behavior where extension options were ignored, this code path:
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/ac3c209326a26b46f65a6cc6f5b5ebf6beb79b38/client/tx/aux_builder.go#L193
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
"github.com/spf13/pflag"
|
||||
@ -33,6 +34,7 @@ type Factory struct {
|
||||
sequence uint64
|
||||
gas uint64
|
||||
timeoutHeight uint64
|
||||
timeoutTimestamp time.Time
|
||||
gasAdjustment float64
|
||||
chainID string
|
||||
fromName string
|
||||
@ -86,7 +88,8 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
|
||||
|
||||
gasAdj := clientCtx.Viper.GetFloat64(flags.FlagGasAdjustment)
|
||||
memo := clientCtx.Viper.GetString(flags.FlagNote)
|
||||
timeoutHeight := clientCtx.Viper.GetUint64(flags.FlagTimeoutHeight)
|
||||
timestampUnix := clientCtx.Viper.GetInt64(flags.FlagTimeoutTimestamp)
|
||||
timeoutTimestamp := time.Unix(timestampUnix, 0)
|
||||
unordered := clientCtx.Viper.GetBool(flags.FlagUnordered)
|
||||
|
||||
gasStr := clientCtx.Viper.GetString(flags.FlagGas)
|
||||
@ -104,7 +107,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
|
||||
simulateAndExecute: gasSetting.Simulate,
|
||||
accountNumber: accNum,
|
||||
sequence: accSeq,
|
||||
timeoutHeight: timeoutHeight,
|
||||
timeoutTimestamp: timeoutTimestamp,
|
||||
unordered: unordered,
|
||||
gasAdjustment: gasAdj,
|
||||
memo: memo,
|
||||
@ -135,6 +138,7 @@ func (f Factory) Fees() sdk.Coins { return f.fees }
|
||||
func (f Factory) GasPrices() sdk.DecCoins { return f.gasPrices }
|
||||
func (f Factory) AccountRetriever() client.AccountRetriever { return f.accountRetriever }
|
||||
func (f Factory) TimeoutHeight() uint64 { return f.timeoutHeight }
|
||||
func (f Factory) TimeoutTimestamp() time.Time { return f.timeoutTimestamp }
|
||||
func (f Factory) Unordered() bool { return f.unordered }
|
||||
func (f Factory) FromName() string { return f.fromName }
|
||||
|
||||
@ -249,6 +253,12 @@ func (f Factory) WithTimeoutHeight(height uint64) Factory {
|
||||
return f
|
||||
}
|
||||
|
||||
// WithTimeoutTimestamp returns a copy of the Factory with an updated timeout timestamp.
|
||||
func (f Factory) WithTimeoutTimestamp(timestamp time.Time) Factory {
|
||||
f.timeoutTimestamp = timestamp
|
||||
return f
|
||||
}
|
||||
|
||||
// WithUnordered returns a copy of the Factory with an updated unordered field.
|
||||
func (f Factory) WithUnordered(v bool) Factory {
|
||||
f.unordered = v
|
||||
@ -361,6 +371,7 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) {
|
||||
tx.SetFeeGranter(f.feeGranter)
|
||||
tx.SetFeePayer(f.feePayer)
|
||||
tx.SetTimeoutHeight(f.TimeoutHeight())
|
||||
tx.SetTimeoutTimestamp(f.TimeoutTimestamp())
|
||||
tx.SetUnordered(f.Unordered())
|
||||
|
||||
if etx, ok := tx.(client.ExtendedTxBuilder); ok {
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/x/auth/signing"
|
||||
txsigning "cosmossdk.io/x/tx/signing"
|
||||
|
||||
@ -48,6 +50,7 @@ type (
|
||||
SetFeePayer(feePayer sdk.AccAddress)
|
||||
SetGasLimit(limit uint64)
|
||||
SetTimeoutHeight(height uint64)
|
||||
SetTimeoutTimestamp(timestamp time.Time)
|
||||
SetUnordered(v bool)
|
||||
SetFeeGranter(feeGranter sdk.AccAddress)
|
||||
AddAuxSignerData(tx.AuxSignerData) error
|
||||
|
||||
@ -27,7 +27,7 @@ Flags:
|
||||
-o, --output string Output format (text|json) (default "json")
|
||||
-s, --sequence uint The sequence number of the signing account (offline mode only)
|
||||
--sign-mode string Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature
|
||||
--timeout-height uint Set a block timeout height to prevent the tx from being committed past a certain height
|
||||
--timeout-timestamp int Set a block timeout timestamp to prevent the tx from being committed past a certain time
|
||||
--tip string Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator
|
||||
--unordered Enable unordered transaction delivery; must be used in conjunction with --timeout-height
|
||||
--unordered Enable unordered transaction delivery; must be used in conjunction with --timeout-timestamp
|
||||
-y, --yes Skip tx broadcasting prompt confirmation
|
||||
|
||||
2
client/v2/autocli/testdata/msg-output.golden
vendored
2
client/v2/autocli/testdata/msg-output.golden
vendored
@ -1 +1 @@
|
||||
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}]},"auth_info":{"fee":{"gas_limit":"200000"}}}
|
||||
{"body":{"messages":[{"@type":"/cosmos.bank.v1beta1.MsgSend","from_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","to_address":"cosmos1y74p8wyy4enfhfn342njve6cjmj5c8dtl6emdk","amount":[{"denom":"foo","amount":"1"}]}],"timeout_timestamp":"1970-01-01T00:00:00Z"},"auth_info":{"fee":{"gas_limit":"200000"}}}
|
||||
@ -113,6 +113,7 @@ func (b *builder) GetSigningTxData() (txsigning.TxData, error) {
|
||||
Messages: msgs,
|
||||
Memo: body.Memo,
|
||||
TimeoutHeight: body.TimeoutHeight,
|
||||
TimeoutTimestamp: body.TimeoutTimestamp,
|
||||
ExtensionOptions: extOptions,
|
||||
NonCriticalExtensionOptions: nonCriticalExtOptions,
|
||||
}
|
||||
|
||||
@ -35,13 +35,13 @@ this proposal, they'll follow the nonce rules the same as before.
|
||||
When an un-ordered transaction is included into a block, the transaction hash is
|
||||
recorded in a dictionary. New transactions are checked against this dictionary for
|
||||
duplicates, and to prevent the dictionary grow indefinitely, the transaction must
|
||||
specify `timeout_height` for expiration, so it's safe to removed it from the
|
||||
specify `timeout_timestamp` for expiration, so it's safe to removed it from the
|
||||
dictionary after it's expired.
|
||||
|
||||
The dictionary can be simply implemented as an in-memory golang map, a preliminary
|
||||
analysis shows that the memory consumption won't be too big, for example `32M = 32 * 1024 * 1024`
|
||||
can support 1024 blocks where each block contains 1024 unordered transactions. For
|
||||
safety, we should limit the range of `timeout_height` to prevent very long expiration,
|
||||
safety, we should limit the range of `timeout_timestamp` to prevent very long expiration,
|
||||
and limit the size of the dictionary.
|
||||
|
||||
### Transaction Format
|
||||
@ -58,12 +58,12 @@ message TxBody {
|
||||
|
||||
In order to provide replay protection, a user should ensure that the transaction's
|
||||
TTL value is relatively short-lived but long enough to provide enough time to be
|
||||
included in a block, e.g. ~H+50.
|
||||
included in a block, e.g. ~10 minutes.
|
||||
|
||||
We facilitate this by storing the transaction's hash in a durable map, `UnorderedTxManager`,
|
||||
to prevent duplicates, i.e. replay attacks. Upon transaction ingress during `CheckTx`,
|
||||
we check if the transaction's hash exists in this map or if the TTL value is stale,
|
||||
i.e. before the current block. If so, we reject it. Upon inclusion in a block
|
||||
i.e. before the current block time. If so, we reject it. Upon inclusion in a block
|
||||
during `DeliverTx`, the transaction's hash is set in the map along with it's TTL
|
||||
value.
|
||||
|
||||
@ -93,20 +93,20 @@ const PurgeLoopSleepMS = 500
|
||||
// UnorderedTxManager contains the tx hash dictionary for duplicates checking,
|
||||
// and expire them when block production progresses.
|
||||
type UnorderedTxManager struct {
|
||||
// blockCh defines a channel to receive newly committed block heights
|
||||
blockCh chan uint64
|
||||
// blockCh defines a channel to receive newly committed block time
|
||||
blockCh chan time.Time
|
||||
|
||||
mu sync.RWMutex
|
||||
// txHashes defines a map from tx hash -> TTL value, which is used for duplicate
|
||||
// checking and replay protection, as well as purging the map when the TTL is
|
||||
// expired.
|
||||
txHashes map[TxHash]uint64
|
||||
txHashes map[TxHash]time.Time
|
||||
}
|
||||
|
||||
func NewUnorderedTxManager() *UnorderedTxManager {
|
||||
m := &UnorderedTxManager{
|
||||
blockCh: make(chan uint64, 16),
|
||||
txHashes: make(map[TxHash]uint64),
|
||||
blockCh: make(chan time.Time, 16),
|
||||
txHashes: make(map[TxHash]time.Time),
|
||||
}
|
||||
|
||||
return m
|
||||
@ -137,27 +137,27 @@ func (m *UnorderedTxManager) Size() int {
|
||||
return len(m.txHashes)
|
||||
}
|
||||
|
||||
func (m *UnorderedTxManager) Add(hash TxHash, expire uint64) {
|
||||
func (m *UnorderedTxManager) Add(hash TxHash, expire time.Time) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.txHashes[hash] = expire
|
||||
}
|
||||
|
||||
// OnNewBlock send the latest block number to the background purge loop, which
|
||||
// OnNewBlock send the latest block time to the background purge loop, which
|
||||
// should be called in ABCI Commit event.
|
||||
func (m *UnorderedTxManager) OnNewBlock(blockHeight uint64) {
|
||||
m.blockCh <- blockHeight
|
||||
func (m *UnorderedTxManager) OnNewBlock(blockTime time.Time) {
|
||||
m.blockCh <- blockTime
|
||||
}
|
||||
|
||||
// expiredTxs returns expired tx hashes based on the provided block height.
|
||||
func (m *UnorderedTxManager) expiredTxs(blockHeight uint64) []TxHash {
|
||||
// expiredTxs returns expired tx hashes based on the provided block time.
|
||||
func (m *UnorderedTxManager) expiredTxs(blockTime time.Time) []TxHash {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
var result []TxHash
|
||||
for txHash, expire := range m.txHashes {
|
||||
if blockHeight > expire {
|
||||
if blockTime.After(expire) {
|
||||
result = append(result, txHash)
|
||||
}
|
||||
}
|
||||
@ -178,21 +178,17 @@ func (m *UnorderedTxManager) purge(txHashes []TxHash) {
|
||||
// purgeLoop removes expired tx hashes in the background
|
||||
func (m *UnorderedTxManager) purgeLoop() error {
|
||||
for {
|
||||
blocks := channelBatchRecv(m.blockCh)
|
||||
if len(blocks) == 0 {
|
||||
// channel closed
|
||||
break
|
||||
}
|
||||
latestTime, ok := m.batchReceive()
|
||||
if !ok {
|
||||
// channel closed
|
||||
return
|
||||
}
|
||||
|
||||
latest := *blocks[len(blocks)-1]
|
||||
hashes := m.expired(latest)
|
||||
if len(hashes) > 0 {
|
||||
m.purge(hashes)
|
||||
}
|
||||
|
||||
// avoid burning cpu in catching up phase
|
||||
time.Sleep(PurgeLoopSleepMS * time.Millisecond)
|
||||
}
|
||||
hashes := m.expiredTxs(latestTime)
|
||||
if len(hashes) > 0 {
|
||||
m.purge(hashes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -237,14 +233,14 @@ verification and map lookup.
|
||||
|
||||
```golang
|
||||
const (
|
||||
// DefaultMaxUnOrderedTTL defines the default maximum TTL an un-ordered transaction
|
||||
// DefaultMaxTimeoutDuration defines the default maximum duration an un-ordered transaction
|
||||
// can set.
|
||||
DefaultMaxUnOrderedTTL = 1024
|
||||
DefaultMaxTimeoutDuration = time.Minute * 40
|
||||
)
|
||||
|
||||
type DedupTxDecorator struct {
|
||||
m *UnorderedTxManager
|
||||
maxUnOrderedTTL uint64
|
||||
maxTimeoutDuration time.Time
|
||||
}
|
||||
|
||||
func (d *DedupTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
|
||||
@ -253,13 +249,17 @@ func (d *DedupTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
|
||||
return next(ctx, tx, simulate)
|
||||
}
|
||||
|
||||
if tx.TimeoutHeight() == 0 {
|
||||
return nil, errorsmod.Wrap(sdkerrors.ErrLogic, "unordered tx must set timeout-height")
|
||||
}
|
||||
|
||||
if tx.TimeoutHeight() > ctx.BlockHeight() + d.maxUnOrderedTTL {
|
||||
return nil, errorsmod.Wrapf(sdkerrors.ErrLogic, "unordered tx ttl exceeds %d", d.maxUnOrderedTTL)
|
||||
}
|
||||
headerInfo := d.env.HeaderService.HeaderInfo(ctx)
|
||||
timeoutTimestamp := unorderedTx.GetTimeoutTimeStamp()
|
||||
if timeoutTimestamp.IsZero() || timeoutTimestamp.Unix() == 0 {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction must have timeout_timestamp set")
|
||||
}
|
||||
if timeoutTimestamp.Before(headerInfo.Time) {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction has a timeout_timestamp that has already passed")
|
||||
}
|
||||
if timeoutTimestamp.After(headerInfo.Time.Add(d.maxTimeoutDuration)) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unordered tx ttl exceeds %s", d.maxTimeoutDuration.String())
|
||||
}
|
||||
|
||||
// in order to create a deterministic hash based on the tx, we need to hash the contents of the tx with signature
|
||||
// Get a Buffer from the pool
|
||||
@ -302,7 +302,7 @@ encoding is not malleable. If a given transaction, which is otherwise valid, can
|
||||
be encoded to produce different hashes, which reflect the same valid transaction,
|
||||
then a duplicate unordered transaction can be submitted and included in a block.
|
||||
|
||||
In order to prevent this, the decoded transaction contents is taken. Starting with the content of the transaction we marshal the transaction in order to prevent a client reordering the transaction. Next we include the gas and timeout height as part of the identifier. All these fields are signed over in the transaction payload. If one of them changes the signature will not match the transaction.
|
||||
In order to prevent this, the decoded transaction contents is taken. Starting with the content of the transaction we marshal the transaction in order to prevent a client reordering the transaction. Next we include the gas and timeout timestamp as part of the identifier. All these fields are signed over in the transaction payload. If one of them changes the signature will not match the transaction.
|
||||
|
||||
### State Management
|
||||
|
||||
|
||||
@ -480,7 +480,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci.go#L623
|
||||
|
||||
When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends the transactions in FinalizeBlock message to the application for each transaction in a sequential order.
|
||||
|
||||
Since `FinalizeBlock` is an ABCI call, `Tx` is received in the encoded `[]byte` form. Nodes first unmarshal the transaction, using the [`TxConfig`](./00-app-anatomy.md#register-codec) defined in the app, then call `runTx` in `execModeFinalize`, which is very similar to `CheckTx` but also executes and writes state changes.
|
||||
Since `FinalizeBlock` is an ABCI call, `Tx` is received in the encoded `[]byte` form. Nodes first unmarshal the transaction, using the [`TxConfig`](../beginner/00-app-anatomy.md#register-codec) defined in the app, then call `runTx` in `execModeFinalize`, which is very similar to `CheckTx` but also executes and writes state changes.
|
||||
|
||||

|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import "cosmos/crypto/multisig/v1beta1/multisig.proto";
|
||||
import "cosmos/base/v1beta1/coin.proto";
|
||||
import "cosmos/tx/signing/v1beta1/signing.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/types/tx";
|
||||
|
||||
@ -110,10 +111,6 @@ message TxBody {
|
||||
|
||||
// timeout_height is the block height after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
uint64 timeout_height = 3;
|
||||
|
||||
// unordered, when set to true, indicates that the transaction signer(s)
|
||||
@ -122,11 +119,19 @@ message TxBody {
|
||||
// incremented, which allows for fire-and-forget as well as concurrent
|
||||
// transaction execution.
|
||||
//
|
||||
// Note, when set to true, the existing 'timeout_height' value must be set and
|
||||
// will be used to correspond to a height in which the transaction is deemed
|
||||
// Note, when set to true, the existing 'timeout_height' value must
|
||||
// be set and will be used to correspond to a time_stamp in which the transaction is deemed
|
||||
// valid.
|
||||
bool unordered = 4;
|
||||
|
||||
// timeout_timestamp is the block time after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
google.protobuf.Timestamp timeout_timestamp = 5 [(gogoproto.nullable) = true, (gogoproto.stdtime) = true];
|
||||
|
||||
// extension_options are arbitrary options that can be added by chains
|
||||
// when the default options are not sufficient. If any of these are present
|
||||
// and can't be handled, the transaction will be rejected
|
||||
|
||||
@ -39,7 +39,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
|
||||
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
|
||||
ante.NewValidateBasicDecorator(options.Environment),
|
||||
ante.NewTxTimeoutHeightDecorator(options.Environment),
|
||||
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, options.TxManager, options.Environment, ante.DefaultSha256Cost),
|
||||
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.TxManager, options.Environment, ante.DefaultSha256Cost),
|
||||
ante.NewValidateMemoDecorator(options.AccountKeeper),
|
||||
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
|
||||
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
|
||||
|
||||
@ -174,7 +174,7 @@ func TestBaseApp_BlockGas(t *testing.T) {
|
||||
require.Equal(t, []byte("ok"), okValue)
|
||||
}
|
||||
// check block gas is always consumed
|
||||
baseGas := uint64(38012) // baseGas is the gas consumed before tx msg
|
||||
baseGas := uint64(38142) // baseGas is the gas consumed before tx msg
|
||||
expGasConsumed := addUint64Saturating(tc.gasToConsume, baseGas)
|
||||
if expGasConsumed > uint64(simtestutil.DefaultConsensusParams.Block.MaxGas) {
|
||||
// capped by gasLimit
|
||||
|
||||
@ -3,8 +3,9 @@
|
||||
package systemtests
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -27,11 +28,9 @@ func TestUnorderedTXDuplicate(t *testing.T) {
|
||||
|
||||
sut.StartChain(t)
|
||||
|
||||
height := sut.CurrentHeight()
|
||||
timeoutHeight := height + 15
|
||||
timeoutHeightStr := strconv.Itoa(int(timeoutHeight))
|
||||
timeoutTimestamp := time.Now().Add(time.Minute)
|
||||
// send tokens
|
||||
rsp1 := cli.Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", "--timeout-height="+timeoutHeightStr, "--unordered", "--sequence=1", "--note=1")
|
||||
rsp1 := cli.Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", fmt.Sprintf("--timeout-timestamp=%v", timeoutTimestamp.Unix()), "--unordered", "--sequence=1", "--note=1")
|
||||
RequireTxSuccess(t, rsp1)
|
||||
|
||||
assertDuplicateErr := func(xt assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
|
||||
@ -39,14 +38,10 @@ func TestUnorderedTXDuplicate(t *testing.T) {
|
||||
assert.Contains(t, gotOutputs[0], "is duplicated: invalid request")
|
||||
return false // always abort
|
||||
}
|
||||
rsp2 := cli.WithRunErrorMatcher(assertDuplicateErr).Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", "--timeout-height="+timeoutHeightStr, "--unordered", "--sequence=1")
|
||||
rsp2 := cli.WithRunErrorMatcher(assertDuplicateErr).Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", fmt.Sprintf("--timeout-timestamp=%v", timeoutTimestamp.Unix()), "--unordered", "--sequence=1")
|
||||
RequireTxFailure(t, rsp2)
|
||||
|
||||
// assert TX executed before timeout
|
||||
for cli.QueryBalance(account2Addr, "stake") != 5000 {
|
||||
t.Log("query balance")
|
||||
if current := sut.AwaitNextBlock(t); current > timeoutHeight {
|
||||
t.Fatal("TX was not executed before timeout")
|
||||
}
|
||||
}
|
||||
require.Eventually(t, func() bool {
|
||||
return cli.QueryBalance(account2Addr, "stake") == 5000
|
||||
}, time.Minute, time.Microsecond*500, "TX was not executed before timeout")
|
||||
}
|
||||
|
||||
@ -142,4 +142,8 @@ var (
|
||||
|
||||
// ErrPanic should only be set when we recovering from a panic
|
||||
ErrPanic = errorsmod.ErrPanic
|
||||
|
||||
// ErrTxTimeout defines an error for when a tx is rejected out due to an
|
||||
// explicitly set timeout timestamp.
|
||||
ErrTxTimeout = errorsmod.Register(RootCodespace, 42, "tx timeout")
|
||||
)
|
||||
|
||||
@ -13,16 +13,20 @@ import (
|
||||
signing "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
_ "github.com/cosmos/gogoproto/gogoproto"
|
||||
proto "github.com/cosmos/gogoproto/proto"
|
||||
github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types"
|
||||
any "github.com/cosmos/gogoproto/types/any"
|
||||
_ "google.golang.org/protobuf/types/known/timestamppb"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
var _ = time.Kitchen
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
@ -359,10 +363,6 @@ type TxBody struct {
|
||||
Memo string `protobuf:"bytes,2,opt,name=memo,proto3" json:"memo,omitempty"`
|
||||
// timeout_height is the block height after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
TimeoutHeight uint64 `protobuf:"varint,3,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty"`
|
||||
// unordered, when set to true, indicates that the transaction signer(s)
|
||||
// intend for the transaction to be evaluated and executed in an un-ordered
|
||||
@ -370,10 +370,17 @@ type TxBody struct {
|
||||
// incremented, which allows for fire-and-forget as well as concurrent
|
||||
// transaction execution.
|
||||
//
|
||||
// Note, when set to true, the existing 'timeout_height' value must be set and
|
||||
// will be used to correspond to a height in which the transaction is deemed
|
||||
// Note, when set to true, the existing 'timeout_height' value must
|
||||
// be set and will be used to correspond to a time_stamp in which the transaction is deemed
|
||||
// valid.
|
||||
Unordered bool `protobuf:"varint,4,opt,name=unordered,proto3" json:"unordered,omitempty"`
|
||||
// timeout_timestamp is the block time after which this transaction will not
|
||||
// be processed by the chain.
|
||||
//
|
||||
// Note, if unordered=true this value MUST be set
|
||||
// and will act as a short-lived TTL in which the transaction is deemed valid
|
||||
// and kept in memory to prevent duplicates.
|
||||
TimeoutTimestamp *time.Time `protobuf:"bytes,5,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3,stdtime" json:"timeout_timestamp,omitempty"`
|
||||
// extension_options are arbitrary options that can be added by chains
|
||||
// when the default options are not sufficient. If any of these are present
|
||||
// and can't be handled, the transaction will be rejected
|
||||
@ -445,6 +452,13 @@ func (m *TxBody) GetUnordered() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *TxBody) GetTimeoutTimestamp() *time.Time {
|
||||
if m != nil {
|
||||
return m.TimeoutTimestamp
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *TxBody) GetExtensionOptions() []*any.Any {
|
||||
if m != nil {
|
||||
return m.ExtensionOptions
|
||||
@ -1036,77 +1050,79 @@ func init() {
|
||||
func init() { proto.RegisterFile("cosmos/tx/v1beta1/tx.proto", fileDescriptor_96d1575ffde80842) }
|
||||
|
||||
var fileDescriptor_96d1575ffde80842 = []byte{
|
||||
// 1106 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0xcf, 0x6f, 0x1b, 0xc5,
|
||||
0x17, 0xf7, 0x7a, 0x6d, 0xc7, 0x7e, 0x4d, 0xfa, 0x63, 0xbe, 0xed, 0x57, 0x8e, 0x4b, 0xdd, 0xe0,
|
||||
0xaa, 0x60, 0x55, 0x64, 0xb7, 0x4d, 0x11, 0x94, 0x08, 0x51, 0xec, 0x86, 0x28, 0x55, 0x29, 0x48,
|
||||
0x9b, 0x9c, 0x7a, 0x59, 0x8d, 0x77, 0x27, 0xeb, 0x51, 0xbd, 0x33, 0xcb, 0xce, 0x2c, 0x78, 0x8f,
|
||||
0x9c, 0x38, 0x21, 0x55, 0x5c, 0x90, 0xf8, 0x0b, 0x10, 0xa7, 0x4a, 0x54, 0xe2, 0x5f, 0x28, 0xb7,
|
||||
0x2a, 0x27, 0xc4, 0x01, 0xaa, 0xe4, 0xd0, 0x3f, 0x03, 0xb4, 0xb3, 0xb3, 0x9b, 0xb4, 0x75, 0x1d,
|
||||
0x10, 0x48, 0x5c, 0x56, 0x33, 0x6f, 0x3f, 0xef, 0xcd, 0x67, 0xde, 0xfb, 0xcc, 0x7b, 0xd0, 0xf1,
|
||||
0xb8, 0x08, 0xb9, 0xb0, 0xe5, 0xd4, 0xfe, 0xfc, 0xda, 0x88, 0x48, 0x7c, 0xcd, 0x96, 0x53, 0x2b,
|
||||
0x8a, 0xb9, 0xe4, 0xe8, 0x4c, 0xfe, 0xcf, 0x92, 0x53, 0x4b, 0xff, 0xeb, 0x2c, 0xe7, 0x26, 0x57,
|
||||
0x01, 0x6c, 0xfd, 0x5f, 0x6d, 0x3a, 0x67, 0x70, 0x48, 0x19, 0xb7, 0xd5, 0x57, 0x9b, 0xce, 0x06,
|
||||
0x3c, 0xe0, 0x39, 0x34, 0x5b, 0x69, 0xeb, 0xaa, 0x3e, 0xd2, 0x8b, 0xd3, 0x48, 0x72, 0x3b, 0x4c,
|
||||
0x26, 0x92, 0x0a, 0x1a, 0x94, 0xe7, 0x17, 0x06, 0x0d, 0xef, 0x6a, 0xf8, 0x08, 0x0b, 0x52, 0x62,
|
||||
0x3c, 0x4e, 0x99, 0xfe, 0xff, 0xe6, 0xe1, 0x0d, 0x04, 0x0d, 0x18, 0x65, 0x87, 0x91, 0xf4, 0x5e,
|
||||
0x03, 0x97, 0x03, 0xce, 0x83, 0x09, 0xb1, 0xd5, 0x6e, 0x94, 0xec, 0xda, 0x98, 0xa5, 0xf9, 0xaf,
|
||||
0xde, 0xd7, 0x06, 0x54, 0x77, 0xa6, 0x68, 0x15, 0x6a, 0x23, 0xee, 0xa7, 0x6d, 0x63, 0xc5, 0xe8,
|
||||
0x9f, 0x58, 0x5b, 0xb6, 0x5e, 0xba, 0xbf, 0xb5, 0x33, 0x1d, 0x72, 0x3f, 0x75, 0x14, 0x0c, 0xdd,
|
||||
0x80, 0x16, 0x4e, 0xe4, 0xd8, 0xa5, 0x6c, 0x97, 0xb7, 0xab, 0xca, 0xe7, 0xfc, 0x0c, 0x9f, 0x41,
|
||||
0x22, 0xc7, 0xb7, 0xd9, 0x2e, 0x77, 0x9a, 0x58, 0xaf, 0x50, 0x17, 0x20, 0xe3, 0x86, 0x65, 0x12,
|
||||
0x13, 0xd1, 0x36, 0x57, 0xcc, 0xfe, 0xa2, 0x73, 0xc4, 0xd2, 0x63, 0x50, 0xdf, 0x99, 0x3a, 0xf8,
|
||||
0x0b, 0x74, 0x01, 0x20, 0x3b, 0xca, 0x1d, 0xa5, 0x92, 0x08, 0xc5, 0x6b, 0xd1, 0x69, 0x65, 0x96,
|
||||
0x61, 0x66, 0x40, 0x6f, 0xc0, 0xa9, 0x92, 0x81, 0xc6, 0x54, 0x15, 0x66, 0xa9, 0x38, 0x2a, 0xc7,
|
||||
0x1d, 0x77, 0xde, 0x37, 0x06, 0x2c, 0x6c, 0xd3, 0x80, 0x6d, 0x70, 0xef, 0xdf, 0x3a, 0x72, 0x19,
|
||||
0x9a, 0xde, 0x18, 0x53, 0xe6, 0x52, 0xbf, 0x6d, 0xae, 0x18, 0xfd, 0x96, 0xb3, 0xa0, 0xf6, 0xb7,
|
||||
0x7d, 0x74, 0x19, 0x4e, 0x62, 0xcf, 0xe3, 0x09, 0x93, 0x2e, 0x4b, 0xc2, 0x11, 0x89, 0xdb, 0xb5,
|
||||
0x15, 0xa3, 0x5f, 0x73, 0x96, 0xb4, 0xf5, 0x13, 0x65, 0xec, 0x7d, 0x55, 0x85, 0xd3, 0x9a, 0xd4,
|
||||
0x06, 0x8d, 0x89, 0x27, 0x07, 0xc9, 0xf4, 0x38, 0x76, 0xd7, 0x01, 0xa2, 0x64, 0x34, 0xa1, 0x9e,
|
||||
0x7b, 0x9f, 0xa4, 0xba, 0x26, 0x67, 0xad, 0xbc, 0xf0, 0x56, 0x51, 0x78, 0x6b, 0xc0, 0x52, 0xa7,
|
||||
0x95, 0xe3, 0xee, 0x90, 0xf4, 0x9f, 0x53, 0x45, 0x1d, 0x68, 0x0a, 0xf2, 0x59, 0x42, 0x98, 0x47,
|
||||
0xda, 0x75, 0x05, 0x28, 0xf7, 0xe8, 0x2d, 0x30, 0x25, 0x8d, 0xda, 0x0d, 0xc5, 0xe5, 0xff, 0xb3,
|
||||
0x34, 0x45, 0xa3, 0x61, 0xb5, 0x6d, 0x38, 0x19, 0x6c, 0xfd, 0x7f, 0x7b, 0x8f, 0x56, 0x4f, 0xe5,
|
||||
0x98, 0x55, 0xe1, 0xdf, 0x5f, 0xb9, 0x6a, 0xbd, 0xfd, 0x4e, 0xef, 0xc7, 0x2a, 0x34, 0x72, 0xe5,
|
||||
0xa1, 0xab, 0xd0, 0x0c, 0x89, 0x10, 0x38, 0x50, 0xb7, 0x37, 0x5f, 0x79, 0xbd, 0x12, 0x85, 0x10,
|
||||
0xd4, 0x42, 0x12, 0xe6, 0x02, 0x6d, 0x39, 0x6a, 0x9d, 0x5d, 0x4b, 0xd2, 0x90, 0xf0, 0x44, 0xba,
|
||||
0x63, 0x42, 0x83, 0xb1, 0x54, 0xf7, 0xae, 0x39, 0x4b, 0xda, 0xba, 0xa5, 0x8c, 0xe8, 0x35, 0x68,
|
||||
0x25, 0x8c, 0xc7, 0x3e, 0x89, 0x89, 0xaf, 0x2e, 0xde, 0x74, 0x0e, 0x0d, 0x68, 0x08, 0x67, 0xc8,
|
||||
0x54, 0x12, 0x26, 0x28, 0x67, 0x2e, 0x8f, 0x24, 0xe5, 0x4c, 0xb4, 0xff, 0x58, 0x98, 0x43, 0xea,
|
||||
0x74, 0x89, 0xff, 0x34, 0x87, 0xa3, 0x7b, 0xd0, 0x65, 0x9c, 0xb9, 0x5e, 0x4c, 0x25, 0xf5, 0xf0,
|
||||
0xc4, 0x9d, 0x11, 0xf0, 0xd4, 0x9c, 0x80, 0xe7, 0x19, 0x67, 0xb7, 0xb4, 0xef, 0x47, 0x2f, 0xc4,
|
||||
0xee, 0xfd, 0x64, 0x40, 0xb3, 0x78, 0x7b, 0xe8, 0x43, 0x58, 0xcc, 0xf4, 0x4e, 0x62, 0x25, 0xdc,
|
||||
0x22, 0x77, 0x17, 0x66, 0x94, 0x63, 0x5b, 0xc1, 0xd4, 0x83, 0x3d, 0x21, 0xca, 0xb5, 0x40, 0x7d,
|
||||
0x30, 0x77, 0x09, 0xd1, 0x9a, 0x9a, 0x55, 0xc7, 0x4d, 0x42, 0x9c, 0x0c, 0x82, 0x6e, 0xe6, 0x15,
|
||||
0x37, 0xe7, 0x56, 0xfc, 0xdc, 0xaf, 0x2f, 0x17, 0x5a, 0x8b, 0xa0, 0xf7, 0xad, 0x01, 0x70, 0x48,
|
||||
0xe3, 0x05, 0x51, 0x1b, 0x7f, 0x4d, 0xd4, 0x37, 0xa0, 0x15, 0x72, 0x9f, 0x1c, 0xd7, 0x9c, 0xee,
|
||||
0x72, 0x9f, 0xe4, 0xcd, 0x29, 0xd4, 0xab, 0xe7, 0xc4, 0x6c, 0x3e, 0x2f, 0xe6, 0xde, 0xd3, 0x2a,
|
||||
0x34, 0x0b, 0x17, 0xf4, 0x3e, 0x34, 0x04, 0x65, 0xc1, 0x84, 0x68, 0x4e, 0xbd, 0x39, 0xf1, 0xad,
|
||||
0x6d, 0x85, 0xdc, 0xaa, 0x38, 0xda, 0x07, 0xbd, 0x07, 0x75, 0xd5, 0xe9, 0x35, 0xb9, 0xd7, 0xe7,
|
||||
0x39, 0xdf, 0xcd, 0x80, 0x5b, 0x15, 0x27, 0xf7, 0xe8, 0x0c, 0xa0, 0x91, 0x87, 0x43, 0xef, 0x42,
|
||||
0x2d, 0xe3, 0xad, 0x08, 0x9c, 0x5c, 0xbb, 0x74, 0x24, 0x46, 0xd1, 0xfb, 0x8f, 0x96, 0x35, 0x8b,
|
||||
0xe7, 0x28, 0x87, 0xce, 0x03, 0x03, 0xea, 0x2a, 0x2a, 0xba, 0x03, 0xcd, 0x11, 0x95, 0x38, 0x8e,
|
||||
0x71, 0x91, 0x5b, 0xbb, 0x08, 0x93, 0x4f, 0x28, 0xab, 0x1c, 0x48, 0x45, 0xac, 0x5b, 0x3c, 0x8c,
|
||||
0xb0, 0x27, 0x87, 0x54, 0x0e, 0x32, 0x37, 0xa7, 0x0c, 0x80, 0xd6, 0x01, 0xca, 0xac, 0x67, 0x8d,
|
||||
0xd1, 0x3c, 0x2e, 0xed, 0xad, 0x22, 0xed, 0x62, 0x58, 0x07, 0x53, 0x24, 0x61, 0xef, 0xcb, 0x2a,
|
||||
0x98, 0x9b, 0x84, 0xa0, 0x14, 0x1a, 0x38, 0xcc, 0x7a, 0x8c, 0xd6, 0x6a, 0x39, 0x8e, 0xb2, 0x41,
|
||||
0x78, 0x84, 0x0a, 0x65, 0xc3, 0xcd, 0xc7, 0xbf, 0x5d, 0xac, 0xfc, 0xf0, 0xfb, 0xc5, 0x7e, 0x40,
|
||||
0xe5, 0x38, 0x19, 0x59, 0x1e, 0x0f, 0xed, 0x62, 0xc8, 0x96, 0x0a, 0xb3, 0x65, 0x1a, 0x11, 0xa1,
|
||||
0x1c, 0xc4, 0x77, 0xcf, 0x1e, 0x5e, 0x59, 0x9c, 0x90, 0x00, 0x7b, 0xa9, 0x9b, 0x8d, 0x52, 0xf1,
|
||||
0xfd, 0xb3, 0x87, 0x57, 0x0c, 0x47, 0x1f, 0x88, 0xce, 0x43, 0x2b, 0xc0, 0xc2, 0x9d, 0xd0, 0x90,
|
||||
0x4a, 0x55, 0x9e, 0x9a, 0xd3, 0x0c, 0xb0, 0xf8, 0x38, 0xdb, 0x23, 0x0b, 0xea, 0x11, 0x4e, 0x49,
|
||||
0x9c, 0xb7, 0xca, 0x61, 0x7b, 0xef, 0xd1, 0xea, 0x59, 0xcd, 0x6c, 0xe0, 0xfb, 0x31, 0x11, 0x62,
|
||||
0x5b, 0xc6, 0x94, 0x05, 0x4e, 0x0e, 0x43, 0x6b, 0xb0, 0x10, 0xc4, 0x98, 0x49, 0xdd, 0x3b, 0xe7,
|
||||
0x79, 0x14, 0xc0, 0xde, 0xcf, 0x06, 0x98, 0x3b, 0x34, 0xfa, 0x2f, 0x73, 0x70, 0x15, 0x1a, 0x92,
|
||||
0x46, 0x11, 0x89, 0xf3, 0xc6, 0x39, 0x87, 0xb5, 0xc6, 0xad, 0x9f, 0xdb, 0x9b, 0xf5, 0xa2, 0x7b,
|
||||
0x07, 0x06, 0x2c, 0x0d, 0x92, 0x69, 0xfe, 0x9e, 0x37, 0xb0, 0xc4, 0x59, 0x46, 0x70, 0x1e, 0x41,
|
||||
0x09, 0x6e, 0x6e, 0x46, 0x34, 0x10, 0x7d, 0x00, 0xcd, 0x4c, 0xd1, 0xae, 0xcf, 0x3d, 0xfd, 0x60,
|
||||
0x2e, 0xbd, 0xa2, 0x77, 0x1d, 0x1d, 0x97, 0xce, 0x82, 0xd0, 0x53, 0xbd, 0x78, 0x28, 0xe6, 0xdf,
|
||||
0x7c, 0x28, 0xe8, 0x34, 0x98, 0x82, 0x06, 0xaa, 0x74, 0x8b, 0x4e, 0xb6, 0x9c, 0x39, 0xa2, 0x86,
|
||||
0x37, 0x1f, 0xef, 0x77, 0x8d, 0x27, 0xfb, 0x5d, 0xe3, 0xe9, 0x7e, 0xd7, 0x78, 0x70, 0xd0, 0xad,
|
||||
0x3c, 0x39, 0xe8, 0x56, 0x7e, 0x39, 0xe8, 0x56, 0xee, 0x5d, 0x3e, 0xbe, 0x20, 0xb6, 0x9c, 0x8e,
|
||||
0x1a, 0xaa, 0x91, 0x5d, 0xff, 0x33, 0x00, 0x00, 0xff, 0xff, 0x6d, 0xc2, 0x59, 0x2a, 0x91, 0x0a,
|
||||
0x00, 0x00,
|
||||
// 1147 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x4f, 0x8f, 0xdb, 0x44,
|
||||
0x14, 0x8f, 0xe3, 0x24, 0x9b, 0xbc, 0xee, 0xb6, 0xbb, 0x43, 0x8b, 0xb2, 0x29, 0xcd, 0x2e, 0xa9,
|
||||
0x0a, 0x51, 0xc5, 0xda, 0xed, 0x16, 0x41, 0xa9, 0x10, 0x25, 0x69, 0xa9, 0x5a, 0x95, 0x82, 0xf0,
|
||||
0xee, 0xa9, 0x17, 0x6b, 0x62, 0xcf, 0x3a, 0xa3, 0xc6, 0x33, 0xc6, 0x33, 0x86, 0xf8, 0xc8, 0x05,
|
||||
0x4e, 0x48, 0x15, 0x17, 0x24, 0x3e, 0x01, 0xe2, 0xd4, 0x43, 0x25, 0xbe, 0x42, 0xb9, 0x55, 0x3d,
|
||||
0x21, 0x0e, 0x6d, 0xd5, 0x3d, 0xf4, 0x63, 0x80, 0x3c, 0x1e, 0x7b, 0xb7, 0xdd, 0x34, 0x0b, 0x02,
|
||||
0x89, 0x4b, 0xe4, 0x79, 0xf3, 0x7b, 0x6f, 0x7e, 0xef, 0x7f, 0xa0, 0xe3, 0x71, 0x11, 0x72, 0x61,
|
||||
0xcb, 0xa9, 0xfd, 0xd5, 0xf9, 0x11, 0x91, 0xf8, 0xbc, 0x2d, 0xa7, 0x56, 0x14, 0x73, 0xc9, 0xd1,
|
||||
0x4a, 0x7e, 0x67, 0xc9, 0xa9, 0xa5, 0xef, 0x3a, 0xab, 0xb9, 0xc8, 0x55, 0x00, 0x5b, 0xdf, 0xab,
|
||||
0x43, 0x67, 0x05, 0x87, 0x94, 0x71, 0x5b, 0xfd, 0x6a, 0xd1, 0xf1, 0x80, 0x07, 0x3c, 0x87, 0x66,
|
||||
0x5f, 0x5a, 0xba, 0xa1, 0x9f, 0xf4, 0xe2, 0x34, 0x92, 0xdc, 0x0e, 0x93, 0x89, 0xa4, 0x82, 0x06,
|
||||
0xe5, 0xfb, 0x85, 0x40, 0xc3, 0xbb, 0x1a, 0x3e, 0xc2, 0x82, 0x94, 0x18, 0x8f, 0x53, 0xa6, 0xef,
|
||||
0xdf, 0xde, 0xf3, 0x40, 0xd0, 0x80, 0x51, 0xb6, 0x67, 0x49, 0x9f, 0x35, 0x70, 0x35, 0xe0, 0x3c,
|
||||
0x98, 0x10, 0x5b, 0x9d, 0x46, 0xc9, 0x8e, 0x8d, 0x59, 0xaa, 0xaf, 0xd6, 0x5e, 0xbe, 0x92, 0x34,
|
||||
0x24, 0x42, 0xe2, 0x30, 0xca, 0x01, 0xbd, 0xef, 0x0d, 0xa8, 0x6e, 0x4f, 0xd1, 0x06, 0xd4, 0x46,
|
||||
0xdc, 0x4f, 0xdb, 0xc6, 0xba, 0xd1, 0x3f, 0xb2, 0xb9, 0x6a, 0x1d, 0x08, 0x90, 0xb5, 0x3d, 0x1d,
|
||||
0x72, 0x3f, 0x75, 0x14, 0x0c, 0x5d, 0x84, 0x16, 0x4e, 0xe4, 0xd8, 0xa5, 0x6c, 0x87, 0xb7, 0xab,
|
||||
0x4a, 0xe7, 0xe4, 0x0c, 0x9d, 0x41, 0x22, 0xc7, 0x37, 0xd8, 0x0e, 0x77, 0x9a, 0x58, 0x7f, 0xa1,
|
||||
0x2e, 0x40, 0x46, 0x1e, 0xcb, 0x24, 0x26, 0xa2, 0x6d, 0xae, 0x9b, 0xfd, 0x45, 0x67, 0x9f, 0xa4,
|
||||
0xc7, 0xa0, 0xbe, 0x3d, 0x75, 0xf0, 0xd7, 0xe8, 0x14, 0x40, 0xf6, 0x94, 0x3b, 0x4a, 0x25, 0x11,
|
||||
0x8a, 0xd7, 0xa2, 0xd3, 0xca, 0x24, 0xc3, 0x4c, 0x80, 0xde, 0x82, 0x63, 0x25, 0x03, 0x8d, 0xa9,
|
||||
0x2a, 0xcc, 0x52, 0xf1, 0x54, 0x8e, 0x3b, 0xec, 0xbd, 0x1f, 0x0c, 0x58, 0xd8, 0xa2, 0x01, 0xbb,
|
||||
0xca, 0xbd, 0xff, 0xea, 0xc9, 0x55, 0x68, 0x7a, 0x63, 0x4c, 0x99, 0x4b, 0xfd, 0xb6, 0xb9, 0x6e,
|
||||
0xf4, 0x5b, 0xce, 0x82, 0x3a, 0xdf, 0xf0, 0xd1, 0x19, 0x38, 0x8a, 0x3d, 0x8f, 0x27, 0x4c, 0xba,
|
||||
0x2c, 0x09, 0x47, 0x24, 0x6e, 0xd7, 0xd6, 0x8d, 0x7e, 0xcd, 0x59, 0xd2, 0xd2, 0xcf, 0x94, 0xb0,
|
||||
0xf7, 0x5d, 0x15, 0x96, 0x35, 0xa9, 0xab, 0x34, 0x26, 0x9e, 0x1c, 0x24, 0xd3, 0xc3, 0xd8, 0x5d,
|
||||
0x00, 0x88, 0x92, 0xd1, 0x84, 0x7a, 0xee, 0x1d, 0x92, 0xea, 0x9c, 0x1c, 0xb7, 0xf2, 0xf4, 0x5b,
|
||||
0x45, 0xfa, 0xad, 0x01, 0x4b, 0x9d, 0x56, 0x8e, 0xbb, 0x49, 0xd2, 0x7f, 0x4f, 0x15, 0x75, 0xa0,
|
||||
0x29, 0xc8, 0x97, 0x09, 0x61, 0x1e, 0x69, 0xd7, 0x15, 0xa0, 0x3c, 0xa3, 0x77, 0xc0, 0x94, 0x34,
|
||||
0x6a, 0x37, 0x14, 0x97, 0xd7, 0x67, 0xd5, 0x14, 0x8d, 0x86, 0xd5, 0xb6, 0xe1, 0x64, 0xb0, 0x4b,
|
||||
0xaf, 0x3d, 0xba, 0xbf, 0x71, 0x2c, 0xc7, 0x6c, 0x08, 0xff, 0xce, 0xfa, 0x39, 0xeb, 0xdd, 0xf7,
|
||||
0x7a, 0xdf, 0x9a, 0xd0, 0xc8, 0x2b, 0x0f, 0x9d, 0x83, 0x66, 0x48, 0x84, 0xc0, 0x81, 0xf2, 0xde,
|
||||
0x7c, 0xa5, 0x7b, 0x25, 0x0a, 0x21, 0xa8, 0x85, 0x24, 0xcc, 0x0b, 0xb4, 0xe5, 0xa8, 0xef, 0xcc,
|
||||
0xad, 0xac, 0x05, 0x78, 0x22, 0xdd, 0x31, 0xa1, 0xc1, 0x58, 0x2a, 0xbf, 0x6b, 0xce, 0x92, 0x96,
|
||||
0x5e, 0x57, 0x42, 0xf4, 0x06, 0xb4, 0x12, 0xc6, 0x63, 0x9f, 0xc4, 0xc4, 0x57, 0x8e, 0x37, 0x9d,
|
||||
0x3d, 0x01, 0xfa, 0x02, 0x56, 0x0a, 0x23, 0x65, 0x3f, 0x29, 0xef, 0x8f, 0x6c, 0x76, 0x0e, 0x70,
|
||||
0xda, 0x2e, 0x10, 0xc3, 0xe6, 0x83, 0xc7, 0x6b, 0xc6, 0xdd, 0x27, 0x6b, 0x86, 0xb3, 0xac, 0xd5,
|
||||
0xcb, 0x3b, 0x34, 0x84, 0x15, 0x32, 0x95, 0x84, 0x09, 0xca, 0x99, 0xcb, 0x23, 0x49, 0x39, 0x13,
|
||||
0xed, 0x3f, 0x17, 0xe6, 0xf8, 0xb9, 0x5c, 0xe2, 0x3f, 0xcf, 0xe1, 0xe8, 0x36, 0x74, 0x19, 0x67,
|
||||
0xae, 0x17, 0x53, 0x49, 0x3d, 0x3c, 0x71, 0x67, 0x18, 0x3c, 0x36, 0xc7, 0xe0, 0x49, 0xc6, 0xd9,
|
||||
0x15, 0xad, 0xfb, 0xc9, 0x4b, 0xb6, 0x7b, 0xbf, 0x1a, 0xd0, 0x2c, 0xda, 0x19, 0x7d, 0x0c, 0x8b,
|
||||
0x59, 0x0b, 0x91, 0x58, 0xf5, 0x42, 0x91, 0x8e, 0x53, 0x33, 0x32, 0xbc, 0xa5, 0x60, 0x6a, 0x06,
|
||||
0x1c, 0x11, 0xe5, 0xb7, 0x40, 0x7d, 0x30, 0x77, 0x08, 0xd1, 0x65, 0x3a, 0xab, 0x34, 0xae, 0x11,
|
||||
0xe2, 0x64, 0x10, 0x74, 0x39, 0x2f, 0x22, 0x73, 0x6e, 0x11, 0x9d, 0xf8, 0xe3, 0x60, 0xed, 0xe8,
|
||||
0xba, 0xea, 0xfd, 0x68, 0x00, 0xec, 0xd1, 0x78, 0xa9, 0x4f, 0x8c, 0xbf, 0xd7, 0x27, 0x17, 0xa1,
|
||||
0x15, 0x72, 0x9f, 0x1c, 0x36, 0xef, 0x6e, 0x71, 0x9f, 0xe4, 0xf3, 0x2e, 0xd4, 0x5f, 0x2f, 0xf4,
|
||||
0x87, 0xf9, 0x62, 0x7f, 0xf4, 0x9e, 0x56, 0xa1, 0x59, 0xa8, 0xa0, 0x0f, 0xa1, 0x21, 0x28, 0x0b,
|
||||
0x26, 0x44, 0x73, 0xea, 0xcd, 0xb1, 0x6f, 0x6d, 0x29, 0xe4, 0xf5, 0x8a, 0xa3, 0x75, 0xd0, 0x07,
|
||||
0x50, 0x57, 0xdb, 0x45, 0x93, 0x7b, 0x73, 0x9e, 0xf2, 0xad, 0x0c, 0x78, 0xbd, 0xe2, 0xe4, 0x1a,
|
||||
0x9d, 0x01, 0x34, 0x72, 0x73, 0xe8, 0x7d, 0xa8, 0x65, 0xbc, 0x15, 0x81, 0xa3, 0x9b, 0xa7, 0xf7,
|
||||
0xd9, 0x28, 0xf6, 0xcd, 0xfe, 0xb4, 0x66, 0xf6, 0x1c, 0xa5, 0xd0, 0xb9, 0x6b, 0x40, 0x5d, 0x59,
|
||||
0x45, 0x37, 0xa1, 0x39, 0xa2, 0x12, 0xc7, 0x31, 0x2e, 0x62, 0x6b, 0x17, 0x66, 0xf2, 0xad, 0x68,
|
||||
0x95, 0x4b, 0xb0, 0xb0, 0x75, 0x85, 0x87, 0x11, 0xf6, 0xe4, 0x90, 0xca, 0x41, 0xa6, 0xe6, 0x94,
|
||||
0x06, 0xd0, 0x25, 0x80, 0x32, 0xea, 0xd9, 0xac, 0x35, 0x0f, 0x0b, 0x7b, 0xab, 0x08, 0xbb, 0x18,
|
||||
0xd6, 0xc1, 0x14, 0x49, 0xd8, 0xfb, 0xa6, 0x0a, 0xe6, 0x35, 0x42, 0x50, 0x0a, 0x0d, 0x1c, 0x66,
|
||||
0x63, 0x4b, 0xd7, 0x6a, 0xb9, 0xe1, 0xb2, 0xe5, 0xbb, 0x8f, 0x0a, 0x65, 0xc3, 0x6b, 0x0f, 0x1e,
|
||||
0xaf, 0x55, 0x7e, 0x79, 0xb2, 0xd6, 0x0f, 0xa8, 0x1c, 0x27, 0x23, 0xcb, 0xe3, 0xa1, 0x5d, 0x2c,
|
||||
0xf6, 0xb2, 0xc2, 0x6c, 0x99, 0x46, 0x44, 0x28, 0x05, 0xf1, 0xd3, 0xf3, 0x7b, 0x67, 0x17, 0x27,
|
||||
0x24, 0xc0, 0x5e, 0xea, 0x66, 0xeb, 0x5b, 0xfc, 0xfc, 0xfc, 0xde, 0x59, 0xc3, 0xd1, 0x0f, 0xa2,
|
||||
0x93, 0xd0, 0x0a, 0xb0, 0x70, 0x27, 0x34, 0xa4, 0x52, 0xa5, 0xa7, 0xe6, 0x34, 0x03, 0x2c, 0x3e,
|
||||
0xcd, 0xce, 0xc8, 0x82, 0x7a, 0x84, 0x53, 0x12, 0xe7, 0xd3, 0x77, 0xd8, 0x7e, 0x74, 0x7f, 0xe3,
|
||||
0xb8, 0x66, 0x36, 0xf0, 0xfd, 0x98, 0x08, 0xb1, 0x25, 0x63, 0xca, 0x02, 0x27, 0x87, 0xa1, 0x4d,
|
||||
0x58, 0x08, 0x62, 0xcc, 0xa4, 0x1e, 0xc7, 0xf3, 0x34, 0x0a, 0x60, 0xef, 0x37, 0x03, 0xcc, 0x6d,
|
||||
0x1a, 0xfd, 0x9f, 0x31, 0x38, 0x07, 0x0d, 0x49, 0xa3, 0x88, 0xc4, 0xf9, 0x2c, 0x9e, 0xc3, 0x5a,
|
||||
0xe3, 0x2e, 0x9d, 0x78, 0x34, 0xab, 0xa3, 0x7b, 0xbb, 0x06, 0x2c, 0x0d, 0x92, 0x69, 0xde, 0xcf,
|
||||
0x57, 0xb1, 0xc4, 0x59, 0x44, 0x70, 0x6e, 0x41, 0x15, 0xdc, 0xdc, 0x88, 0x68, 0x20, 0xfa, 0x08,
|
||||
0x9a, 0x59, 0x45, 0xbb, 0x3e, 0xf7, 0x74, 0xc3, 0x9c, 0x7e, 0xc5, 0xec, 0xda, 0xbf, 0x81, 0x9d,
|
||||
0x05, 0xa1, 0xff, 0x28, 0x14, 0x8d, 0x62, 0xfe, 0xc3, 0x46, 0x41, 0xcb, 0x60, 0x0a, 0x1a, 0xa8,
|
||||
0xd4, 0x2d, 0x3a, 0xd9, 0xe7, 0xcc, 0xad, 0x37, 0xbc, 0xfc, 0xe0, 0x59, 0xd7, 0x78, 0xf8, 0xac,
|
||||
0x6b, 0x3c, 0x7d, 0xd6, 0x35, 0xee, 0xee, 0x76, 0x2b, 0x0f, 0x77, 0xbb, 0x95, 0xdf, 0x77, 0xbb,
|
||||
0x95, 0xdb, 0x67, 0x0e, 0x4f, 0x88, 0x2d, 0xa7, 0xa3, 0x86, 0x1a, 0x64, 0x17, 0xfe, 0x0a, 0x00,
|
||||
0x00, 0xff, 0xff, 0x72, 0x63, 0x4f, 0x0e, 0x05, 0x0b, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Tx) Marshal() (dAtA []byte, err error) {
|
||||
@ -1383,6 +1399,16 @@ func (m *TxBody) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0xfa
|
||||
}
|
||||
}
|
||||
if m.TimeoutTimestamp != nil {
|
||||
n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.TimeoutTimestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.TimeoutTimestamp):])
|
||||
if err5 != nil {
|
||||
return 0, err5
|
||||
}
|
||||
i -= n5
|
||||
i = encodeVarintTx(dAtA, i, uint64(n5))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
if m.Unordered {
|
||||
i--
|
||||
if m.Unordered {
|
||||
@ -1974,6 +2000,10 @@ func (m *TxBody) Size() (n int) {
|
||||
if m.Unordered {
|
||||
n += 2
|
||||
}
|
||||
if m.TimeoutTimestamp != nil {
|
||||
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.TimeoutTimestamp)
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
if len(m.ExtensionOptions) > 0 {
|
||||
for _, e := range m.ExtensionOptions {
|
||||
l = e.Size()
|
||||
@ -3007,6 +3037,42 @@ func (m *TxBody) Unmarshal(dAtA []byte) error {
|
||||
}
|
||||
}
|
||||
m.Unordered = bool(v != 0)
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTx
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.TimeoutTimestamp == nil {
|
||||
m.TimeoutTimestamp = new(time.Time)
|
||||
}
|
||||
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.TimeoutTimestamp, dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 1023:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ExtensionOptions", wireType)
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
|
||||
@ -79,6 +80,14 @@ type (
|
||||
GetMemo() string
|
||||
}
|
||||
|
||||
// TxWithTimeoutTimeStamp extends the Tx interface by allowing a transaction to
|
||||
// set a timeout timestamp.
|
||||
TxWithTimeoutTimeStamp interface {
|
||||
Tx
|
||||
|
||||
GetTimeoutTimeStamp() time.Time
|
||||
}
|
||||
|
||||
// TxWithTimeoutHeight extends the Tx interface by allowing a transaction to
|
||||
// set a height timeout.
|
||||
TxWithTimeoutHeight interface {
|
||||
@ -88,9 +97,9 @@ type (
|
||||
}
|
||||
|
||||
// TxWithUnordered extends the Tx interface by allowing a transaction to set
|
||||
// the unordered field, which implicitly relies on TxWithTimeoutHeight.
|
||||
// the unordered field, which implicitly relies on TxWithTimeoutTimeStamp.
|
||||
TxWithUnordered interface {
|
||||
TxWithTimeoutHeight
|
||||
TxWithTimeoutTimeStamp
|
||||
|
||||
GetUnordered() bool
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package ante
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/core/appmodule/v2"
|
||||
"cosmossdk.io/core/transaction"
|
||||
@ -227,6 +228,7 @@ type (
|
||||
sdk.Tx
|
||||
|
||||
GetTimeoutHeight() uint64
|
||||
GetTimeoutTimeStamp() time.Time
|
||||
}
|
||||
)
|
||||
|
||||
@ -266,5 +268,12 @@ func (txh TxTimeoutHeightDecorator) ValidateTx(ctx context.Context, tx sdk.Tx) e
|
||||
)
|
||||
}
|
||||
|
||||
timeoutTimestamp := timeoutTx.GetTimeoutTimeStamp()
|
||||
if !timeoutTimestamp.IsZero() && timeoutTimestamp.Unix() != 0 && timeoutTimestamp.Before(headerInfo.Time) {
|
||||
return errorsmod.Wrapf(
|
||||
sdkerrors.ErrTxTimeout, "block time: %s, timeout timestamp: %s", headerInfo.Time.String(), timeoutTimestamp.String(),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -193,21 +194,30 @@ func TestTxHeightTimeoutDecorator(t *testing.T) {
|
||||
// keys and addresses
|
||||
priv1, _, addr1 := testdata.KeyTestPubAddr()
|
||||
|
||||
currentTime := time.Now()
|
||||
|
||||
// msg and signatures
|
||||
msg := testdata.NewTestMsg(addr1)
|
||||
feeAmount := testdata.NewTestFeeAmount()
|
||||
gasLimit := testdata.NewTestGasLimit()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
timeout uint64
|
||||
height int64
|
||||
expectedErr error
|
||||
name string
|
||||
timeout uint64
|
||||
height int64
|
||||
timeoutTimestamp time.Time
|
||||
timestamp time.Time
|
||||
expectedErr error
|
||||
}{
|
||||
{"default value", 0, 10, nil},
|
||||
{"no timeout (greater height)", 15, 10, nil},
|
||||
{"no timeout (same height)", 10, 10, nil},
|
||||
{"timeout (smaller height)", 9, 10, sdkerrors.ErrTxTimeoutHeight},
|
||||
{"default value", 0, 10, time.Time{}, time.Time{}, nil},
|
||||
{"no timeout (greater height)", 15, 10, time.Time{}, time.Time{}, nil},
|
||||
{"no timeout (same height)", 10, 10, time.Time{}, time.Time{}, nil},
|
||||
{"timeout (smaller height)", 9, 10, time.Time{}, time.Time{}, sdkerrors.ErrTxTimeoutHeight},
|
||||
{"no timeout (timeout after timestamp)", 0, 20, currentTime.Add(time.Minute), currentTime, nil},
|
||||
{"no timeout (current time)", 0, 20, currentTime, currentTime, nil},
|
||||
{"timeout before timestamp", 0, 20, currentTime, currentTime.Add(time.Minute), sdkerrors.ErrTxTimeout},
|
||||
{"tx contain both timeouts, timeout (timeout before timestamp)", 15, 10, currentTime, currentTime.Add(time.Minute), sdkerrors.ErrTxTimeout},
|
||||
{"tx contain both timeout, no timeout", 15, 10, currentTime.Add(time.Minute), currentTime, nil},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -222,12 +232,14 @@ func TestTxHeightTimeoutDecorator(t *testing.T) {
|
||||
suite.txBuilder.SetGasLimit(gasLimit)
|
||||
suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10))
|
||||
suite.txBuilder.SetTimeoutHeight(tc.timeout)
|
||||
suite.txBuilder.SetTimeoutTimestamp(tc.timeoutTimestamp)
|
||||
|
||||
privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
|
||||
tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
|
||||
require.NoError(t, err)
|
||||
|
||||
mockHeaderService.WithBlockHeight(tc.height)
|
||||
mockHeaderService.WithBlockTime(tc.timestamp)
|
||||
_, err = antehandler(suite.ctx, tx, true)
|
||||
require.ErrorIs(t, err, tc.expectedErr)
|
||||
})
|
||||
@ -247,3 +259,7 @@ func (m *mockHeaderService) HeaderInfo(_ context.Context) header.Info {
|
||||
func (m *mockHeaderService) WithBlockHeight(height int64) {
|
||||
m.exp.Height = height
|
||||
}
|
||||
|
||||
func (m *mockHeaderService) WithBlockTime(blocktime time.Time) {
|
||||
m.exp.Time = blocktime
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto" // nolint: staticcheck // for proto.Message
|
||||
|
||||
@ -42,18 +43,18 @@ var _ sdk.AnteDecorator = (*UnorderedTxDecorator)(nil)
|
||||
// chain to ensure that during DeliverTx, the transaction is added to the UnorderedTxManager.
|
||||
type UnorderedTxDecorator struct {
|
||||
// maxUnOrderedTTL defines the maximum TTL a transaction can define.
|
||||
maxUnOrderedTTL uint64
|
||||
txManager *unorderedtx.Manager
|
||||
env appmodule.Environment
|
||||
sha256Cost uint64
|
||||
maxTimeoutDuration time.Duration
|
||||
txManager *unorderedtx.Manager
|
||||
env appmodule.Environment
|
||||
sha256Cost uint64
|
||||
}
|
||||
|
||||
func NewUnorderedTxDecorator(maxTTL uint64, m *unorderedtx.Manager, env appmodule.Environment, gasCost uint64) *UnorderedTxDecorator {
|
||||
func NewUnorderedTxDecorator(maxDuration time.Duration, m *unorderedtx.Manager, env appmodule.Environment, gasCost uint64) *UnorderedTxDecorator {
|
||||
return &UnorderedTxDecorator{
|
||||
maxUnOrderedTTL: maxTTL,
|
||||
txManager: m,
|
||||
env: env,
|
||||
sha256Cost: gasCost,
|
||||
maxTimeoutDuration: maxDuration,
|
||||
txManager: m,
|
||||
env: env,
|
||||
sha256Cost: gasCost,
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,17 +66,16 @@ func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, _ bool, ne
|
||||
return next(ctx, tx, false)
|
||||
}
|
||||
|
||||
// TTL is defined as a specific block height at which this tx is no longer valid
|
||||
ttl := unorderedTx.GetTimeoutHeight()
|
||||
|
||||
if ttl == 0 {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction must have timeout_height set")
|
||||
headerInfo := d.env.HeaderService.HeaderInfo(ctx)
|
||||
timeoutTimestamp := unorderedTx.GetTimeoutTimeStamp()
|
||||
if timeoutTimestamp.IsZero() || timeoutTimestamp.Unix() == 0 {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction must have timeout_timestamp set")
|
||||
}
|
||||
if ttl < uint64(ctx.BlockHeight()) {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction has a timeout_height that has already passed")
|
||||
if timeoutTimestamp.Before(headerInfo.Time) {
|
||||
return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction has a timeout_timestamp that has already passed")
|
||||
}
|
||||
if ttl > uint64(ctx.BlockHeight())+d.maxUnOrderedTTL {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unordered tx ttl exceeds %d", d.maxUnOrderedTTL)
|
||||
if timeoutTimestamp.After(headerInfo.Time.Add(d.maxTimeoutDuration)) {
|
||||
return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unordered tx ttl exceeds %s", d.maxTimeoutDuration.String())
|
||||
}
|
||||
|
||||
// consume gas in all exec modes to avoid gas estimation discrepancies
|
||||
@ -90,7 +90,7 @@ func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, _ bool, ne
|
||||
}
|
||||
|
||||
// calculate the tx hash
|
||||
txHash, err := TxIdentifier(ttl, tx)
|
||||
txHash, err := TxIdentifier(uint64(timeoutTimestamp.Unix()), tx)
|
||||
if err != nil {
|
||||
return ctx, err
|
||||
}
|
||||
@ -101,7 +101,7 @@ func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, _ bool, ne
|
||||
}
|
||||
if d.env.TransactionService.ExecMode(ctx) == transaction.ExecModeFinalize {
|
||||
// a new tx included in the block, add the hash to the unordered tx manager
|
||||
d.txManager.Add(txHash, ttl)
|
||||
d.txManager.Add(txHash, timeoutTimestamp)
|
||||
}
|
||||
|
||||
return next(ctx, tx, false)
|
||||
|
||||
@ -2,9 +2,11 @@ package ante_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"cosmossdk.io/core/header"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
"cosmossdk.io/x/auth/ante"
|
||||
"cosmossdk.io/x/auth/ante/unorderedtx"
|
||||
@ -27,10 +29,10 @@ func TestUnorderedTxDecorator_OrderedTx(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, false, 0)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
|
||||
tx, txBz := genUnorderedTx(t, false, time.Time{})
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz)
|
||||
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.NoError(t, err)
|
||||
@ -46,10 +48,10 @@ func TestUnorderedTxDecorator_UnorderedTx_NoTTL(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, 0)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
|
||||
tx, txBz := genUnorderedTx(t, true, time.Time{})
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz)
|
||||
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.Error(t, err)
|
||||
@ -65,11 +67,10 @@ func TestUnorderedTxDecorator_UnorderedTx_InvalidTTL(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, 100+unorderedtx.DefaultMaxUnOrderedTTL+1)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100)
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, time.Now().Add(unorderedtx.DefaultMaxTimeoutDuration+time.Second))
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithHeaderInfo(header.Info{Time: time.Now()})
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.Error(t, err)
|
||||
}
|
||||
@ -84,14 +85,14 @@ func TestUnorderedTxDecorator_UnorderedTx_AlreadyExists(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, 150)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute))
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithHeaderInfo(header.Info{Time: time.Now()}).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
|
||||
bz := [32]byte{}
|
||||
copy(bz[:], txBz[:32])
|
||||
txm.Add(bz, 150)
|
||||
txm.Add(bz, time.Now().Add(time.Minute))
|
||||
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.Error(t, err)
|
||||
@ -107,10 +108,10 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidCheckTx(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, 150)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeCheck).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute))
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithHeaderInfo(header.Info{Time: time.Now()}).WithExecMode(sdk.ExecModeCheck).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.NoError(t, err)
|
||||
@ -126,10 +127,10 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidDeliverTx(t *testing.T) {
|
||||
|
||||
suite := SetupTestSuite(t, false)
|
||||
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, suite.accountKeeper.GetEnvironment(), ante.DefaultSha256Cost))
|
||||
|
||||
tx, txBz := genUnorderedTx(t, true, 150)
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeFinalize).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute))
|
||||
ctx := sdk.Context{}.WithTxBytes(txBz).WithHeaderInfo(header.Info{Time: time.Now()}).WithExecMode(sdk.ExecModeFinalize).WithGasMeter(storetypes.NewGasMeter(gasConsumed))
|
||||
|
||||
_, err := chain(ctx, tx, false)
|
||||
require.NoError(t, err)
|
||||
@ -140,7 +141,7 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidDeliverTx(t *testing.T) {
|
||||
require.True(t, txm.Contains(bz))
|
||||
}
|
||||
|
||||
func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) {
|
||||
func genUnorderedTx(t *testing.T, unordered bool, timestamp time.Time) (sdk.Tx, []byte) {
|
||||
t.Helper()
|
||||
|
||||
s := SetupTestSuite(t, true)
|
||||
@ -158,13 +159,13 @@ func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) {
|
||||
s.txBuilder.SetFeeAmount(feeAmount)
|
||||
s.txBuilder.SetGasLimit(gasLimit)
|
||||
s.txBuilder.SetUnordered(unordered)
|
||||
s.txBuilder.SetTimeoutHeight(ttl)
|
||||
s.txBuilder.SetTimeoutTimestamp(timestamp)
|
||||
|
||||
privKeys, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0}
|
||||
tx, err := s.CreateTestTx(s.ctx, privKeys, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT)
|
||||
require.NoError(t, err)
|
||||
|
||||
txBz, err := ante.TxIdentifier(ttl, tx)
|
||||
txBz, err := ante.TxIdentifier(uint64(timestamp.Unix()), tx)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@ -18,9 +18,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultMaxUnOrderedTTL defines the default maximum TTL an un-ordered transaction
|
||||
// DefaultmaxTimeoutDuration defines the default maximum duration an un-ordered transaction
|
||||
// can set.
|
||||
DefaultMaxUnOrderedTTL = 1024
|
||||
DefaultMaxTimeoutDuration = time.Minute * 40
|
||||
|
||||
dirName = "unordered_txs"
|
||||
fileName = "data"
|
||||
@ -33,7 +33,7 @@ type TxHash [32]byte
|
||||
// them when block production progresses.
|
||||
type Manager struct {
|
||||
// blockCh defines a channel to receive newly committed block heights
|
||||
blockCh chan uint64
|
||||
blockCh chan time.Time
|
||||
// doneCh allows us to ensure the purgeLoop has gracefully terminated prior to closing
|
||||
doneCh chan struct{}
|
||||
|
||||
@ -48,10 +48,11 @@ type Manager struct {
|
||||
dataDir string
|
||||
|
||||
mu sync.RWMutex
|
||||
// txHashes defines a map from tx hash -> TTL value, which is used for duplicate
|
||||
|
||||
// txHashes defines a map from tx hash -> TTL value defined as block time, which is used for duplicate
|
||||
// checking and replay protection, as well as purging the map when the TTL is
|
||||
// expired.
|
||||
txHashes map[TxHash]uint64
|
||||
txHashes map[TxHash]time.Time
|
||||
}
|
||||
|
||||
func NewManager(dataDir string) *Manager {
|
||||
@ -62,9 +63,9 @@ func NewManager(dataDir string) *Manager {
|
||||
|
||||
m := &Manager{
|
||||
dataDir: dataDir,
|
||||
blockCh: make(chan uint64, 16),
|
||||
blockCh: make(chan time.Time, 16),
|
||||
doneCh: make(chan struct{}),
|
||||
txHashes: make(map[TxHash]uint64),
|
||||
txHashes: make(map[TxHash]time.Time),
|
||||
}
|
||||
|
||||
return m
|
||||
@ -91,7 +92,6 @@ func (m *Manager) Close() error {
|
||||
func (m *Manager) Contains(hash TxHash) bool {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
_, ok := m.txHashes[hash]
|
||||
return ok
|
||||
}
|
||||
@ -103,11 +103,11 @@ func (m *Manager) Size() int {
|
||||
return len(m.txHashes)
|
||||
}
|
||||
|
||||
func (m *Manager) Add(txHash TxHash, ttl uint64) {
|
||||
func (m *Manager) Add(txHash TxHash, timestamp time.Time) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.txHashes[txHash] = ttl
|
||||
m.txHashes[txHash] = timestamp
|
||||
}
|
||||
|
||||
// OnInit must be called when a node starts up. Typically, this should be called
|
||||
@ -145,7 +145,8 @@ func (m *Manager) OnInit() error {
|
||||
var txHash TxHash
|
||||
copy(txHash[:], buf[:txHashSize])
|
||||
|
||||
m.Add(txHash, binary.BigEndian.Uint64(buf[txHashSize:]))
|
||||
timeStamp := binary.BigEndian.Uint64(buf[txHashSize:])
|
||||
m.Add(txHash, time.Unix(int64(timeStamp), 0))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -153,8 +154,8 @@ func (m *Manager) OnInit() error {
|
||||
|
||||
// OnNewBlock sends the latest block number to the background purge loop, which
|
||||
// should be called in ABCI Commit event.
|
||||
func (m *Manager) OnNewBlock(blockHeight uint64) {
|
||||
m.blockCh <- blockHeight
|
||||
func (m *Manager) OnNewBlock(blockTime time.Time) {
|
||||
m.blockCh <- blockTime
|
||||
}
|
||||
|
||||
func (m *Manager) exportSnapshot(height uint64, snapshotWriter func([]byte) error) error {
|
||||
@ -164,14 +165,16 @@ func (m *Manager) exportSnapshot(height uint64, snapshotWriter func([]byte) erro
|
||||
keys := maps.Keys(m.txHashes)
|
||||
sort.Slice(keys, func(i, j int) bool { return bytes.Compare(keys[i][:], keys[j][:]) < 0 })
|
||||
|
||||
timestamp := time.Unix(int64(height), 0)
|
||||
for _, txHash := range keys {
|
||||
ttl := m.txHashes[txHash]
|
||||
if height > ttl {
|
||||
timeoutTime := m.txHashes[txHash]
|
||||
if timestamp.After(timeoutTime) {
|
||||
// skip expired txs that have yet to be purged
|
||||
continue
|
||||
}
|
||||
|
||||
chunk := unorderedTxToBytes(txHash, ttl)
|
||||
// right now we dont have access block time at this flow, so we would just include the expired txs
|
||||
// and let it be purge during purge loop
|
||||
chunk := unorderedTxToBytes(txHash, uint64(timeoutTime.Unix()))
|
||||
|
||||
if _, err := w.Write(chunk); err != nil {
|
||||
return fmt.Errorf("failed to write unordered tx to buffer: %w", err)
|
||||
@ -195,8 +198,8 @@ func (m *Manager) flushToFile() error {
|
||||
defer f.Close()
|
||||
|
||||
w := bufio.NewWriter(f)
|
||||
for txHash, ttl := range m.txHashes {
|
||||
chunk := unorderedTxToBytes(txHash, ttl)
|
||||
for txHash, timestamp := range m.txHashes {
|
||||
chunk := unorderedTxToBytes(txHash, uint64(timestamp.Unix()))
|
||||
|
||||
if _, err = w.Write(chunk); err != nil {
|
||||
return fmt.Errorf("failed to write unordered tx to buffer: %w", err)
|
||||
@ -211,13 +214,13 @@ func (m *Manager) flushToFile() error {
|
||||
}
|
||||
|
||||
// expiredTxs returns expired tx hashes based on the provided block height.
|
||||
func (m *Manager) expiredTxs(blockHeight uint64) []TxHash {
|
||||
func (m *Manager) expiredTxs(blockTime time.Time) []TxHash {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
var result []TxHash
|
||||
for txHash, ttl := range m.txHashes {
|
||||
if blockHeight > ttl {
|
||||
for txHash, timestamp := range m.txHashes {
|
||||
if blockTime.After(timestamp) {
|
||||
result = append(result, txHash)
|
||||
}
|
||||
}
|
||||
@ -237,37 +240,38 @@ func (m *Manager) purge(txHashes []TxHash) {
|
||||
// purgeLoop removes expired tx hashes in the background
|
||||
func (m *Manager) purgeLoop() {
|
||||
for {
|
||||
latestHeight, ok := m.batchReceive()
|
||||
latestTime, ok := m.batchReceive()
|
||||
if !ok {
|
||||
// channel closed
|
||||
m.doneCh <- struct{}{}
|
||||
return
|
||||
}
|
||||
|
||||
hashes := m.expiredTxs(latestHeight)
|
||||
hashes := m.expiredTxs(latestTime)
|
||||
if len(hashes) > 0 {
|
||||
m.purge(hashes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) batchReceive() (uint64, bool) {
|
||||
func (m *Manager) batchReceive() (time.Time, bool) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
var latestHeight uint64
|
||||
var latestTime time.Time
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return latestHeight, true
|
||||
return latestTime, true
|
||||
|
||||
case blockHeight, ok := <-m.blockCh:
|
||||
case blockTime, ok := <-m.blockCh:
|
||||
if !ok {
|
||||
// channel is closed
|
||||
return 0, false
|
||||
return time.Time{}, false
|
||||
}
|
||||
if blockHeight > latestHeight {
|
||||
latestHeight = blockHeight
|
||||
|
||||
if blockTime.After(latestTime) {
|
||||
latestTime = blockTime
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,7 +281,7 @@ func unorderedTxToBytes(txHash TxHash, ttl uint64) []byte {
|
||||
chunk := make([]byte, chunkSize)
|
||||
copy(chunk[:txHashSize], txHash[:])
|
||||
|
||||
ttlBz := make([]byte, ttlSize)
|
||||
ttlBz := make([]byte, timeoutSize)
|
||||
binary.BigEndian.PutUint64(ttlBz, ttl)
|
||||
copy(chunk[txHashSize:], ttlBz)
|
||||
|
||||
|
||||
@ -25,9 +25,9 @@ func TestUnorderedTxManager_SimpleSize(t *testing.T) {
|
||||
|
||||
txm.Start()
|
||||
|
||||
txm.Add([32]byte{0xFF}, 100)
|
||||
txm.Add([32]byte{0xAA}, 100)
|
||||
txm.Add([32]byte{0xCC}, 100)
|
||||
txm.Add([32]byte{0xFF}, time.Now())
|
||||
txm.Add([32]byte{0xAA}, time.Now())
|
||||
txm.Add([32]byte{0xCC}, time.Now())
|
||||
|
||||
require.Equal(t, 3, txm.Size())
|
||||
}
|
||||
@ -42,7 +42,7 @@ func TestUnorderedTxManager_SimpleContains(t *testing.T) {
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
txHash := [32]byte{byte(i)}
|
||||
txm.Add(txHash, 100)
|
||||
txm.Add(txHash, time.Now())
|
||||
require.True(t, txm.Contains(txHash))
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ func TestUnorderedTxManager_CloseInit(t *testing.T) {
|
||||
|
||||
// add a handful of unordered txs
|
||||
for i := 0; i < 100; i++ {
|
||||
txm.Add([32]byte{byte(i)}, 100)
|
||||
txm.Add([32]byte{byte(i)}, time.Now())
|
||||
}
|
||||
|
||||
// close the manager, which should flush all unexpired txs to file
|
||||
@ -100,15 +100,17 @@ func TestUnorderedTxManager_Flow(t *testing.T) {
|
||||
|
||||
txm.Start()
|
||||
|
||||
currentTime := time.Now()
|
||||
|
||||
// Seed the manager with a txs, some of which should eventually be purged and
|
||||
// the others will remain. Txs with TTL less than or equal to 50 should be purged.
|
||||
for i := 1; i <= 100; i++ {
|
||||
txHash := [32]byte{byte(i)}
|
||||
|
||||
if i <= 50 {
|
||||
txm.Add(txHash, uint64(i))
|
||||
txm.Add(txHash, currentTime.Add(time.Millisecond*500*time.Duration(i)))
|
||||
} else {
|
||||
txm.Add(txHash, 100)
|
||||
txm.Add(txHash, currentTime.Add(time.Hour))
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,19 +120,12 @@ func TestUnorderedTxManager_Flow(t *testing.T) {
|
||||
ticker := time.NewTicker(time.Millisecond * 500)
|
||||
defer ticker.Stop()
|
||||
|
||||
var (
|
||||
height uint64 = 1
|
||||
i = 101
|
||||
)
|
||||
for range ticker.C {
|
||||
txm.OnNewBlock(height)
|
||||
height++
|
||||
for t := range ticker.C {
|
||||
txm.OnNewBlock(t)
|
||||
|
||||
if height > 51 {
|
||||
if t.After(currentTime.Add(time.Millisecond * 500 * time.Duration(50))) {
|
||||
doneBlockCh <- true
|
||||
return
|
||||
} else {
|
||||
txm.Add([32]byte{byte(i)}, 50)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@ -4,14 +4,15 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
snapshot "cosmossdk.io/store/snapshots/types"
|
||||
)
|
||||
|
||||
const (
|
||||
txHashSize = 32
|
||||
ttlSize = 8
|
||||
chunkSize = txHashSize + ttlSize
|
||||
txHashSize = 32
|
||||
timeoutSize = 8
|
||||
chunkSize = txHashSize + timeoutSize
|
||||
)
|
||||
|
||||
var _ snapshot.ExtensionSnapshotter = &Snapshotter{}
|
||||
@ -78,11 +79,13 @@ func (s *Snapshotter) restore(height uint64, payloadReader snapshot.ExtensionPay
|
||||
var txHash TxHash
|
||||
copy(txHash[:], payload[i:i+txHashSize])
|
||||
|
||||
ttl := binary.BigEndian.Uint64(payload[i+txHashSize : i+chunkSize])
|
||||
|
||||
if height < ttl {
|
||||
// only add unordered transactions that are still valid, i.e. unexpired
|
||||
s.m.Add(txHash, ttl)
|
||||
timestamp := binary.BigEndian.Uint64(payload[i+txHashSize : i+chunkSize])
|
||||
// need to come up with a way to fetch blocktime to filter out expired txs
|
||||
//
|
||||
// right now we dont have access block time at this flow, so we would just include the expired txs
|
||||
// and let it be purge during purge loop
|
||||
if timestamp != 0 && timestamp > height {
|
||||
s.m.Add(txHash, time.Unix(int64(timestamp), 0))
|
||||
}
|
||||
|
||||
i += chunkSize
|
||||
|
||||
@ -2,6 +2,7 @@ package unorderedtx_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@ -12,9 +13,11 @@ func TestSnapshotter(t *testing.T) {
|
||||
dataDir := t.TempDir()
|
||||
txm := unorderedtx.NewManager(dataDir)
|
||||
|
||||
currentTime := time.Now()
|
||||
|
||||
// add a handful of unordered txs
|
||||
for i := 0; i < 100; i++ {
|
||||
txm.Add([32]byte{byte(i)}, 100)
|
||||
txm.Add([32]byte{byte(i)}, currentTime.Add(time.Second*100))
|
||||
}
|
||||
|
||||
var unorderedTxBz []byte
|
||||
@ -36,17 +39,17 @@ func TestSnapshotter(t *testing.T) {
|
||||
err = s.RestoreExtension(50, 2, pr)
|
||||
require.Error(t, err)
|
||||
|
||||
// restore with height > ttl which should result in no unordered txs synced
|
||||
// restore with timestamp > timeout time which should result in no unordered txs synced
|
||||
txm2 := unorderedtx.NewManager(dataDir)
|
||||
s2 := unorderedtx.NewSnapshotter(txm2)
|
||||
err = s2.RestoreExtension(200, unorderedtx.SnapshotFormat, pr)
|
||||
err = s2.RestoreExtension(uint64(currentTime.Add(time.Second*200).Unix()), unorderedtx.SnapshotFormat, pr)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, txm2.Size())
|
||||
|
||||
// restore with height < ttl which should result in all unordered txs synced
|
||||
// restore with timestamp < timeout time which should result in all unordered txs synced
|
||||
txm3 := unorderedtx.NewManager(dataDir)
|
||||
s3 := unorderedtx.NewSnapshotter(txm3)
|
||||
err = s3.RestoreExtension(50, unorderedtx.SnapshotFormat, pr)
|
||||
err = s3.RestoreExtension(uint64(currentTime.Add(time.Second*50).Unix()), unorderedtx.SnapshotFormat, pr)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 100, txm3.Size())
|
||||
|
||||
|
||||
@ -3,9 +3,11 @@ package tx
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
basev1beta1 "cosmossdk.io/api/cosmos/base/v1beta1"
|
||||
multisigv1beta1 "cosmossdk.io/api/cosmos/crypto/multisig/v1beta1"
|
||||
@ -79,16 +81,17 @@ type builder struct {
|
||||
decoder *decode.Decoder
|
||||
codec codec.BinaryCodec
|
||||
|
||||
msgs []sdk.Msg
|
||||
timeoutHeight uint64
|
||||
granter []byte
|
||||
payer []byte
|
||||
unordered bool
|
||||
memo string
|
||||
gasLimit uint64
|
||||
fees sdk.Coins
|
||||
signerInfos []*tx.SignerInfo
|
||||
signatures [][]byte
|
||||
msgs []sdk.Msg
|
||||
timeoutHeight uint64
|
||||
timeoutTimestamp time.Time
|
||||
granter []byte
|
||||
payer []byte
|
||||
unordered bool
|
||||
memo string
|
||||
gasLimit uint64
|
||||
fees sdk.Coins
|
||||
signerInfos []*tx.SignerInfo
|
||||
signatures [][]byte
|
||||
|
||||
extensionOptions []*codectypes.Any
|
||||
nonCriticalExtensionOptions []*codectypes.Any
|
||||
@ -115,6 +118,7 @@ func (w *builder) getTx() (*gogoTxWrapper, error) {
|
||||
Messages: anyMsgs,
|
||||
Memo: w.memo,
|
||||
TimeoutHeight: w.timeoutHeight,
|
||||
TimeoutTimestamp: timestamppb.New(w.timeoutTimestamp),
|
||||
Unordered: w.unordered,
|
||||
ExtensionOptions: intoAnyV2(w.extensionOptions),
|
||||
NonCriticalExtensionOptions: intoAnyV2(w.nonCriticalExtensionOptions),
|
||||
@ -189,6 +193,8 @@ func (w *builder) SetMsgs(msgs ...sdk.Msg) error {
|
||||
// SetTimeoutHeight sets the transaction's height timeout.
|
||||
func (w *builder) SetTimeoutHeight(height uint64) { w.timeoutHeight = height }
|
||||
|
||||
func (w *builder) SetTimeoutTimestamp(timestamp time.Time) { w.timeoutTimestamp = timestamp }
|
||||
|
||||
func (w *builder) SetUnordered(v bool) { w.unordered = v }
|
||||
|
||||
func (w *builder) SetMemo(memo string) { w.memo = memo }
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/gogoproto/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
@ -177,6 +178,11 @@ func (w *gogoTxWrapper) GetMemo() string { return w.Tx.Body.Memo }
|
||||
// GetTimeoutHeight returns the transaction's timeout height (if set).
|
||||
func (w *gogoTxWrapper) GetTimeoutHeight() uint64 { return w.Tx.Body.TimeoutHeight }
|
||||
|
||||
// GetTimeoutTimeStamp returns the transaction's timeout timestamp (if set).
|
||||
func (w *gogoTxWrapper) GetTimeoutTimeStamp() time.Time {
|
||||
return w.Tx.Body.TimeoutTimestamp.AsTime()
|
||||
}
|
||||
|
||||
// GetUnordered returns the transaction's unordered field (if set).
|
||||
func (w *gogoTxWrapper) GetUnordered() bool { return w.Tx.Body.Unordered }
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user