-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(runtime/v2): remove dependency on sdk #20389
Conversation
WalkthroughWalkthroughThe update brings significant refactoring and modularization to the codebase. It includes adding new interfaces and methods for genesis operations, adjusting codec interfaces, and restructuring application modules for improved modularity. Changes involve updating import paths, modifying function signatures, and enhancing the dependency injection framework. Changes
Possibly related issues
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
core/appmodule/v2/module.go
Outdated
@@ -104,3 +110,11 @@ type ValidatorUpdate struct { | |||
type HasRegisterInterfaces interface { | |||
RegisterInterfaces(registry.InterfaceRegistrar) | |||
} | |||
|
|||
type HasName interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this isn't a v2 thing only, so I'd put that on v1 and alias it here.
core/appmodule/v2/module.go
Outdated
Name() string | ||
} | ||
|
||
type HasAminoCodec interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
core/appmodule/v2/module.go
Outdated
@@ -47,6 +49,10 @@ type HasEndBlocker interface { | |||
EndBlock(context.Context) error | |||
} | |||
|
|||
type HasABCIEndBlock interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we want that to be a v2 thing that third-party modules can implement?
I would just do the interface check maybe in runtime/v2 for backward compatibility but not add it to core
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds reasonable to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Out of diff range and nitpick comments (7)
core/appmodule/genesis.go (1)
33-39
: Consider adding comments to the methods in theHasGenesisBasics
interface to improve code readability and maintainability.Adding comments to interface methods helps other developers understand the purpose and usage of each method.
core/appmodule/module.go (2)
69-72
: Consider adding comments to theName
method in theHasName
interface to improve code readability and maintainability.Adding comments to interface methods helps other developers understand the purpose and usage of each method.
74-78
: Consider adding comments to theRegisterLegacyAminoCodec
method in theHasAminoCodec
interface to improve code readability and maintainability.Adding comments to interface methods helps other developers understand the purpose and usage of each method.
codec/depinject.go (1)
55-64
: Consider adding comments to the fields in theAddressCodecInputs
struct to improve code readability and maintainability.Adding comments to struct fields helps other developers understand the purpose and usage of each field.
x/genutil/module.go (1)
98-104
: Consider adding comments to theDecodeGenesisJSON
method to improve code readability and maintainability.Adding comments to methods helps other developers understand the purpose and usage of each method.
runtime/v2/app.go (1)
64-67
: Consider adding comments to the fields in theApp
struct to improve code readability and maintainability.Adding comments to struct fields helps other developers understand the purpose and usage of each field.
runtime/v2/builder.go (1)
181-187
: Consider adding comments to theAppBuilderWithPostTxExec
method to improve code readability and maintainability.Adding comments to methods helps other developers understand the purpose and usage of each method.
Review Details
Configuration used: .coderabbit.yml
Review profile: CHILL
Files ignored due to path filters (3)
runtime/v2/go.mod
is excluded by!**/*.mod
runtime/v2/go.sum
is excluded by!**/*.sum
x/accounts/defaults/lockup/go.mod
is excluded by!**/*.mod
Files selected for processing (16)
- codec/depinject.go (2 hunks)
- core/appmodule/genesis.go (2 hunks)
- core/appmodule/module.go (2 hunks)
- core/appmodule/v2/genesis.go (1 hunks)
- crypto/codec/proto.go (2 hunks)
- crypto/keys/secp256r1/doc.go (2 hunks)
- runtime/module.go (5 hunks)
- runtime/v2/app.go (2 hunks)
- runtime/v2/builder.go (3 hunks)
- runtime/v2/manager.go (17 hunks)
- runtime/v2/module.go (6 hunks)
- runtime/v2/types.go (1 hunks)
- std/codec.go (2 hunks)
- types/codec.go (2 hunks)
- types/tx/types.go (2 hunks)
- x/genutil/module.go (3 hunks)
Additional Context Used
Path-based Instructions (16)
types/codec.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.std/codec.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.core/appmodule/v2/genesis.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.crypto/keys/secp256r1/doc.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.crypto/codec/proto.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/v2/types.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.core/appmodule/genesis.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.core/appmodule/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.codec/depinject.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.x/genutil/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/v2/app.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/v2/builder.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.types/tx/types.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/v2/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/v2/manager.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.
Additional comments not posted (26)
types/codec.go (1)
21-23
: Update to useregistry.InterfaceRegistrar
looks good.std/codec.go (1)
Line range hint
21-27
: Update to useregistry.InterfaceRegistrar
looks good.core/appmodule/v2/genesis.go (3)
18-18
: TheHasGenesis
interface is well-defined for handling genesis operations.
20-22
: TheHasABCIGenesis
interface is well-defined for handling ABCI genesis operations.
24-26
: TheGenesisDecoder
interface is well-defined for decoding genesis JSON data.crypto/keys/secp256r1/doc.go (1)
34-36
: Update to useregistry.InterfaceRegistrar
looks good.crypto/codec/proto.go (1)
Line range hint
14-26
: Update to useregistry.InterfaceRegistrar
looks good.runtime/v2/types.go (2)
24-47
: ThevalidateProtoAnnotations
function is well-implemented for validating proto annotations.
51-63
: ThevalidateMsgServiceAnnotations
function is well-implemented for validating thecosmos.msg.v1.service
proto annotation.runtime/v2/builder.go (1)
41-52
: Ensure that all modules implementingappmodule.HasName
andappmodulev2.HasRegisterInterfaces
are correctly registered.Verify that all modules implementing these interfaces are correctly registered to avoid runtime errors.
types/tx/types.go (2)
8-8
: Import statement forregistry
added.
Line range hint
230-238
: TheRegisterInterfaces
function has been updated to useregistry.InterfaceRegistrar
.runtime/v2/module.go (3)
Line range hint
107-141
: TheProvideAppBuilder
function has been updated to useregistry.InterfaceRegistrar
andlegacy.Amino
.
147-154
: TheAppInputs
struct has been updated to useregistry.InterfaceRegistrar
andlegacy.Amino
.
163-165
: TheSetupAppBuilder
function has been updated to register interfaces and legacy amino codec using the newregistry
andlegacy
packages.runtime/module.go (1)
97-97
: TheProvideApp
function has been updated to includecodec.ProvideAddressCodec
.runtime/v2/manager.go (10)
21-21
: New imports added.The new imports for
legacy
,registry
, andtransaction
are appropriate and align with the changes in the code.
63-63
: Ensure thedefaultMigrationsOrder
function is correctly implemented.Verify that the
defaultMigrationsOrder
function correctly orders the modules, especially handling the "auth" module as specified.Verification successful
The
defaultMigrationsOrder
function correctly handles the "auth" module by ensuring it is appended at the end of the sorted list of modules. The implementation is as follows:
- It checks for the presence of the "auth" module.
- It sorts the other modules.
- It appends "auth" at the end if it exists.
This confirms that the function is correctly implemented.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the implementation of the `defaultMigrationsOrder` function. # Test: Search for the function implementation. Expect: Correct handling of the "auth" module. rg --type go 'func defaultMigrationsOrder'Length of output: 123
Script:
#!/bin/bash # Extract the implementation of the `defaultMigrationsOrder` function from `runtime/v2/manager.go` ast-grep --lang go --pattern $'func defaultMigrationsOrder(modules []string) []string { $$$ }' runtime/v2/manager.goLength of output: 891
86-90
: Ensure proper registration of legacy Amino codecs.The
RegisterLegacyAminoCodec
function correctly registers the legacy Amino codecs for all modules implementing theHasAminoCodec
interface.
Line range hint
107-115
: Ensure proper handling of default genesis data.The
DefaultGenesis
function correctly handles the default genesis data for all modules, including those implementing theHasGenesisBasics
andHasGenesis
interfaces.
Line range hint
122-130
: Ensure proper validation of genesis data.The
ValidateGenesis
function correctly validates the genesis data for all modules, including those implementing theHasGenesisBasics
andHasGenesis
interfaces.
Line range hint
137-193
: Ensure proper initialization of genesis data from JSON.The
InitGenesisJSON
function correctly initializes the genesis data from JSON for all modules, including handling special cases like the "genutil" module and modules implementing theGenesisDecoder
,HasGenesis
, andHasABCIGenesis
interfaces.
Line range hint
199-234
: Ensure proper export of genesis data for modules.The
ExportGenesisForModules
function correctly exports the genesis data for the specified modules, including handling modules implementing theHasGenesis
andHasABCIGenesis
interfaces.
Line range hint
288-318
: Ensure proper handling of end-block logic.The
EndBlock
function correctly handles the end-block logic for all modules, including those implementing theHasEndBlocker
andhasABCIEndBlock
interfaces.
Line range hint
403-413
: Ensure proper handling of module migrations.The
RunMigrations
function correctly handles the migrations for all modules, including those implementing theHasConsensusVersion
andHasABCIGenesis
interfaces.
666-685
: Ensure proper ordering of module migrations.The
defaultMigrationsOrder
function correctly orders the modules for migrations, ensuring the "auth" module runs last as specified.
// ProvideAddressCodec provides an address.Codec to the container for any | ||
// modules that want to do address string <> bytes conversion. | ||
func ProvideAddressCodec(in AddressCodecInputs) (address.Codec, address.ValidatorAddressCodec, address.ConsensusAddressCodec) { | ||
if in.AddressCodecFactory != nil && in.ValidatorAddressCodecFactory != nil && in.ConsensusAddressCodecFactory != nil { | ||
return in.AddressCodecFactory(), in.ValidatorAddressCodecFactory(), in.ConsensusAddressCodecFactory() | ||
} | ||
|
||
if in.AuthConfig == nil || in.AuthConfig.Bech32Prefix == "" { | ||
panic("auth config bech32 prefix cannot be empty if no custom address codec is provided") | ||
} | ||
|
||
if in.StakingConfig == nil { | ||
in.StakingConfig = &stakingmodulev1.Module{} | ||
} | ||
|
||
if in.StakingConfig.Bech32PrefixValidator == "" { | ||
in.StakingConfig.Bech32PrefixValidator = fmt.Sprintf("%svaloper", in.AuthConfig.Bech32Prefix) | ||
} | ||
|
||
if in.StakingConfig.Bech32PrefixConsensus == "" { | ||
in.StakingConfig.Bech32PrefixConsensus = fmt.Sprintf("%svalcons", in.AuthConfig.Bech32Prefix) | ||
} | ||
|
||
return addresscodec.NewBech32Codec(in.AuthConfig.Bech32Prefix), | ||
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixValidator), | ||
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixConsensus) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure proper error handling in the ProvideAddressCodec
function to avoid potential runtime panics.
- panic("auth config bech32 prefix cannot be empty if no custom address codec is provided")
+ return nil, nil, fmt.Errorf("auth config bech32 prefix cannot be empty if no custom address codec is provided")
Using panic
for error handling is not recommended as it can cause the program to terminate unexpectedly. Returning an error allows the caller to handle it gracefully.
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
// ProvideAddressCodec provides an address.Codec to the container for any | |
// modules that want to do address string <> bytes conversion. | |
func ProvideAddressCodec(in AddressCodecInputs) (address.Codec, address.ValidatorAddressCodec, address.ConsensusAddressCodec) { | |
if in.AddressCodecFactory != nil && in.ValidatorAddressCodecFactory != nil && in.ConsensusAddressCodecFactory != nil { | |
return in.AddressCodecFactory(), in.ValidatorAddressCodecFactory(), in.ConsensusAddressCodecFactory() | |
} | |
if in.AuthConfig == nil || in.AuthConfig.Bech32Prefix == "" { | |
panic("auth config bech32 prefix cannot be empty if no custom address codec is provided") | |
} | |
if in.StakingConfig == nil { | |
in.StakingConfig = &stakingmodulev1.Module{} | |
} | |
if in.StakingConfig.Bech32PrefixValidator == "" { | |
in.StakingConfig.Bech32PrefixValidator = fmt.Sprintf("%svaloper", in.AuthConfig.Bech32Prefix) | |
} | |
if in.StakingConfig.Bech32PrefixConsensus == "" { | |
in.StakingConfig.Bech32PrefixConsensus = fmt.Sprintf("%svalcons", in.AuthConfig.Bech32Prefix) | |
} | |
return addresscodec.NewBech32Codec(in.AuthConfig.Bech32Prefix), | |
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixValidator), | |
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixConsensus) | |
} | |
// ProvideAddressCodec provides an address.Codec to the container for any | |
// modules that want to do address string <> bytes conversion. | |
func ProvideAddressCodec(in AddressCodecInputs) (address.Codec, address.ValidatorAddressCodec, address.ConsensusAddressCodec, error) { | |
if in.AddressCodecFactory != nil && in.ValidatorAddressCodecFactory != nil && in.ConsensusAddressCodecFactory != nil { | |
return in.AddressCodecFactory(), in.ValidatorAddressCodecFactory(), in.ConsensusAddressCodecFactory(), nil | |
} | |
if in.AuthConfig == nil || in.AuthConfig.Bech32Prefix == "" { | |
return nil, nil, nil, fmt.Errorf("auth config bech32 prefix cannot be empty if no custom address codec is provided") | |
} | |
if in.StakingConfig == nil { | |
in.StakingConfig = &stakingmodulev1.Module{} | |
} | |
if in.StakingConfig.Bech32PrefixValidator == "" { | |
in.StakingConfig.Bech32PrefixValidator = fmt.Sprintf("%svaloper", in.AuthConfig.Bech32Prefix) | |
} | |
if in.StakingConfig.Bech32PrefixConsensus == "" { | |
in.StakingConfig.Bech32PrefixConsensus = fmt.Sprintf("%svalcons", in.AuthConfig.Bech32Prefix) | |
} | |
return addresscodec.NewBech32Codec(in.AuthConfig.Bech32Prefix), | |
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixValidator), | |
addresscodec.NewBech32Codec(in.StakingConfig.Bech32PrefixConsensus), | |
nil | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review Details
Configuration used: .coderabbit.yml
Review profile: CHILL
Files selected for processing (1)
- runtime/v2/manager.go (17 hunks)
Additional Context Used
Path-based Instructions (1)
runtime/v2/manager.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.
Additional comments not posted (7)
runtime/v2/manager.go (7)
21-21
: New imports added forlegacy
,registry
,transaction
,log
, andstf
are appropriate and necessary for the refactored code.
63-63
: SettingOrderMigrations
to a default value if not provided is a good practice to avoid potential issues during migrations.
86-88
: TheRegisterLegacyAminoCodec
function correctly iterates over the modules and registers the legacy amino codec if the module implements theHasAminoCodec
interface.
107-107
: TheDefaultGenesis
function now checks for theHasGenesisBasics
interface, ensuring compatibility with modules implementing this interface.
122-122
: TheValidateGenesis
function now checks for theHasGenesisBasics
interface, ensuring compatibility with modules implementing this interface.
Line range hint
137-193
: TheInitGenesisJSON
function includes additional checks and handles different module types (HasGenesisAuto
,GenesisDecoder
,HasGenesis
,HasABCIGenesis
). This ensures proper initialization of genesis data for various module types.
199-202
: TheExportGenesisForModules
function includes a check to verify that the modules exist in the app before exporting genesis data, preventing potential panics during the export process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
@@ -64,3 +65,14 @@ type HasPrecommit interface { | |||
appmodule.AppModule | |||
Precommit(context.Context) error | |||
} | |||
|
|||
// HasName is an extension interface that must return the appmodule.AppModule's Name. | |||
type HasName interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add an alias for this in appmodulev2? I remember it was considered as a legacy thing as we can get the module name as a depinject.ModuleKey, but the module manager doesn't really cares and is still very dependent on Name().
Cc @aaronc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should make in a follow up the runtime/v2 module manager a bit less dependent on this to fulfill this abstraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it, created #20408
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left one question otherwise LGTM
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1" | ||
stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we fine with this for now? I guess there isn't a choice in the current design? maybe we open an issue to close before we release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the modules config. When depinject supports gogo proto, we should make sure it is able to provide both types (if existing), so that the provider can resolve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cringed but also don't have an alternative at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review Details
Configuration used: .coderabbit.yml
Review profile: CHILL
Files selected for processing (3)
- runtime/module.go (5 hunks)
- runtime/v2/module.go (6 hunks)
- types/tx/types.go (2 hunks)
Files skipped from review as they are similar to previous changes (1)
- types/tx/types.go
Additional Context Used
Path-based Instructions (2)
runtime/v2/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.runtime/module.go (1)
Pattern
**/*.go
: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.
Additional comments not posted (9)
runtime/v2/module.go (8)
20-21
: Necessary imports forlegacy
andregistry
.
107-110
: Function signature includes new parametersinterfaceRegistrar
andamino
.
121-123
: Proto annotations validation ensures correctness at startup.
141-141
: Return values are consistent with the function's purpose.
147-154
:AppInputs
struct includes new fieldsInterfaceRegistrar
andLegacyAmino
.
163-163
: Function body initializes the app with the provided inputs.
165-165
: TODO comment suggests a potential improvement for store key registration.
179-179
: Function initializes a new module manager with the provided logger, config, and modules.runtime/module.go (1)
97-97
: Addition ofProvideAddressCodec
toappconfig.Provide
is necessary for the new address codec functionality.
* main: (95 commits) fix(x/accounts): check for overflows in multisig weights and votes (#20384) docs(x/account/auth): Improve error handling and comments in fee.go (#20426) docs: fix some markdown syntax (#20432) revert: bank change module to account change (#20427) fix: nil pointer panic when store don't exists in historical version (#20425) fix(store/v2): Remove should not error on miss (#20423) chore: upstream more changes from v2 (#20387) docs(x/auth/ante): fixed typo in TxWithTimeoutHeight interface name (#20418) fix: avoid default sendenabled for module accounts (#20419) docs(x/auth): fixed typo in command example for multisign transaction (#20417) build(deps): Bump bufbuild/buf-setup-action from 1.31.0 to 1.32.0 (#20413) build(deps): Bump github.com/hashicorp/go-plugin from 1.6.0 to 1.6.1 in /store (#20414) feat(x/accounts): Add schema caching feature and corresponding test case (#20055) refactor(runtime/v2): remove dependency on sdk (#20389) refactor!: turn MsgsV2 into ReflectMessages to make it less confusing (#19839) docs: Enhanced the ParsePagination method documentation (#20385) refactor(runtime,core): split router service (#20401) chore: fix spelling errors (#20400) docs: Documented error handling in OfferSnapshot method (#20380) build(deps): Bump google.golang.org/grpc from 1.63.2 to 1.64.0 (#20390) ...
Description
A follow up to #20369, removes the dependency on the SDK from runtime/v2.
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
in the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
Summary by CodeRabbit
Refactor
Chores