Skip to content

Commit

Permalink
Fix MultiSigLegacy (#13146)
Browse files Browse the repository at this point in the history
  • Loading branch information
mystenmark authored Jul 25, 2023
1 parent 03a0e23 commit 331f81b
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 60 deletions.
165 changes: 165 additions & 0 deletions crates/sui-e2e-tests/tests/multisig_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use sui_core::authority_client::AuthorityAPI;
use sui_json_rpc_types::SuiTransactionBlockEffectsAPI;
use sui_macros::sim_test;
use sui_test_transaction_builder::TestTransactionBuilder;
use sui_types::{
base_types::SuiAddress,
error::{SuiError, SuiResult},
multisig::MultiSigPublicKey,
multisig_legacy::MultiSigPublicKeyLegacy,
utils::{keys, make_upgraded_multisig_tx},
};
use test_cluster::TestClusterBuilder;

async fn do_upgraded_multisig_test() -> SuiResult {
let test_cluster = TestClusterBuilder::new().build().await;
let tx = make_upgraded_multisig_tx();

test_cluster
.authority_aggregator()
.authority_clients
.values()
.next()
.unwrap()
.authority_client()
.handle_transaction(tx)
.await
.map(|_| ())
}

#[sim_test]
async fn test_upgraded_multisig_feature_deny() {
use sui_protocol_config::ProtocolConfig;

let _guard = ProtocolConfig::apply_overrides_for_testing(|_, mut config| {
config.set_upgraded_multisig_for_testing(false);
config
});

let err = do_upgraded_multisig_test().await.unwrap_err();

assert!(matches!(err, SuiError::UnsupportedFeatureError { .. }));
}

#[sim_test]
async fn test_upgraded_multisig_feature_allow() {
use sui_protocol_config::ProtocolConfig;

let _guard = ProtocolConfig::apply_overrides_for_testing(|_, mut config| {
config.set_upgraded_multisig_for_testing(true);
config
});

let res = do_upgraded_multisig_test().await;

// we didn't make a real transaction with a valid object, but we verify that we pass the
// feature gate.
assert!(matches!(res.unwrap_err(), SuiError::UserInputError { .. }));
}

#[sim_test]
async fn test_multisig_e2e() {
let mut test_cluster = TestClusterBuilder::new().build().await;

let keys = keys();
let pk1 = keys[0].public();
let pk2 = keys[1].public();
let pk3 = keys[2].public();

let multisig_pk = MultiSigPublicKey::new(
vec![pk1.clone(), pk2.clone(), pk3.clone()],
vec![1, 1, 1],
2,
)
.unwrap();
let multisig_addr = SuiAddress::from(&multisig_pk);

let (sender, gas) = test_cluster
.wallet
.get_one_gas_object()
.await
.unwrap()
.unwrap();
let rgp = test_cluster.get_reference_gas_price().await;
let context = &mut test_cluster.wallet;
let transfer_to_multisig = context.sign_transaction(
&TestTransactionBuilder::new(sender, gas, rgp)
.transfer_sui(Some(20000000000), multisig_addr)
.build(),
);
let resp = context
.execute_transaction_must_succeed(transfer_to_multisig)
.await;

let new_obj = resp
.effects
.unwrap()
.created()
.first()
.unwrap()
.reference
.to_object_ref();
// now send it back
let transfer_from_multisig = TestTransactionBuilder::new(multisig_addr, new_obj, rgp)
.transfer_sui(Some(1000000), sender)
.build_and_sign_multisig(multisig_pk, &[&keys[0], &keys[1]]);

context
.execute_transaction_must_succeed(transfer_from_multisig)
.await;
}

#[sim_test]
async fn test_multisig_legacy_e2e() {
let mut test_cluster = TestClusterBuilder::new().build().await;

let keys = keys();
let pk1 = keys[0].public();
let pk2 = keys[1].public();
let pk3 = keys[2].public();

let multisig_pk = MultiSigPublicKeyLegacy::new(
vec![pk1.clone(), pk2.clone(), pk3.clone()],
vec![1, 1, 1],
2,
)
.unwrap();
let multisig_addr = SuiAddress::from(&multisig_pk);

let (sender, gas) = test_cluster
.wallet
.get_one_gas_object()
.await
.unwrap()
.unwrap();
let rgp = test_cluster.get_reference_gas_price().await;
let context = &mut test_cluster.wallet;
let transfer_to_multisig = context.sign_transaction(
&TestTransactionBuilder::new(sender, gas, rgp)
.transfer_sui(Some(20000000000), multisig_addr)
.build(),
);
let resp = context
.execute_transaction_must_succeed(transfer_to_multisig)
.await;

let new_obj = resp
.effects
.unwrap()
.created()
.first()
.unwrap()
.reference
.to_object_ref();
// now send it back
let transfer_from_multisig = TestTransactionBuilder::new(multisig_addr, new_obj, rgp)
.transfer_sui(Some(1000000), sender)
.build_and_sign_multisig_legacy(multisig_pk, &[&keys[0], &keys[1]]);

context
.execute_transaction_must_succeed(transfer_from_multisig)
.await;
}
54 changes: 0 additions & 54 deletions crates/sui-e2e-tests/tests/multisig_upgrade_test.rs

This file was deleted.

46 changes: 45 additions & 1 deletion crates/sui-test-transaction-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

use move_core_types::ident_str;
use shared_crypto::intent::Intent;
use shared_crypto::intent::{Intent, IntentMessage};
use std::path::PathBuf;
use sui_genesis_builder::validator_info::GenesisValidatorMetadata;
use sui_move_build::BuildConfig;
Expand All @@ -13,7 +13,10 @@ use sui_sdk::wallet_context::WalletContext;
use sui_types::base_types::{ObjectID, ObjectRef, SequenceNumber, SuiAddress};
use sui_types::crypto::{get_key_pair, AccountKeyPair, Signature, Signer};
use sui_types::digests::TransactionDigest;
use sui_types::multisig::{MultiSig, MultiSigPublicKey};
use sui_types::multisig_legacy::{MultiSigLegacy, MultiSigPublicKeyLegacy};
use sui_types::object::Owner;
use sui_types::signature::GenericSignature;
use sui_types::sui_system_state::SUI_SYSTEM_MODULE_NAME;
use sui_types::transaction::{
CallArg, ObjectArg, ProgrammableTransaction, Transaction, TransactionData,
Expand Down Expand Up @@ -278,6 +281,47 @@ impl TestTransactionBuilder {
pub fn build_and_sign(self, signer: &dyn Signer<Signature>) -> Transaction {
Transaction::from_data_and_signer(self.build(), Intent::sui_transaction(), vec![signer])
}

pub fn build_and_sign_multisig(
self,
multisig_pk: MultiSigPublicKey,
signers: &[&dyn Signer<Signature>],
) -> Transaction {
let data = self.build();
let intent = Intent::sui_transaction();
let intent_msg = IntentMessage::new(intent.clone(), data.clone());

let mut signatures = Vec::with_capacity(signers.len());
for signer in signers {
signatures.push(Signature::new_secure(&intent_msg, *signer));
}

let multisig =
GenericSignature::MultiSig(MultiSig::combine(signatures, multisig_pk).unwrap());

Transaction::from_generic_sig_data(data, intent, vec![multisig])
}

pub fn build_and_sign_multisig_legacy(
self,
multisig_pk: MultiSigPublicKeyLegacy,
signers: &[&dyn Signer<Signature>],
) -> Transaction {
let data = self.build();
let intent = Intent::sui_transaction();
let intent_msg = IntentMessage::new(intent.clone(), data.clone());

let mut signatures = Vec::with_capacity(signers.len());
for signer in signers {
signatures.push(Signature::new_secure(&intent_msg, *signer));
}

let multisig = GenericSignature::MultiSigLegacy(
MultiSigLegacy::combine(signatures, multisig_pk).unwrap(),
);

Transaction::from_generic_sig_data(data, intent, vec![multisig])
}
}

enum TestTransactionData {
Expand Down
11 changes: 6 additions & 5 deletions crates/sui-types/src/multisig_legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,20 @@ impl Hash for MultiSigLegacy {

impl AuthenticatorTrait for MultiSigLegacy {
fn verify_user_authenticator_epoch(&self, _: EpochId) -> Result<(), SuiError> {
unreachable!("cannot be called because verify_authenticator is overridden");
Ok(())
}

fn verify_claims<T>(
&self,
_: &IntentMessage<T>,
_: SuiAddress,
_: &VerifyParams,
value: &IntentMessage<T>,
author: SuiAddress,
aux_verify_data: &VerifyParams,
) -> Result<(), SuiError>
where
T: Serialize,
{
unreachable!("cannot be called because verify_authenticator is overridden");
let multisig: MultiSig = self.clone().try_into()?;
multisig.verify_claims(value, author, aux_verify_data)
}

fn verify_authenticator<T>(
Expand Down

2 comments on commit 331f81b

@vercel
Copy link

@vercel vercel bot commented on 331f81b Jul 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

sui-typescript-docs – ./sdk/docs

sui-typescript-docs-git-main-mysten-labs.vercel.app
sui-typescript-docs-mysten-labs.vercel.app
sui-typescript-docs.vercel.app

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 Validators 500/s Owned Transactions Benchmark Results

Benchmark Report:
+-------------+-----+-----+--------+---------------+---------------+---------------+-----------------------+----------------------------+
| duration(s) | tps | cps | error% | latency (min) | latency (p50) | latency (p99) | gas used (MIST total) | gas used/hr (MIST approx.) |
+=======================================================================================================================================+
| 60          | 593 | 593 | 0      | 19            | 8343          | 8551          | 430,781,952,000       | 25,846,917,120,000         |
Stress Performance Report:
+-----------+-----+-----+
| metric    | p50 | p99 |
+=======================+
| cpu usage | 12  | 100 |

4 Validators 500/s Shared Transactions Benchmark Results

Benchmark Report:
+-------------+-----+-----+--------+---------------+---------------+---------------+-----------------------+----------------------------+
| duration(s) | tps | cps | error% | latency (min) | latency (p50) | latency (p99) | gas used (MIST total) | gas used/hr (MIST approx.) |
+=======================================================================================================================================+
| 60          | 490 | 490 | 0      | 22            | 9127          | 13207         | 442,671,699,600       | 26,560,301,976,000         |
Stress Performance Report:
+-----------+-----+-----+
| metric    | p50 | p99 |
+=======================+
| cpu usage | 12  | 100 |

20 Validators 50/s Owned Transactions Benchmark Results

Benchmark Report:
+-------------+-----+-----+--------+---------------+---------------+---------------+-----------------------+----------------------------+
| duration(s) | tps | cps | error% | latency (min) | latency (p50) | latency (p99) | gas used (MIST total) | gas used/hr (MIST approx.) |
+=======================================================================================================================================+
| 60          | 200 | 200 | 0      | 21            | 65            | 124           | 141,062,400,000       | 8,463,744,000,000          |
Stress Performance Report:
+-----------+-----+-----+
| metric    | p50 | p99 |
+=======================+
| cpu usage | 27  | 50  |

20 Validators 50/s Shared Transactions Benchmark Results

Benchmark Report:
+-------------+-----+-----+--------+---------------+---------------+---------------+-----------------------+----------------------------+
| duration(s) | tps | cps | error% | latency (min) | latency (p50) | latency (p99) | gas used (MIST total) | gas used/hr (MIST approx.) |
+=======================================================================================================================================+
| 60          | 194 | 194 | 0      | 66            | 1422          | 2105          | 177,653,904,000       | 10,659,234,240,000         |
Stress Performance Report:
+-----------+-----+-----+
| metric    | p50 | p99 |
+=======================+
| cpu usage | 25  | 57  |

Narwhal Benchmark Results

 SUMMARY:
-----------------------------------------
 + CONFIG:
 Faults: 0 node(s)
 Committee size: 4 node(s)
 Worker(s) per node: 1 worker(s)
 Collocate primary and workers: True
 Input rate: 50,000 tx/s
 Transaction size: 512 B
 Execution time: 0 s

 Header number of batches threshold: 32 digests
 Header maximum number of batches: 1,000 digests
 Max header delay: 2,000 ms
 GC depth: 50 round(s)
 Sync retry delay: 10,000 ms
 Sync retry nodes: 3 node(s)
 batch size: 500,000 B
 Max batch delay: 200 ms
 Max concurrent requests: 500,000 

 + RESULTS:
 Batch creation avg latency: 202 ms
 Header creation avg latency: -1 ms
 	Batch to header avg latency: -1 ms
 Header to certificate avg latency: 1 ms
 	Request vote outbound avg latency: 0 ms
 Certificate commit avg latency: 722 ms

 Consensus TPS: 0 tx/s
 Consensus BPS: 0 B/s
 Consensus latency: 0 ms

 End-to-end TPS: 0 tx/s
 End-to-end BPS: 0 B/s
 End-to-end latency: 0 ms
-----------------------------------------

Please sign in to comment.