-
Notifications
You must be signed in to change notification settings - Fork 277
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
feat: improve multisig utility and usability #5027
base: main
Are you sure you want to change the base?
Conversation
Genesis needs to be updated |
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 think this change is great improvement to usability of multisigs.
Updates:
Notes:
|
Updates:
Notes:
|
8d4f2f2
to
84c1ec8
Compare
BREAKING CHANGES: - (api-changes) `CanRegisterAnyTrigger` `CanUnregisterAnyTrigger` permission - (config-changes) `defaults/genesis.json` assumes `wasm_triggers[*].action.executable` is prebuilt under `wasm_samples/target/prebuilt/` Major commits: - feat: support multisig recursion - feat: introduce multisig quorum and weights - feat: add multisig subcommand to client CLI - feat: introduce multisig transaction time-to-live - feat: predefine multisig world-level trigger in genesis - feat: allow accounts in domain to register multisig accounts Signed-off-by: Shunkichi Sato <[email protected]>
@@ -30,6 +30,7 @@ path = "src/main.rs" | |||
iroha = { workspace = true } | |||
iroha_primitives = { workspace = true } | |||
iroha_config_base = { workspace = true } | |||
executor_custom_data_model = { version = "=2.0.0-rc.1.0", path = "../../wasm_samples/executor_custom_data_model" } |
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 doesn't make sense that this is a dependency of CLI because executor_custom_data_model
is intended to only be used in tests
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.
you should create a separate crate for MST data model
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 is a temporary workaround. I'm planning to move those *Args
for ExecuteTrigger
to somewhere under the regular iroha_data_model
when iroha
introduces custom instructions, then CLI will only depend on iroha
.
Or should we pack everything relevant to multisig to one crate for more clear modularity? Related to this, it might be better to move wasm_samples/multisig_*
to somewhere as they are not just samples
pub quorum: u16, | ||
/// Time-to-live of multisig transactions made by the multisig account | ||
#[arg(short, long)] | ||
pub transaction_ttl_secs: Option<u32>, |
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.
pub transaction_ttl_secs: Option<u32>, | |
pub transaction_ttl: Duration, |
why is it optional? and why not use Duration
?
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.
Yeah, instead of being optional, its default value can be explicitly specified in the arg
attribute.
u32
because it needs to be parsed from stdin
let register_multisig_account = | ||
iroha::data_model::isi::ExecuteTrigger::new(registry_id).with_args(&args); |
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.
so the trigger has to already exist before executing this. Who should register it? Shouldn't it first be registered here?
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.
The domains initializer should register the accounts registry on the domain creation. See diagram in review notes
let propose_multisig_transaction = | ||
iroha::data_model::isi::ExecuteTrigger::new(registry_id).with_args(&args); |
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 assume this trigger is registered by the trigger from the Register
CLI subcommand
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.
No, the accounts registry should register the transactions registry on the multisig account registration. See diagram in review notes
pub account: AccountId, | ||
/// Instructions to approve | ||
#[arg(short, long)] | ||
pub instructions_hash: iroha::crypto::Hash, |
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.
pub instructions_hash: iroha::crypto::Hash, | |
pub instructions: iroha::crypto::HashOf<Vec<Instruction>>, |
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.
Just utilized iroha::crypto::Hash: FromStr
. It is immediately converted to HashOf<Vec<InstructionBox>>
@@ -39,12 +41,13 @@ pub struct RawGenesisTransaction { | |||
chain: ChainId, | |||
/// Path to the [`Executor`] file | |||
executor: ExecutorPath, | |||
/// Initial topology | |||
topology: Vec<PeerId>, |
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 field should be last as it was before
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.
The idea is no gap with the actual execution order.
Reviewed discussions around #4739 and didn't find reason for the position in RawGenesisTransaction
. Is it because topology is supposed to be edited at genesis.json
?
/// Parameters | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
parameters: Option<Parameters>, | ||
instructions: Vec<InstructionBox>, | ||
/// Initial topology | ||
topology: Vec<PeerId>, | ||
wasm_triggers: Vec<GenesisWasmTrigger>, |
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.
wasm_triggers: Vec<GenesisWasmTrigger>, | |
triggers: Vec<GenesisWasmTrigger>, |
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'd also prefer to put it after instructions
so that they can execute triggers but it's just not possible atm because triggers depend on some instructions executing before them
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.
wasm_
prefix implies the executable is supposed to be Wasm
, not Instructions
.
Yes, ideally it would be in a free position as one of ordinary instructions
as before, which would require WasmSmartContract
to serialize to a short string and deserialize to a full blob
#[derive(Debug, Clone, Serialize, Deserialize, IntoSchema, Encode, Decode)] | ||
pub struct GenesisWasmAction { | ||
/// Expected to be converted by [`iroha_test_samples::load_sample_wasm`] | ||
executable: String, |
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.
executable: String, | |
executable: PathBuf, |
like ExecutorPath
// iroha_test_samples::MULTISIG_SYSTEM_ID | ||
"ed01201F677E0900C2F633391310D12D155112DF65EDF9DC800D13797CEE5DAF47B890@system" | ||
.parse() | ||
.unwrap(); |
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.
if you want to have hardcoded system
domain and account, then they shouldn't be defined in the genesis.json
. Rather they should be always implicitly created
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.
Like genesis domain and account, right?
/// Threshold of total weight at which the multisig is considered authenticated | ||
pub quorum: u16, | ||
/// Multisig transaction time-to-live based on block timestamps. Defaults to [`DEFAULT_MULTISIG_TTL_SECS`] | ||
pub transaction_ttl_secs: Option<u32>, |
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.
pub transaction_ttl_secs: Option<u32>, | |
#[serde(default = DEFAULT_MULTISIG_TTL_SECS)] | |
pub transaction_ttl_ms: u32, |
- can we do it like this?
- we use
ms
intransaction.rs
as unix timestamp
I think there should always be a TTL defined. User an just put a huge number
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.
Ok, we can accept seconds as an user input and convert it to milliseconds here
BREAKING CHANGES:
CanRegisterAnyTrigger
CanUnregisterAnyTrigger
permissiondefaults/genesis.json
assumeswasm_triggers[*].action.executable
is prebuilt underwasm_samples/target/prebuilt/
Major commits:
Context
Solution
Each commit is explained below, starting with the most recent. You can see the commit history here
feat: support multisig recursion
Allows multisig to function hierarchically, expected to be useful for e.g. automating organizational approval flows.
Tests:
cargo test -p iroha integration::multisig::multisig_recursion bash scripts/tests/multisig.recursion.sh
feat: introduce multisig quorum and weights
Inspired by Sui's multisig. Allows for flexible, if not completely free, authentication policies beyond "m of n". For example, weight equivalent to quorum represents administrative privileges
feat: add multisig subcommand to client CLI
You can see more usage in the testing script
feat: introduce multisig transaction time-to-live
Considers the latest block timestamp as the current time and determines timeout, when the transactions registry is called
feat: predefine multisig world-level trigger in genesis
Defines a global trigger in genesis that exercises authority over all domains. There will be three types of triggers on the system side related to multisig:
feat: allow accounts in domain to register multisig accounts
Accounts registry has authority of the domain owner, so access was previously restricted. This commit allows anyone to organize any multisig account within the domain.
This may be too lenient. Discussion
Review notes
To get an overview,
cargo test -p iroha integration::multisig::multisig bash scripts/tests/multisig.sh
The dotted line indicates an automatic process
Checklist
CONTRIBUTING.md
.