feat: Add PrepareCheckState and Precommit callbacks (#14860)

Co-authored-by: dydxwill <119354122+dydxwill@users.noreply.github.com>
This commit is contained in:
Bryce Neal 2023-04-23 12:04:36 -04:00 committed by GitHub
parent be081b1051
commit 93d64cc6fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 925 additions and 69 deletions

View File

@ -62,6 +62,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (runtime) [#15547](https://github.com/cosmos/cosmos-sdk/pull/15547) Allow runtime to pass event core api service to modules
* (telemetry) [#15657](https://github.com/cosmos/cosmos-sdk/pull/15657) Emit more data (go version, sdk version, upgrade height) in prom metrics
* (modulemanager) [#15829](https://github.com/cosmos/cosmos-sdk/pull/15829) add new endblocker interface to handle valset updates
* (core) [#14860](https://github.com/cosmos/cosmos-sdk/pull/14860) Add `Precommit` and `PrepareCheckState` AppModule callbacks.
### Improvements

View File

@ -294,15 +294,109 @@ func (x *_Module_7_list) IsValid() bool {
return x.list != nil
}
var _ protoreflect.List = (*_Module_8_list)(nil)
type _Module_8_list struct {
list *[]string
}
func (x *_Module_8_list) Len() int {
if x.list == nil {
return 0
}
return len(*x.list)
}
func (x *_Module_8_list) Get(i int) protoreflect.Value {
return protoreflect.ValueOfString((*x.list)[i])
}
func (x *_Module_8_list) Set(i int, value protoreflect.Value) {
valueUnwrapped := value.String()
concreteValue := valueUnwrapped
(*x.list)[i] = concreteValue
}
func (x *_Module_8_list) Append(value protoreflect.Value) {
valueUnwrapped := value.String()
concreteValue := valueUnwrapped
*x.list = append(*x.list, concreteValue)
}
func (x *_Module_8_list) AppendMutable() protoreflect.Value {
panic(fmt.Errorf("AppendMutable can not be called on message Module at list field Precommiters as it is not of Message kind"))
}
func (x *_Module_8_list) Truncate(n int) {
*x.list = (*x.list)[:n]
}
func (x *_Module_8_list) NewElement() protoreflect.Value {
v := ""
return protoreflect.ValueOfString(v)
}
func (x *_Module_8_list) IsValid() bool {
return x.list != nil
}
var _ protoreflect.List = (*_Module_9_list)(nil)
type _Module_9_list struct {
list *[]string
}
func (x *_Module_9_list) Len() int {
if x.list == nil {
return 0
}
return len(*x.list)
}
func (x *_Module_9_list) Get(i int) protoreflect.Value {
return protoreflect.ValueOfString((*x.list)[i])
}
func (x *_Module_9_list) Set(i int, value protoreflect.Value) {
valueUnwrapped := value.String()
concreteValue := valueUnwrapped
(*x.list)[i] = concreteValue
}
func (x *_Module_9_list) Append(value protoreflect.Value) {
valueUnwrapped := value.String()
concreteValue := valueUnwrapped
*x.list = append(*x.list, concreteValue)
}
func (x *_Module_9_list) AppendMutable() protoreflect.Value {
panic(fmt.Errorf("AppendMutable can not be called on message Module at list field PrepareCheckStaters as it is not of Message kind"))
}
func (x *_Module_9_list) Truncate(n int) {
*x.list = (*x.list)[:n]
}
func (x *_Module_9_list) NewElement() protoreflect.Value {
v := ""
return protoreflect.ValueOfString(v)
}
func (x *_Module_9_list) IsValid() bool {
return x.list != nil
}
var (
md_Module protoreflect.MessageDescriptor
fd_Module_app_name protoreflect.FieldDescriptor
fd_Module_begin_blockers protoreflect.FieldDescriptor
fd_Module_end_blockers protoreflect.FieldDescriptor
fd_Module_init_genesis protoreflect.FieldDescriptor
fd_Module_export_genesis protoreflect.FieldDescriptor
fd_Module_override_store_keys protoreflect.FieldDescriptor
fd_Module_order_migrations protoreflect.FieldDescriptor
md_Module protoreflect.MessageDescriptor
fd_Module_app_name protoreflect.FieldDescriptor
fd_Module_begin_blockers protoreflect.FieldDescriptor
fd_Module_end_blockers protoreflect.FieldDescriptor
fd_Module_init_genesis protoreflect.FieldDescriptor
fd_Module_export_genesis protoreflect.FieldDescriptor
fd_Module_override_store_keys protoreflect.FieldDescriptor
fd_Module_order_migrations protoreflect.FieldDescriptor
fd_Module_precommiters protoreflect.FieldDescriptor
fd_Module_prepare_check_staters protoreflect.FieldDescriptor
)
func init() {
@ -315,6 +409,8 @@ func init() {
fd_Module_export_genesis = md_Module.Fields().ByName("export_genesis")
fd_Module_override_store_keys = md_Module.Fields().ByName("override_store_keys")
fd_Module_order_migrations = md_Module.Fields().ByName("order_migrations")
fd_Module_precommiters = md_Module.Fields().ByName("precommiters")
fd_Module_prepare_check_staters = md_Module.Fields().ByName("prepare_check_staters")
}
var _ protoreflect.Message = (*fastReflection_Module)(nil)
@ -424,6 +520,18 @@ func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, proto
return
}
}
if len(x.Precommiters) != 0 {
value := protoreflect.ValueOfList(&_Module_8_list{list: &x.Precommiters})
if !f(fd_Module_precommiters, value) {
return
}
}
if len(x.PrepareCheckStaters) != 0 {
value := protoreflect.ValueOfList(&_Module_9_list{list: &x.PrepareCheckStaters})
if !f(fd_Module_prepare_check_staters, value) {
return
}
}
}
// Has reports whether a field is populated.
@ -453,6 +561,10 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool {
return len(x.OverrideStoreKeys) != 0
case "cosmos.app.runtime.v1alpha1.Module.order_migrations":
return len(x.OrderMigrations) != 0
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
return len(x.Precommiters) != 0
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
return len(x.PrepareCheckStaters) != 0
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module"))
@ -483,6 +595,10 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) {
x.OverrideStoreKeys = nil
case "cosmos.app.runtime.v1alpha1.Module.order_migrations":
x.OrderMigrations = nil
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
x.Precommiters = nil
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
x.PrepareCheckStaters = nil
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module"))
@ -538,6 +654,18 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro
}
listValue := &_Module_7_list{list: &x.OrderMigrations}
return protoreflect.ValueOfList(listValue)
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
if len(x.Precommiters) == 0 {
return protoreflect.ValueOfList(&_Module_8_list{})
}
listValue := &_Module_8_list{list: &x.Precommiters}
return protoreflect.ValueOfList(listValue)
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
if len(x.PrepareCheckStaters) == 0 {
return protoreflect.ValueOfList(&_Module_9_list{})
}
listValue := &_Module_9_list{list: &x.PrepareCheckStaters}
return protoreflect.ValueOfList(listValue)
default:
if descriptor.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module"))
@ -584,6 +712,14 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto
lv := value.List()
clv := lv.(*_Module_7_list)
x.OrderMigrations = *clv.list
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
lv := value.List()
clv := lv.(*_Module_8_list)
x.Precommiters = *clv.list
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
lv := value.List()
clv := lv.(*_Module_9_list)
x.PrepareCheckStaters = *clv.list
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module"))
@ -640,6 +776,18 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore
}
value := &_Module_7_list{list: &x.OrderMigrations}
return protoreflect.ValueOfList(value)
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
if x.Precommiters == nil {
x.Precommiters = []string{}
}
value := &_Module_8_list{list: &x.Precommiters}
return protoreflect.ValueOfList(value)
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
if x.PrepareCheckStaters == nil {
x.PrepareCheckStaters = []string{}
}
value := &_Module_9_list{list: &x.PrepareCheckStaters}
return protoreflect.ValueOfList(value)
case "cosmos.app.runtime.v1alpha1.Module.app_name":
panic(fmt.Errorf("field app_name of message cosmos.app.runtime.v1alpha1.Module is not mutable"))
default:
@ -675,6 +823,12 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor
case "cosmos.app.runtime.v1alpha1.Module.order_migrations":
list := []string{}
return protoreflect.ValueOfList(&_Module_7_list{list: &list})
case "cosmos.app.runtime.v1alpha1.Module.precommiters":
list := []string{}
return protoreflect.ValueOfList(&_Module_8_list{list: &list})
case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters":
list := []string{}
return protoreflect.ValueOfList(&_Module_9_list{list: &list})
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module"))
@ -784,6 +938,18 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods {
n += 1 + l + runtime.Sov(uint64(l))
}
}
if len(x.Precommiters) > 0 {
for _, s := range x.Precommiters {
l = len(s)
n += 1 + l + runtime.Sov(uint64(l))
}
}
if len(x.PrepareCheckStaters) > 0 {
for _, s := range x.PrepareCheckStaters {
l = len(s)
n += 1 + l + runtime.Sov(uint64(l))
}
}
if x.unknownFields != nil {
n += len(x.unknownFields)
}
@ -813,6 +979,24 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods {
i -= len(x.unknownFields)
copy(dAtA[i:], x.unknownFields)
}
if len(x.PrepareCheckStaters) > 0 {
for iNdEx := len(x.PrepareCheckStaters) - 1; iNdEx >= 0; iNdEx-- {
i -= len(x.PrepareCheckStaters[iNdEx])
copy(dAtA[i:], x.PrepareCheckStaters[iNdEx])
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PrepareCheckStaters[iNdEx])))
i--
dAtA[i] = 0x4a
}
}
if len(x.Precommiters) > 0 {
for iNdEx := len(x.Precommiters) - 1; iNdEx >= 0; iNdEx-- {
i -= len(x.Precommiters[iNdEx])
copy(dAtA[i:], x.Precommiters[iNdEx])
i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Precommiters[iNdEx])))
i--
dAtA[i] = 0x42
}
}
if len(x.OrderMigrations) > 0 {
for iNdEx := len(x.OrderMigrations) - 1; iNdEx >= 0; iNdEx-- {
i -= len(x.OrderMigrations[iNdEx])
@ -1156,6 +1340,70 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods {
}
x.OrderMigrations = append(x.OrderMigrations, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 8:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Precommiters", wireType)
}
var stringLen uint64
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++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if postIndex > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
x.Precommiters = append(x.Precommiters, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 9:
if wireType != 2 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PrepareCheckStaters", wireType)
}
var stringLen uint64
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++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if postIndex > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
x.PrepareCheckStaters = append(x.PrepareCheckStaters, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := runtime.Skip(dAtA[iNdEx:])
@ -1719,6 +1967,14 @@ type Module struct {
// If this is left empty, it uses the default migration order.
// https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.47.0-alpha2/types/module#DefaultMigrationsOrder
OrderMigrations []string `protobuf:"bytes,7,rep,name=order_migrations,json=orderMigrations,proto3" json:"order_migrations,omitempty"`
// precommiters specifies the module names of the precommiters
// to call in the order in which they should be called. If this is left empty
// no precommit function will be registered.
Precommiters []string `protobuf:"bytes,8,rep,name=precommiters,proto3" json:"precommiters,omitempty"`
// prepare_check_staters specifies the module names of the prepare_check_staters
// to call in the order in which they should be called. If this is left empty
// no preparecheckstate function will be registered.
PrepareCheckStaters []string `protobuf:"bytes,9,rep,name=prepare_check_staters,json=prepareCheckStaters,proto3" json:"prepare_check_staters,omitempty"`
}
func (x *Module) Reset() {
@ -1790,6 +2046,20 @@ func (x *Module) GetOrderMigrations() []string {
return nil
}
func (x *Module) GetPrecommiters() []string {
if x != nil {
return x.Precommiters
}
return nil
}
func (x *Module) GetPrepareCheckStaters() []string {
if x != nil {
return x.PrepareCheckStaters
}
return nil
}
// StoreKeyConfig may be supplied to override the default module store key, which
// is the module name.
type StoreKeyConfig struct {
@ -1846,7 +2116,7 @@ var file_cosmos_app_runtime_v1alpha1_module_proto_rawDesc = []byte{
0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f,
0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64,
0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x03, 0x0a, 0x06, 0x4d, 0x6f,
0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, 0x03, 0x0a, 0x06, 0x4d, 0x6f,
0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12,
0x25, 0x0a, 0x0e, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x72,
@ -1866,33 +2136,39 @@ var file_cosmos_app_runtime_v1alpha1_module_proto_rawDesc = []byte{
0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x73,
0x12, 0x29, 0x0a, 0x10, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x72, 0x64, 0x65,
0x72, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x43, 0xba, 0xc0, 0x96,
0xda, 0x01, 0x3d, 0x0a, 0x24, 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, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x13, 0x63, 0x6f, 0x73,
0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x22, 0x53, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e,
0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x6b, 0x76, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f,
0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x76, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x4b, 0x65, 0x79, 0x42, 0xfb, 0x01, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f,
0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c,
0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73,
0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41, 0x52, 0xaa, 0x02, 0x1b, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d,
0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x1b, 0x43, 0x6f, 0x73,
0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c,
0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x27, 0x43, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
0x74, 0x61, 0xea, 0x02, 0x1e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x70,
0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x72, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70,
0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x12,
0x32, 0x0a, 0x15, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b,
0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13,
0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74,
0x65, 0x72, 0x73, 0x3a, 0x43, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x3d, 0x0a, 0x24, 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, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
0x65, 0x12, 0x15, 0x0a, 0x13, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x53, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72,
0x65, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f,
0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x6b,
0x76, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x6b, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x42, 0xfb, 0x01,
0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70,
0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,
0x5a, 0x3c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x75,
0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72,
0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02,
0x03, 0x43, 0x41, 0x52, 0xaa, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70,
0x70, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0xca, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c,
0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0xe2, 0x02, 0x27, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75,
0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47,
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1e, 0x43, 0x6f, 0x73,
0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x70, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d,
0x65, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x33,
}
var (

View File

@ -457,6 +457,10 @@ func (app *BaseApp) Commit() abci.ResponseCommit {
header := app.deliverState.ctx.BlockHeader()
retainHeight := app.GetBlockRetentionHeight(header.Height)
if app.precommiter != nil {
app.precommiter(app.deliverState.ctx)
}
rms, ok := app.cms.(*rootmulti.Store)
if ok {
rms.SetCommitHeader(header)
@ -464,7 +468,7 @@ func (app *BaseApp) Commit() abci.ResponseCommit {
// Write the DeliverTx state into branched storage and commit the MultiStore.
// The write to the DeliverTx state writes all state transitions to the root
// MultiStore (app.cms) so when Commit() is called is persists those values.
// MultiStore (app.cms) so when Commit() is called it persists those values.
app.deliverState.ms.Write()
commitID := app.cms.Commit()
@ -497,6 +501,10 @@ func (app *BaseApp) Commit() abci.ResponseCommit {
// empty/reset the deliver state
app.deliverState = nil
if app.prepareCheckStater != nil {
app.prepareCheckStater(app.checkState.ctx)
}
var halt bool
switch {

View File

@ -598,6 +598,60 @@ func TestABCI_EndBlock(t *testing.T) {
require.Equal(t, cp.Block.MaxGas, res.ConsensusParamUpdates.Block.MaxGas)
}
func TestBaseApp_PrepareCheckState(t *testing.T) {
db := dbm.NewMemDB()
name := t.Name()
logger := log.NewTestLogger(t)
cp := &cmtproto.ConsensusParams{
Block: &cmtproto.BlockParams{
MaxGas: 5000000,
},
}
app := baseapp.NewBaseApp(name, logger, db, nil)
app.SetParamStore(&paramStore{db: dbm.NewMemDB()})
app.InitChain(abci.RequestInitChain{
ConsensusParams: cp,
})
wasPrepareCheckStateCalled := false
app.SetPrepareCheckStater(func(ctx sdk.Context) {
wasPrepareCheckStateCalled = true
})
app.Seal()
app.Commit()
require.Equal(t, true, wasPrepareCheckStateCalled)
}
func TestBaseApp_Precommit(t *testing.T) {
db := dbm.NewMemDB()
name := t.Name()
logger := log.NewTestLogger(t)
cp := &cmtproto.ConsensusParams{
Block: &cmtproto.BlockParams{
MaxGas: 5000000,
},
}
app := baseapp.NewBaseApp(name, logger, db, nil)
app.SetParamStore(&paramStore{db: dbm.NewMemDB()})
app.InitChain(abci.RequestInitChain{
ConsensusParams: cp,
})
wasPrecommiterCalled := false
app.SetPrecommiter(func(ctx sdk.Context) {
wasPrecommiterCalled = true
})
app.Seal()
app.Commit()
require.Equal(t, true, wasPrecommiterCalled)
}
func TestABCI_CheckTx(t *testing.T) {
// This ante handler reads the key and checks that the value matches the
// current counter. This ensures changes to the KVStore persist across
@ -1322,6 +1376,49 @@ func TestABCI_GetBlockRetentionHeight(t *testing.T) {
}
}
// Verifies that PrepareCheckState is called with the checkState.
func TestPrepareCheckStateCalledWithCheckState(t *testing.T) {
t.Parallel()
logger := log.NewTestLogger(t)
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, nil)
wasPrepareCheckStateCalled := false
app.SetPrepareCheckStater(func(ctx sdk.Context) {
require.Equal(t, true, ctx.IsCheckTx())
wasPrepareCheckStateCalled = true
})
app.BeginBlock(abci.RequestBeginBlock{Header: cmtproto.Header{Height: 1}})
app.Commit()
require.Equal(t, true, wasPrepareCheckStateCalled)
}
// Verifies that the Precommiter is called with the deliverState.
func TestPrecommiterCalledWithDeliverState(t *testing.T) {
t.Parallel()
logger := log.NewTestLogger(t)
db := dbm.NewMemDB()
name := t.Name()
app := baseapp.NewBaseApp(name, logger, db, nil)
wasPrecommiterCalled := false
app.SetPrecommiter(func(ctx sdk.Context) {
require.Equal(t, false, ctx.IsCheckTx())
require.Equal(t, false, ctx.IsReCheckTx())
wasPrecommiterCalled = true
})
app.BeginBlock(abci.RequestBeginBlock{Header: cmtproto.Header{Height: 1}})
app.Commit()
require.Equal(t, true, wasPrecommiterCalled)
}
func TestABCI_Proposal_HappyPath(t *testing.T) {
anteKey := []byte("ante-key")
pool := mempool.NewSenderNonceMempool()

View File

@ -62,17 +62,19 @@ type BaseApp struct {
txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx
txEncoder sdk.TxEncoder // marshal sdk.Tx into []byte
mempool mempool.Mempool // application side mempool
anteHandler sdk.AnteHandler // ante handler for fee and auth
postHandler sdk.PostHandler // post handler, optional, e.g. for tips
initChainer sdk.InitChainer // initialize state with validators and state blob
beginBlocker sdk.BeginBlocker // logic to run before any txs
processProposal sdk.ProcessProposalHandler // the handler which runs on ABCI ProcessProposal
prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal
endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes
addrPeerFilter sdk.PeerFilter // filter peers by address and port
idPeerFilter sdk.PeerFilter // filter peers by node ID
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.
mempool mempool.Mempool // application side mempool
anteHandler sdk.AnteHandler // ante handler for fee and auth
postHandler sdk.PostHandler // post handler, optional, e.g. for tips
initChainer sdk.InitChainer // initialize state with validators and state blob
beginBlocker sdk.BeginBlocker // logic to run before any txs
processProposal sdk.ProcessProposalHandler // the handler which runs on ABCI ProcessProposal
prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal
endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes
prepareCheckStater sdk.PrepareCheckStater // logic to run during commit using the checkState
precommiter sdk.Precommiter // logic to run during commit using the deliverState
addrPeerFilter sdk.PeerFilter // filter peers by address and port
idPeerFilter sdk.PeerFilter // filter peers by node ID
fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed.
// manages snapshots, i.e. dumps of app state at certain intervals
snapshotManager *snapshots.Manager

View File

@ -388,6 +388,12 @@ func TestBaseAppOptionSeal(t *testing.T) {
require.Panics(t, func() {
suite.baseApp.SetEndBlocker(nil)
})
require.Panics(t, func() {
suite.baseApp.SetPrepareCheckStater(nil)
})
require.Panics(t, func() {
suite.baseApp.SetPrecommiter(nil)
})
require.Panics(t, func() {
suite.baseApp.SetAnteHandler(nil)
})

View File

@ -167,6 +167,22 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) {
app.endBlocker = endBlocker
}
func (app *BaseApp) SetPrepareCheckStater(prepareCheckStater sdk.PrepareCheckStater) {
if app.sealed {
panic("SetPrepareCheckStater() on sealed BaseApp")
}
app.prepareCheckStater = prepareCheckStater
}
func (app *BaseApp) SetPrecommiter(precommiter sdk.Precommiter) {
if app.sealed {
panic("SetPrecommiter() on sealed BaseApp")
}
app.precommiter = precommiter
}
func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) {
if app.sealed {
panic("SetAnteHandler() on sealed BaseApp")

View File

@ -36,6 +36,8 @@ The above interfaces are mostly embedding smaller interfaces (extension interfac
* [`HasConsensusVersion`](#hasconsensusversion): The extension interface for declaring a module consensus version.
* [`BeginBlockAppModule`](#beginblockappmodule): The extension interface that contains information about the `AppModule` and `BeginBlock`.
* [`EndBlockAppModule`](#endblockappmodule): The extension interface that contains information about the `AppModule` and `EndBlock`.
* [`PrecommitAppModule`](#precommitappmodule): The extension interface that contains information about the `AppModule` and `Precommit`.
* [`PrepareCheckStateAppModule`](#preparecheckstateappmodule): The extension interface that contains information about the `AppModule` and `PrepareCheckState`.
The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/00-app-anatomy.md#core-application-file).
@ -167,6 +169,18 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/types/module/module.go#L20
* `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the end of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the end of each block for this module.
### `PrecommitAppModule`
The `PrecommitAppModule` is an extension interface from `AppModule`. All modules that have a `Precommit` method implement this interface.
* `Precommit(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`deliverState`](../core/00-baseapp.md#state-updates) of the block to be committed. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
### `PrepareCheckStateAppModule`
The `PrepareCheckStateAppModule` is an extension interface from `AppModule`. All modules that have a `PrepareCheckState` method implement this interface.
* `PrepareCheckState(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`checkState`](../core/00-baseapp.md#state-updates) of the next block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
### Implementing the Application Module Interfaces
Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`).
@ -228,6 +242,8 @@ The module manager is used throughout the application whenever an action on a co
* `SetOrderExportGenesis(moduleNames ...string)`: Sets the order in which the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module will be called in case of an export. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function).
* `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function).
* `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the end of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function).
* `SetOrderPrecommiters(moduleNames ...string)`: Sets the order in which the `Precommit()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function).
* `SetOrderPrepareCheckStaters(moduleNames ...string)`: Sets the order in which the `PrepareCheckState()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function).
* `SetOrderMigrations(moduleNames ...string)`: Sets the order of migrations to be run. If not set then migrations will be run with an order defined in `DefaultMigrationsOrder`.
* `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./07-invariants.md) of module implementing the `HasInvariants` interface.
* `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers legacy [`Msg`](./02-messages-and-queries.md#messages) and [`querier`](./04-query-services.md#legacy-queriers) routes.
@ -237,6 +253,8 @@ The module manager is used throughout the application whenever an action on a co
* `ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export.
* `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of each modules implementing the `BeginBlockAppModule` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events.
* `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `EndBlockAppModule` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any).
* `Precommit(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately before the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `PrecommitAppModule` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`deliverState`](../core/00-baseapp.md#state-updates).
* `PrepareCheckState(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `PrepareCheckStateAppModule` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../core/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../core/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block.
Here's an example of a concrete integration within an `simapp`:

1
go.mod
View File

@ -162,6 +162,7 @@ require (
// Below are the long-lived replace of the Cosmos SDK
replace (
cosmossdk.io/api => ./api
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// dgrijalva/jwt-go is deprecated and doesn't receive security updates.

2
go.sum
View File

@ -35,8 +35,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cosmossdk.io/api v0.4.0 h1:x90DmdidP6EhzktAa/6/IofSHidDnPjahdlrUvyQZQw=
cosmossdk.io/api v0.4.0/go.mod h1:TWDzBhUBhI1LhSf2XSYpfIBf6D4mbLu/fvzvDfhcaYM=
cosmossdk.io/collections v0.1.0 h1:nzJGeiq32KnZroSrhB6rPifw4I85Cgmzw/YAmr4luv8=
cosmossdk.io/collections v0.1.0/go.mod h1:xbauc0YsbUF8qKMVeBZl0pFCunxBIhKN/WlxpZ3lBuo=
cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s=

View File

@ -42,6 +42,16 @@ message Module {
// If this is left empty, it uses the default migration order.
// https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.47.0-alpha2/types/module#DefaultMigrationsOrder
repeated string order_migrations = 7;
// precommiters specifies the module names of the precommiters
// to call in the order in which they should be called. If this is left empty
// no precommit function will be registered.
repeated string precommiters = 8;
// prepare_check_staters specifies the module names of the prepare_check_staters
// to call in the order in which they should be called. If this is left empty
// no preparecheckstate function will be registered.
repeated string prepare_check_staters = 9;
}
// StoreKeyConfig may be supplied to override the default module store key, which

View File

@ -100,6 +100,16 @@ func (a *App) Load(loadLatest bool) error {
a.SetEndBlocker(a.EndBlocker)
}
if len(a.config.Precommiters) != 0 {
a.ModuleManager.SetOrderPrecommiters(a.config.Precommiters...)
a.SetPrecommiter(a.Precommiter)
}
if len(a.config.PrepareCheckStaters) != 0 {
a.ModuleManager.SetOrderPrepareCheckStaters(a.config.PrepareCheckStaters...)
a.SetPrepareCheckStater(a.PrepareCheckStater)
}
if len(a.config.OrderMigrations) != 0 {
a.ModuleManager.SetOrderMigrations(a.config.OrderMigrations...)
}
@ -123,6 +133,16 @@ func (a *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) (abci.Respon
return a.ModuleManager.EndBlock(ctx, req)
}
// Precommiter application updates every commit
func (a *App) Precommiter(ctx sdk.Context) {
a.ModuleManager.Precommit(ctx)
}
// PrepareCheckStater application updates every commit
func (a *App) PrepareCheckStater(ctx sdk.Context) {
a.ModuleManager.PrepareCheckState(ctx)
}
// InitChainer initializes the chain.
func (a *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) (abci.ResponseInitChain, error) {
var genesisState map[string]json.RawMessage

View File

@ -8,9 +8,11 @@ import (
// Common metric key constants
const (
MetricKeyBeginBlocker = "begin_blocker"
MetricKeyEndBlocker = "end_blocker"
MetricLabelNameModule = "module"
MetricKeyBeginBlocker = "begin_blocker"
MetricKeyEndBlocker = "end_blocker"
MetricKeyPrepareCheckStater = "prepare_check_stater"
MetricKeyPrecommiter = "precommiter"
MetricLabelNameModule = "module"
)
// NewLabel creates a new instance of Label with name and value

View File

@ -193,6 +193,7 @@ require (
replace (
cosmossdk.io/api => ../api
// TODO tag all extracted modules after SDK refactor
cosmossdk.io/api => ../api
cosmossdk.io/store => ../store
cosmossdk.io/x/evidence => ../x/evidence
cosmossdk.io/x/feegrant => ../x/feegrant

View File

@ -881,6 +881,232 @@ func (mr *MockEndBlockAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 inter
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockEndBlockAppModule)(nil).RegisterLegacyAminoCodec), arg0)
}
// MockPrepareCheckStateAppModule is a mock of PrepareCheckStateAppModule interface.
type MockPrepareCheckStateAppModule struct {
ctrl *gomock.Controller
recorder *MockPrepareCheckStateAppModuleMockRecorder
}
// MockPrepareCheckStateAppModuleMockRecorder is the mock recorder for MockPrepareCheckStateAppModule.
type MockPrepareCheckStateAppModuleMockRecorder struct {
mock *MockPrepareCheckStateAppModule
}
// NewMockPrepareCheckStateAppModule creates a new mock instance.
func NewMockPrepareCheckStateAppModule(ctrl *gomock.Controller) *MockPrepareCheckStateAppModule {
mock := &MockPrepareCheckStateAppModule{ctrl: ctrl}
mock.recorder = &MockPrepareCheckStateAppModuleMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockPrepareCheckStateAppModule) EXPECT() *MockPrepareCheckStateAppModuleMockRecorder {
return m.recorder
}
// GetQueryCmd mocks base method.
func (m *MockPrepareCheckStateAppModule) GetQueryCmd() *cobra.Command {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetQueryCmd")
ret0, _ := ret[0].(*cobra.Command)
return ret0
}
// GetQueryCmd indicates an expected call of GetQueryCmd.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) GetQueryCmd() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).GetQueryCmd))
}
// GetTxCmd mocks base method.
func (m *MockPrepareCheckStateAppModule) GetTxCmd() *cobra.Command {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTxCmd")
ret0, _ := ret[0].(*cobra.Command)
return ret0
}
// GetTxCmd indicates an expected call of GetTxCmd.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) GetTxCmd() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).GetTxCmd))
}
// Name mocks base method.
func (m *MockPrepareCheckStateAppModule) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).Name))
}
// PrepareCheckState mocks base method.
func (m *MockPrepareCheckStateAppModule) PrepareCheckState(arg0 types1.Context) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "PrepareCheckState", arg0)
}
// PrepareCheckState indicates an expected call of PrepareCheckState.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) PrepareCheckState(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareCheckState", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).PrepareCheckState), arg0)
}
// RegisterGRPCGatewayRoutes mocks base method.
func (m *MockPrepareCheckStateAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterGRPCGatewayRoutes", arg0, arg1)
}
// RegisterGRPCGatewayRoutes indicates an expected call of RegisterGRPCGatewayRoutes.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1)
}
// RegisterInterfaces mocks base method.
func (m *MockPrepareCheckStateAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterInterfaces", arg0)
}
// RegisterInterfaces indicates an expected call of RegisterInterfaces.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterInterfaces), arg0)
}
// RegisterLegacyAminoCodec mocks base method.
func (m *MockPrepareCheckStateAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterLegacyAminoCodec", arg0)
}
// RegisterLegacyAminoCodec indicates an expected call of RegisterLegacyAminoCodec.
func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterLegacyAminoCodec), arg0)
}
// MockPrecommitAppModule is a mock of PrecommitAppModule interface.
type MockPrecommitAppModule struct {
ctrl *gomock.Controller
recorder *MockPrecommitAppModuleMockRecorder
}
// MockPrecommitAppModuleMockRecorder is the mock recorder for MockPrecommitAppModule.
type MockPrecommitAppModuleMockRecorder struct {
mock *MockPrecommitAppModule
}
// NewMockPrecommitAppModule creates a new mock instance.
func NewMockPrecommitAppModule(ctrl *gomock.Controller) *MockPrecommitAppModule {
mock := &MockPrecommitAppModule{ctrl: ctrl}
mock.recorder = &MockPrecommitAppModuleMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockPrecommitAppModule) EXPECT() *MockPrecommitAppModuleMockRecorder {
return m.recorder
}
// GetQueryCmd mocks base method.
func (m *MockPrecommitAppModule) GetQueryCmd() *cobra.Command {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetQueryCmd")
ret0, _ := ret[0].(*cobra.Command)
return ret0
}
// GetQueryCmd indicates an expected call of GetQueryCmd.
func (mr *MockPrecommitAppModuleMockRecorder) GetQueryCmd() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockPrecommitAppModule)(nil).GetQueryCmd))
}
// GetTxCmd mocks base method.
func (m *MockPrecommitAppModule) GetTxCmd() *cobra.Command {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTxCmd")
ret0, _ := ret[0].(*cobra.Command)
return ret0
}
// GetTxCmd indicates an expected call of GetTxCmd.
func (mr *MockPrecommitAppModuleMockRecorder) GetTxCmd() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockPrecommitAppModule)(nil).GetTxCmd))
}
// Name mocks base method.
func (m *MockPrecommitAppModule) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
return ret0
}
// Name indicates an expected call of Name.
func (mr *MockPrecommitAppModuleMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockPrecommitAppModule)(nil).Name))
}
// Precommit mocks base method.
func (m *MockPrecommitAppModule) Precommit(arg0 types1.Context) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Precommit", arg0)
}
// Precommit indicates an expected call of Precommit.
func (mr *MockPrecommitAppModuleMockRecorder) Precommit(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Precommit", reflect.TypeOf((*MockPrecommitAppModule)(nil).Precommit), arg0)
}
// RegisterGRPCGatewayRoutes mocks base method.
func (m *MockPrecommitAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterGRPCGatewayRoutes", arg0, arg1)
}
// RegisterGRPCGatewayRoutes indicates an expected call of RegisterGRPCGatewayRoutes.
func (mr *MockPrecommitAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1)
}
// RegisterInterfaces mocks base method.
func (m *MockPrecommitAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterInterfaces", arg0)
}
// RegisterInterfaces indicates an expected call of RegisterInterfaces.
func (mr *MockPrecommitAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterInterfaces), arg0)
}
// RegisterLegacyAminoCodec mocks base method.
func (m *MockPrecommitAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "RegisterLegacyAminoCodec", arg0)
}
// RegisterLegacyAminoCodec indicates an expected call of RegisterLegacyAminoCodec.
func (mr *MockPrecommitAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterLegacyAminoCodec), arg0)
}
// MockHasABCIEndblock is a mock of HasABCIEndblock interface.
type MockHasABCIEndblock struct {
ctrl *gomock.Controller

View File

@ -19,6 +19,13 @@ type BeginBlocker func(ctx Context, req abci.RequestBeginBlock) (abci.ResponseBe
// e.g. BFT timestamps rather than block height for any periodic EndBlock logic
type EndBlocker func(ctx Context, req abci.RequestEndBlock) (abci.ResponseEndBlock, error)
// PrepareCheckStater runs code during commit after the block has been committed, and the `checkState`
// has been branched for the new block.
type PrepareCheckStater func(ctx Context)
// Precommiter runs code during commit immediately before the `deliverState` is written to the `rootMultiStore`.
type Precommiter func(ctx Context)
// PeerFilter responds to p2p filtering queries from Tendermint
type PeerFilter func(info string) abci.ResponseQuery

View File

@ -213,6 +213,19 @@ type EndBlockAppModule interface {
EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
}
// PrepareCheckStateAppModule is an extension interface that contains information about the AppModule
// and PrepareCheckState.
type PrepareCheckStateAppModule interface {
AppModule
PrepareCheckState(sdk.Context)
}
// PreommitAppModule is an extension interface that contains information about the AppModule and Precommit.
type PrecommitAppModule interface {
AppModule
Precommit(sdk.Context)
}
type HasABCIEndblock interface {
AppModule
EndBlock(context.Context) ([]abci.ValidatorUpdate, error)
@ -259,12 +272,14 @@ func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []ab
// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
Modules map[string]interface{} // interface{} is used now to support the legacy AppModule as well as new core appmodule.AppModule.
OrderInitGenesis []string
OrderExportGenesis []string
OrderBeginBlockers []string
OrderEndBlockers []string
OrderMigrations []string
Modules map[string]interface{} // interface{} is used now to support the legacy AppModule as well as new core appmodule.AppModule.
OrderInitGenesis []string
OrderExportGenesis []string
OrderBeginBlockers []string
OrderEndBlockers []string
OrderPrepareCheckStaters []string
OrderPrecommiters []string
OrderMigrations []string
}
// NewManager creates a new Manager object.
@ -277,11 +292,13 @@ func NewManager(modules ...AppModule) *Manager {
}
return &Manager{
Modules: moduleMap,
OrderInitGenesis: modulesStr,
OrderExportGenesis: modulesStr,
OrderBeginBlockers: modulesStr,
OrderEndBlockers: modulesStr,
Modules: moduleMap,
OrderInitGenesis: modulesStr,
OrderExportGenesis: modulesStr,
OrderBeginBlockers: modulesStr,
OrderPrepareCheckStaters: modulesStr,
OrderPrecommiters: modulesStr,
OrderEndBlockers: modulesStr,
}
}
@ -299,11 +316,13 @@ func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
sort.Strings(modulesStr)
return &Manager{
Modules: simpleModuleMap,
OrderInitGenesis: modulesStr,
OrderExportGenesis: modulesStr,
OrderBeginBlockers: modulesStr,
OrderEndBlockers: modulesStr,
Modules: simpleModuleMap,
OrderInitGenesis: modulesStr,
OrderExportGenesis: modulesStr,
OrderBeginBlockers: modulesStr,
OrderEndBlockers: modulesStr,
OrderPrecommiters: modulesStr,
OrderPrepareCheckStaters: modulesStr,
}
}
@ -357,6 +376,28 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) {
m.OrderEndBlockers = moduleNames
}
// SetOrderPrepareCheckStaters sets the order of set prepare-check-stater calls
func (m *Manager) SetOrderPrepareCheckStaters(moduleNames ...string) {
m.assertNoForgottenModules("SetOrderPrepareCheckStaters", moduleNames,
func(moduleName string) bool {
module := m.Modules[moduleName]
_, hasPrepareCheckState := module.(PrepareCheckStateAppModule)
return !hasPrepareCheckState
})
m.OrderPrepareCheckStaters = moduleNames
}
// SetOrderPrecommiters sets the order of set precommiter calls
func (m *Manager) SetOrderPrecommiters(moduleNames ...string) {
m.assertNoForgottenModules("SetOrderPrecommiters", moduleNames,
func(moduleName string) bool {
module := m.Modules[moduleName]
_, hasPrecommit := module.(PrecommitAppModule)
return !hasPrecommit
})
m.OrderPrecommiters = moduleNames
}
// SetOrderMigrations sets the order of migrations to be run. If not set
// then migrations will be run with an order defined in `DefaultMigrationsOrder`.
func (m *Manager) SetOrderMigrations(moduleNames ...string) {
@ -728,6 +769,28 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (abci.Resp
}, nil
}
// Precommit performs precommit functionality for all modules.
func (m *Manager) Precommit(ctx sdk.Context) {
for _, moduleName := range m.OrderPrecommiters {
module, ok := m.Modules[moduleName].(PrecommitAppModule)
if !ok {
continue
}
module.Precommit(ctx)
}
}
// PrepareCheckState performs functionality for preparing the check state for all modules.
func (m *Manager) PrepareCheckState(ctx sdk.Context) {
for _, moduleName := range m.OrderPrepareCheckStaters {
module, ok := m.Modules[moduleName].(PrepareCheckStateAppModule)
if !ok {
continue
}
module.PrepareCheckState(ctx)
}
}
// GetVersionMap gets consensus version from all modules
func (m *Manager) GetVersionMap() VersionMap {
vermap := make(VersionMap)

View File

@ -100,6 +100,60 @@ func TestGenesisOnlyAppModule(t *testing.T) {
goam.RegisterInvariants(mockInvariantRegistry)
}
func TestAssertNoForgottenModules(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
mockAppModule1 := mock.NewMockEndBlockAppModule(mockCtrl)
mockAppModule2 := mock.NewMockBeginBlockAppModule(mockCtrl)
mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl)
mockAppModule4 := mock.NewMockPrecommitAppModule(mockCtrl)
mockAppModule5 := mock.NewMockPrepareCheckStateAppModule(mockCtrl)
mockAppModule1.EXPECT().Name().Times(2).Return("module1")
mockAppModule2.EXPECT().Name().Times(2).Return("module2")
mockAppModule4.EXPECT().Name().Times(2).Return("module4")
mockAppModule5.EXPECT().Name().Times(2).Return("module5")
mm := module.NewManager(
mockAppModule1,
mockAppModule2,
module.CoreAppModuleBasicAdaptor("module3", mockAppModule3),
mockAppModule4,
mockAppModule5,
)
require.NotNil(t, mm)
require.Equal(t, 5, len(mm.Modules))
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderInitGenesis)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderInitGenesis, missing: [module3]", func() {
mm.SetOrderInitGenesis("module2", "module1")
})
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderExportGenesis)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderExportGenesis, missing: [module3]", func() {
mm.SetOrderExportGenesis("module2", "module1")
})
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderBeginBlockers)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderBeginBlockers, missing: [module2]", func() {
mm.SetOrderBeginBlockers("module1", "module3")
})
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderEndBlockers)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderEndBlockers, missing: [module1]", func() {
mm.SetOrderEndBlockers("module2", "module3")
})
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderPrecommiters)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderPrecommiters, missing: [module4]", func() {
mm.SetOrderPrecommiters("module2", "module1")
})
require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderPrepareCheckStaters)
require.PanicsWithValue(t, "all modules must be defined when setting SetOrderPrepareCheckStaters, missing: [module5]", func() {
mm.SetOrderPrepareCheckStaters("module2", "module1")
})
}
func TestManagerOrderSetters(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
@ -128,6 +182,14 @@ func TestManagerOrderSetters(t *testing.T) {
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers)
mm.SetOrderEndBlockers("module2", "module1", "module3")
require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers)
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters)
mm.SetOrderPrepareCheckStaters("module3", "module2", "module1")
require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters)
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters)
mm.SetOrderPrecommiters("module3", "module2", "module1")
require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters)
}
func TestManager_RegisterInvariants(t *testing.T) {
@ -319,6 +381,40 @@ func TestManager_EndBlock(t *testing.T) {
require.Error(t, err)
}
func TestManager_PrepareCheckState(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
mockAppModule1 := mock.NewMockPrepareCheckStateAppModule(mockCtrl)
mockAppModule2 := mock.NewMockPrepareCheckStateAppModule(mockCtrl)
mockAppModule1.EXPECT().Name().Times(2).Return("module1")
mockAppModule2.EXPECT().Name().Times(2).Return("module2")
mm := module.NewManager(mockAppModule1, mockAppModule2)
require.NotNil(t, mm)
require.Equal(t, 2, len(mm.Modules))
mockAppModule1.EXPECT().PrepareCheckState(gomock.Any()).Times(1)
mockAppModule2.EXPECT().PrepareCheckState(gomock.Any()).Times(1)
mm.PrepareCheckState(sdk.Context{})
}
func TestManager_Precommit(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
mockAppModule1 := mock.NewMockPrecommitAppModule(mockCtrl)
mockAppModule2 := mock.NewMockPrecommitAppModule(mockCtrl)
mockAppModule1.EXPECT().Name().Times(2).Return("module1")
mockAppModule2.EXPECT().Name().Times(2).Return("module2")
mm := module.NewManager(mockAppModule1, mockAppModule2)
require.NotNil(t, mm)
require.Equal(t, 2, len(mm.Modules))
mockAppModule1.EXPECT().Precommit(gomock.Any()).Times(1)
mockAppModule2.EXPECT().Precommit(gomock.Any()).Times(1)
mm.Precommit(sdk.Context{})
}
// Core API exclusive tests
func TestCoreAPIManager(t *testing.T) {
mockCtrl := gomock.NewController(t)
@ -431,6 +527,14 @@ func TestCoreAPIManagerOrderSetters(t *testing.T) {
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers)
mm.SetOrderEndBlockers("module2", "module1", "module3")
require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers)
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters)
mm.SetOrderPrepareCheckStaters("module3", "module2", "module1")
require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters)
require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters)
mm.SetOrderPrecommiters("module3", "module2", "module1")
require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters)
}
func TestCoreAPIManager_BeginBlock(t *testing.T) {