Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions tests/test_monero_wallet_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
MoneroAddressBookEntry, MoneroSubmitTxResult, MoneroAccountTag
)
from utils import (
MultisigSampleCodeTester,
TestUtils, WalletEqualityUtils,
StringUtils, AssertUtils,
TxContext, GenUtils, WalletUtils,
Expand Down Expand Up @@ -3980,4 +3981,28 @@ def test_rescan_blockchain(self, wallet: MoneroWallet) -> None:

#endregion

#region Utils

def _test_multisig_sample(self, m: int, n: int) -> None:
"""
Test multisig sample code.

:param int m: multisig threshold.
:param int n: number of participants.
"""
# create participant wallets
wallets: list[MoneroWallet] = []

for i in range(n):
wallets.append(self._create_wallet(MoneroWalletConfig()))
logger.debug(f"Created multisig wallet participant {i + 1}")

tester: MultisigSampleCodeTester = MultisigSampleCodeTester(m, wallets)
tester.test()

if self.get_wallet_type() == WalletType.RPC:
TestUtils.free_wallet_rpc_resources()

#endregion

#endregion
21 changes: 2 additions & 19 deletions tests/test_monero_wallet_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@
from utils import (
TestUtils as Utils, StringUtils,
AssertUtils, WalletUtils, WalletType,
MultisigSampleCodeTester, SyncSeedTester,
SyncProgressTester, WalletEqualityUtils,
WalletErrorUtils
SyncSeedTester, SyncProgressTester,
WalletEqualityUtils, WalletErrorUtils
)
from test_monero_wallet_common import BaseTestMoneroWallet

Expand Down Expand Up @@ -698,22 +697,6 @@ def test_import_key_images(self, wallet: MoneroWallet):

#region Utils

def _test_multisig_sample(self, m: int, n: int) -> None:
"""
Test multisig sample code.

:param int m: multisig threshold.
:param int n: number of participants.
"""
# create participant wallets
wallets: list[MoneroWalletFull] = []
for i in range(n):
wallets.append(self._create_wallet(MoneroWalletConfig()))
logger.debug(f"Created multisig wallet participant {i + 1}")

tester: MultisigSampleCodeTester = MultisigSampleCodeTester(m, wallets)
tester.test()

def _test_sync_seed(
self,
daemon: MoneroDaemonRpc,
Expand Down
6 changes: 6 additions & 0 deletions tests/test_monero_wallet_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ def test_open_wallet(self)-> None:
for wallet in wallets:
self._close_wallet(wallet)

# Supports multisig sample code
@pytest.mark.skipif(Utils.TEST_NON_RELAYS is False, reason="TEST_NON_RELAYS disabled")
def test_multisig_sample(self) -> None:
self._test_multisig_sample(1, 2)
self._test_multisig_sample(2, 2)

# Can save the wallet
@pytest.mark.skipif(Utils.TEST_NON_RELAYS is False, reason="TEST_NON_RELAYS disabled")
def test_save(self, wallet: MoneroWallet) -> None:
Expand Down
31 changes: 19 additions & 12 deletions tests/utils/multisig_sample_code_tester.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import logging

from monero import (
MoneroWalletFull, MoneroMultisigInitResult,
MoneroUtils, MoneroMultisigInfo
MoneroWallet, MoneroUtils,
MoneroMultisigInitResult, MoneroMultisigInfo
)

from .wallet_utils import WalletUtils
from .test_utils import TestUtils

logger: logging.Logger = logging.getLogger("MultisigSampleCodeTester")


class MultisigSampleCodeTester:
"""Create and test a multisig wallet with M/N configuration."""
Expand All @@ -14,23 +18,23 @@ class MultisigSampleCodeTester:
"""Multisig threshold."""
n: int
"""Multisig participants."""
wallets: list[MoneroWalletFull]
wallets: list[MoneroWallet]
"""Participants test wallets."""

def __init__(self, m: int, participants: list[MoneroWalletFull]) -> None:
def __init__(self, m: int, participants: list[MoneroWallet]) -> None:
"""Initialize a new create-multisig-wallet tester.

:param int m: multisig threshold.
:param list[MoneroWalletFull] participants: participant wallets.
:param list[MoneroWallet] participants: participant wallets.
"""
n: int = len(participants)
assert m <= n, "Threshold must be less or equal to number of participants"
self.m = m
self.n = n
self.wallets = participants
self._disposed = False

def test(self) -> None:
"""Test multisig wallet creation."""
def make_multisig_wallets(self) -> list[str]:
# prepare and collect multisig hex from each participant
prepared_multisig_hexes: list[str] = []

Expand All @@ -51,14 +55,20 @@ def test(self) -> None:
multisig_hex: str = self.wallets[i].make_multisig(peer_multisig_hexes, self.m, TestUtils.WALLET_PASSWORD)
made_multisig_hexes.append(multisig_hex)

return made_multisig_hexes.copy()

def test(self) -> None:
"""Test multisig wallet creation."""

# exchange multisig keys N - M + 1 times
multisig_hexes: list[str] = made_multisig_hexes.copy()
multisig_hexes: list[str] = self.make_multisig_wallets()
for i in range(self.n - self.m + 1):
# exchange multisig keys among participants and collect results for next round if applicable
result_multisig_hexes: list[str] = []
for wallet in self.wallets:
# import the multisig hex of other participants and collect results
result: MoneroMultisigInitResult = wallet.exchange_multisig_keys(multisig_hexes, TestUtils.WALLET_PASSWORD)
logger.debug(f"Round {i + 1}, multisig init result: {result.serialize()}")
assert result.multisig_hex is not None
result_multisig_hexes.append(result.multisig_hex)

Expand All @@ -71,8 +81,5 @@ def test(self) -> None:
# TODO: replace with MoneroWallet.get_network_type() when all methods defined in interface
MoneroUtils.validate_address(primary_address, TestUtils.NETWORK_TYPE)
info: MoneroMultisigInfo = wallet.get_multisig_info()
assert info.is_multisig is True
assert info.is_ready is True
assert self.m == info.threshold
assert self.n == info.num_participants
WalletUtils.test_multisig_info(info, self.m, self.n)
wallet.close(True)
16 changes: 15 additions & 1 deletion tests/utils/wallet_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
MoneroNetworkType, MoneroUtils, MoneroAccount,
MoneroSubaddress, MoneroAddressBookEntry,
MoneroMessageSignatureResult, MoneroWallet,
MoneroTxConfig
MoneroTxConfig, MoneroMultisigInfo
)

from .gen_utils import GenUtils
Expand Down Expand Up @@ -234,6 +234,20 @@ def test_wallet_keys(cls, address: str, view_key: str, spend_key: str, w: Monero
MoneroUtils.validate_mnemonic(w.get_seed())
assert MoneroWallet.DEFAULT_LANGUAGE == w.get_seed_language()

@classmethod
def test_multisig_info(cls, info: MoneroMultisigInfo, threshold: int, num_participants: int) -> None:
"""Test multisignature wallet info.

:param MoneroMultisigInfo info: wallet multisignature info to test.
:param int threshold: expected multisig threshold.
:param int num_participants: expected number of participants.
"""
logger.debug(f"Testing multisig info: {info.serialize()}")
assert info.is_multisig is True
assert info.is_ready is True
assert threshold == info.threshold
assert num_participants == info.num_participants

@classmethod
def build_payment_uri_config(cls, address: str) -> MoneroTxConfig:
tx_config = MoneroTxConfig()
Expand Down
Loading