From 603e231bd0ec4dfb1b8027824c8197298ebf7ec3 Mon Sep 17 00:00:00 2001 From: Vincent Texier <vit@free.fr> Date: Fri, 18 Jun 2021 11:34:12 +0200 Subject: [PATCH] [enh] #95 refactor subclass currency argument as optional with default=constants.CURRENCY_CODENAME_G1 Break backward compatibility argument is Optional[str] with default=constants.CURRENCY_CODENAME_G1 --- duniterpy/constants.py | 2 ++ duniterpy/documents/block.py | 47 +++++++++++++++++---------- duniterpy/documents/certification.py | 22 +++++++++---- duniterpy/documents/identity.py | 41 ++++++++++++++--------- duniterpy/documents/membership.py | 19 +++++++---- duniterpy/documents/peer.py | 10 +++--- duniterpy/documents/revocation.py | 22 +++++++++---- duniterpy/documents/transaction.py | 25 +++++++------- duniterpy/documents/ws2p/messages.py | 17 +++++----- duniterpy/helpers/ws2p.py | 29 ++++++++++++----- examples/listen_ws2p.py | 3 +- examples/request_ws2p.py | 3 +- examples/save_revoke_document.py | 2 +- examples/send_certification.py | 2 +- examples/send_identity.py | 2 +- examples/send_membership.py | 2 +- examples/send_transaction.py | 2 +- tests/api/ws2p/test_ws2p.py | 2 +- tests/documents/test_certification.py | 26 +++++++++------ tests/documents/test_membership.py | 4 ++- tests/documents/test_transaction.py | 12 +++---- tests/key/test_verifying_key.py | 2 +- 22 files changed, 180 insertions(+), 116 deletions(-) diff --git a/duniterpy/constants.py b/duniterpy/constants.py index dfa6e2c4..7d6b7cea 100644 --- a/duniterpy/constants.py +++ b/duniterpy/constants.py @@ -56,3 +56,5 @@ WS2P_PUBLIC_PREFIX_REGEX = "I[CT]" WS2P_HEAD_REGEX = "HEAD:?(?:[0-9]+)?" EMPTY_HASH = "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855" ENDPOINT_FLAGS_REGEX = "[S]" +G1_CURRENCY_CODENAME = "g1" +G1_TEST_CURRENCY_CODENAME = "g1-test" diff --git a/duniterpy/documents/block.py b/duniterpy/documents/block.py index ef3f46f3..802b95b3 100644 --- a/duniterpy/documents/block.py +++ b/duniterpy/documents/block.py @@ -18,7 +18,7 @@ import hashlib import re from typing import List, Optional, Sequence, Type, TypeVar -from ..constants import BLOCK_HASH_REGEX, PUBKEY_REGEX +from ..constants import BLOCK_HASH_REGEX, G1_CURRENCY_CODENAME, PUBKEY_REGEX # required to type hint cls in classmethod from ..key import SigningKey, VerifyingKey @@ -152,7 +152,6 @@ class Block(Document): def __init__( self, - currency: str, number: int, powmin: int, time: int, @@ -179,11 +178,11 @@ class Block(Document): nonce: int, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Constructor - :param currency: the block currency :param number: the number of the block :param powmin: the powmin value of this block :param time: the timestamp of this block @@ -210,6 +209,7 @@ class Block(Document): :param nonce: the nonce value of the block :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=block.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) @@ -308,39 +308,40 @@ class Block(Document): arguments["parameters"] = arguments["parameters"].split(":") # identities: List[Identity] arguments["identities"] = [ - Identity.from_inline(currency, i + "\n", version) + Identity.from_inline(i + "\n", version=version, currency=currency) for i in arguments["identities"] ] # joiners: List[Membership] arguments["joiners"] = [ - Membership.from_inline(currency, "IN", i + "\n", version) + Membership.from_inline("IN", i + "\n", version=version, currency=currency) for i in arguments["joiners"] ] # actives: List[Membership] arguments["actives"] = [ - Membership.from_inline(currency, "IN", i + "\n", version) + Membership.from_inline("IN", i + "\n", version=version, currency=currency) for i in arguments["actives"] ] # leavers: List[Membership] arguments["leavers"] = [ - Membership.from_inline(currency, "OUT", i + "\n", version) + Membership.from_inline("OUT", i + "\n", version=version, currency=currency) for i in arguments["leavers"] ] # revokations: List[Revocation] arguments["revokations"] = [ - Revocation.from_inline(currency, i + "\n", version) + Revocation.from_inline(i + "\n", version=version, currency=currency) for i in arguments["revokations"] ] # certifications: List[Certification] arguments["certifications"] = [ Certification.from_inline( - currency, arguments["inner_hash"], i + "\n", version + arguments["inner_hash"], i + "\n", version=version, currency=currency ) for i in arguments["certifications"] ] # transactions: List[Transaction] arguments["transactions"] = [ - Transaction.from_bma_history(currency, i) for i in arguments["transactions"] + Transaction.from_bma_history(i, currency=currency) + for i in arguments["transactions"] ] block = cls(**arguments) @@ -437,35 +438,45 @@ class Block(Document): if Block.re_identities.match(lines[n]) is not None: n += 1 while Block.re_joiners.match(lines[n]) is None: - selfcert = Identity.from_inline(currency, lines[n], version) + selfcert = Identity.from_inline( + lines[n], version=version, currency=currency + ) identities.append(selfcert) n += 1 if Block.re_joiners.match(lines[n]): n += 1 while Block.re_actives.match(lines[n]) is None: - membership = Membership.from_inline(currency, "IN", lines[n], version) + membership = Membership.from_inline( + "IN", lines[n], version=version, currency=currency + ) joiners.append(membership) n += 1 if Block.re_actives.match(lines[n]): n += 1 while Block.re_leavers.match(lines[n]) is None: - membership = Membership.from_inline(currency, "IN", lines[n], version) + membership = Membership.from_inline( + "IN", lines[n], version=version, currency=currency + ) actives.append(membership) n += 1 if Block.re_leavers.match(lines[n]): n += 1 while Block.re_revoked.match(lines[n]) is None: - membership = Membership.from_inline(currency, "OUT", lines[n], version) + membership = Membership.from_inline( + "OUT", lines[n], version=version, currency=currency + ) leavers.append(membership) n += 1 if Block.re_revoked.match(lines[n]): n += 1 while Block.re_excluded.match(lines[n]) is None: - revokation = Revocation.from_inline(currency, lines[n], version) + revokation = Revocation.from_inline( + lines[n], version=version, currency=currency + ) revoked.append(revokation) n += 1 @@ -482,7 +493,7 @@ class Block(Document): n += 1 while Block.re_transactions.match(lines[n]) is None: certification = Certification.from_inline( - currency, prev_hash, lines[n], version + prev_hash, lines[n], version=version, currency=currency ) certifications.append(certification) n += 1 @@ -514,7 +525,7 @@ class Block(Document): for index in range(n, tx_max): tx_lines += lines[index] n += tx_max - n - transaction = Transaction.from_compact(currency, tx_lines) + transaction = Transaction.from_compact(tx_lines, currency=currency) transactions.append(transaction) inner_hash = Block.parse_field("InnerHash", lines[n]) @@ -526,7 +537,6 @@ class Block(Document): signature = Block.parse_field("Signature", lines[n]) block = cls( - currency, number, powmin, time, @@ -552,6 +562,7 @@ class Block(Document): inner_hash, nonce, version=version, + currency=currency, ) # return block with signature diff --git a/duniterpy/documents/certification.py b/duniterpy/documents/certification.py index bbb71b76..d1a0c12b 100644 --- a/duniterpy/documents/certification.py +++ b/duniterpy/documents/certification.py @@ -16,7 +16,13 @@ import re from typing import Optional, Type, TypeVar, Union -from ..constants import BLOCK_ID_REGEX, BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX +from ..constants import ( + BLOCK_ID_REGEX, + BLOCK_UID_REGEX, + G1_CURRENCY_CODENAME, + PUBKEY_REGEX, + SIGNATURE_REGEX, +) # required to type hint cls in classmethod from ..key import SigningKey @@ -57,22 +63,22 @@ class Certification(Document): def __init__( self, - currency: str, pubkey_from: str, identity: Union[Identity, str], timestamp: BlockUID, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Constructor - :param currency: the currency of the blockchain :param pubkey_from: Pubkey of the certifier :param identity: Document instance of the certified identity or identity pubkey string :param timestamp: the blockuid :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=certification.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) self.pubkey_from = pubkey_from @@ -117,7 +123,9 @@ class Certification(Document): identity = Identity.from_certification_raw(signed_raw) - certification = cls(currency, pubkey_from, identity, timestamp, version=version) + certification = cls( + pubkey_from, identity, timestamp, version=version, currency=currency + ) # return certification with signature certification.signature = signature @@ -126,10 +134,10 @@ class Certification(Document): @classmethod def from_inline( cls: Type[CertificationType], - currency: str, blockhash: Optional[str], inline: str, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> CertificationType: """ Return Certification instance from inline document @@ -137,10 +145,10 @@ class Certification(Document): Only self.pubkey_to is populated. You must populate self.identity with an Identity instance to use raw/sign/signed_raw methods - :param currency: Name of the currency :param blockhash: Hash of the block :param inline: Inline document :param version: Document version (default=certification.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ cert_data = Certification.re_inline.match(inline) @@ -156,7 +164,7 @@ class Certification(Document): signature = cert_data.group(4) certification = cls( - currency, pubkey_from, pubkey_to, timestamp, version=version + pubkey_from, pubkey_to, timestamp, version=version, currency=currency ) # return certification with signature diff --git a/duniterpy/documents/identity.py b/duniterpy/documents/identity.py index 7d0c460c..6cf3007c 100644 --- a/duniterpy/documents/identity.py +++ b/duniterpy/documents/identity.py @@ -16,7 +16,13 @@ import re from typing import Type, TypeVar -from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX, UID_REGEX +from ..constants import ( + BLOCK_UID_REGEX, + G1_CURRENCY_CODENAME, + PUBKEY_REGEX, + SIGNATURE_REGEX, + UID_REGEX, +) # required to type hint cls in classmethod from ..key import SigningKey @@ -82,22 +88,22 @@ class Identity(Document): def __init__( self, - currency: str, pubkey: str, uid: str, timestamp: BlockUID, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Create an identity document - :param currency: Name of the currency :param pubkey: Public key of the account linked to the identity :param uid: Unique identifier :param timestamp: BlockUID instance :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=identity.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) @@ -110,14 +116,17 @@ class Identity(Document): @classmethod def from_inline( - cls: Type[IdentityType], currency: str, inline: str, version: int = VERSION + cls: Type[IdentityType], + inline: str, + version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> IdentityType: """ Return Identity instance from inline Identity string - :param currency: Name of the currency :param inline: Inline string of the Identity :param version: Document version (default=certification.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ selfcert_data = Identity.re_inline.match(inline) @@ -233,7 +242,7 @@ Timestamp: {timestamp} n += 1 signature = Identity.parse_field("IdtySignature", lines[n]) - identity = cls(currency, issuer, uid, timestamp, version=version) + identity = cls(issuer, uid, timestamp, version=version, currency=currency) identity.signature = signature return identity @@ -267,7 +276,7 @@ Timestamp: {timestamp} n += 1 signature = Identity.parse_field("IdtySignature", lines[n]) - identity = cls(currency, issuer, uid, timestamp, version=version) + identity = cls(issuer, uid, timestamp, version=version, currency=currency) identity.signature = signature return identity @@ -300,15 +309,15 @@ Timestamp: {timestamp} uid = uid_data["uid"] # type: str signature = uid_data["self"] # type: str - # return self-certification document - identity = cls( - version=version, - currency=currency, - pubkey=pubkey, - uid=uid, - timestamp=timestamp, - ) - identity.signature = signature + # return self-certification document + identity = cls( + pubkey=pubkey, + uid=uid, + timestamp=timestamp, + version=version, + currency=currency, + ) + identity.signature = signature if identity is None: raise Exception("Identity pubkey not found") diff --git a/duniterpy/documents/membership.py b/duniterpy/documents/membership.py index 0f3e940f..3c57df49 100644 --- a/duniterpy/documents/membership.py +++ b/duniterpy/documents/membership.py @@ -16,7 +16,12 @@ import re from typing import Type, TypeVar -from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX +from ..constants import ( + BLOCK_UID_REGEX, + G1_CURRENCY_CODENAME, + PUBKEY_REGEX, + SIGNATURE_REGEX, +) # required to type hint cls in classmethod from ..key import SigningKey @@ -79,7 +84,6 @@ class Membership(Document): def __init__( self, - currency: str, issuer: str, membership_ts: BlockUID, membership_type: str, @@ -87,11 +91,11 @@ class Membership(Document): identity_ts: BlockUID, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Create a membership document - :param currency: Name of the currency :param issuer: Public key of the issuer :param membership_ts: BlockUID of this membership :param membership_type: "IN" or "OUT" to enter or quit the community @@ -99,6 +103,7 @@ class Membership(Document): :param identity_ts: BlockUID of the identity :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=membership.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) @@ -114,18 +119,18 @@ class Membership(Document): @classmethod def from_inline( cls: Type[MembershipType], - currency: str, membership_type: str, inline: str, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> MembershipType: """ Return Membership instance from inline format - :param currency: Name of the currency :param membership_type: "IN" or "OUT" to enter or exit membership :param inline: Inline string format :param version: Document version (default=membership.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ data = Membership.re_inline.match(inline) @@ -137,13 +142,13 @@ class Membership(Document): identity_blockstamp = BlockUID.from_str(data.group(4)) uid = data.group(5) membership = cls( - currency, issuer, membership_blockstamp, membership_type, uid, identity_blockstamp, version=version, + currency=currency, ) # return membership with signature @@ -193,13 +198,13 @@ class Membership(Document): n += 1 membership = cls( - currency, issuer, membership_blockstamp, membership_type, uid, identity_blockstamp, version=version, + currency=currency, ) # return membership with signature diff --git a/duniterpy/documents/peer.py b/duniterpy/documents/peer.py index 9d81e056..7df979ab 100644 --- a/duniterpy/documents/peer.py +++ b/duniterpy/documents/peer.py @@ -18,7 +18,7 @@ from typing import List, Type, TypeVar from duniterpy.api.endpoint import Endpoint, endpoint -from ..constants import BLOCK_HASH_REGEX, PUBKEY_REGEX +from ..constants import BLOCK_HASH_REGEX, G1_CURRENCY_CODENAME, PUBKEY_REGEX # required to type hint cls in classmethod from ..key import SigningKey @@ -68,22 +68,22 @@ class Peer(Document): def __init__( self, - currency: str, pubkey: str, block_uid: BlockUID, endpoints: List[Endpoint], signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Peer instance - :param currency: Name of the currency :param pubkey: Public key of the issuer :param block_uid: BlockUID instance timestamp :param endpoints: List of endpoints string :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=peer.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) @@ -133,7 +133,7 @@ class Peer(Document): raise MalformedDocumentError("Peer") signature = data.group(1) - peer = cls(currency, pubkey, block_uid, endpoints, version=version) + peer = cls(pubkey, block_uid, endpoints, version=version, currency=currency) # return peer with signature peer.signature = signature @@ -174,7 +174,7 @@ Endpoints: signature = str(Peer.re_signature.match(data["signature"])) - peer = cls(currency, pubkey, block_uid, endpoints, version=version) + peer = cls(pubkey, block_uid, endpoints, version=version, currency=currency) # return peer with signature peer.signature = signature diff --git a/duniterpy/documents/revocation.py b/duniterpy/documents/revocation.py index 2aa824f0..1b12f71d 100644 --- a/duniterpy/documents/revocation.py +++ b/duniterpy/documents/revocation.py @@ -16,7 +16,12 @@ import re from typing import Type, TypeVar, Union -from ..constants import BLOCK_UID_REGEX, PUBKEY_REGEX, SIGNATURE_REGEX +from ..constants import ( + BLOCK_UID_REGEX, + G1_CURRENCY_CODENAME, + PUBKEY_REGEX, + SIGNATURE_REGEX, +) # required to type hint cls in classmethod from ..key import SigningKey @@ -64,18 +69,18 @@ class Revocation(Document): def __init__( self, - currency: str, identity: Union[Identity, str], signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Revocation instance - :param currency: Name of the currency :param identity: Identity instance or identity pubkey :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=revocation.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) @@ -87,7 +92,10 @@ class Revocation(Document): @classmethod def from_inline( - cls: Type[RevocationType], currency: str, inline: str, version: int = VERSION + cls: Type[RevocationType], + inline: str, + version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> RevocationType: """ Return Revocation document instance from inline string @@ -95,9 +103,9 @@ class Revocation(Document): Only self.pubkey is populated. You must populate self.identity with an Identity instance to use raw/sign/signed_raw methods - :param currency: Name of the currency :param inline: Inline document :param version: Document version (default=revocation.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ cert_data = Revocation.re_inline.match(inline) @@ -105,7 +113,7 @@ class Revocation(Document): raise MalformedDocumentError("Revokation") pubkey = cert_data.group(1) signature = cert_data.group(2) - revocation = cls(currency, pubkey, version=version) + revocation = cls(pubkey, version=version, currency=currency) # return revocation with signature revocation.signature = signature @@ -135,7 +143,7 @@ class Revocation(Document): identity = Identity.from_revocation_raw(signed_raw) - revocation = cls(currency, identity, version=version) + revocation = cls(identity, version=version, currency=currency) # return revocation with signature revocation.signature = signature diff --git a/duniterpy/documents/transaction.py b/duniterpy/documents/transaction.py index eac8edbf..c1a3d6d1 100644 --- a/duniterpy/documents/transaction.py +++ b/duniterpy/documents/transaction.py @@ -24,6 +24,7 @@ from duniterpy.grammars.output import Condition from ..constants import ( BLOCK_ID_REGEX, BLOCK_UID_REGEX, + G1_CURRENCY_CODENAME, PUBKEY_REGEX, TRANSACTION_HASH_REGEX, ) @@ -540,7 +541,6 @@ class Transaction(Document): def __init__( self, - currency: str, blockstamp: Optional[BlockUID], locktime: int, issuers: List[str], @@ -551,11 +551,11 @@ class Transaction(Document): time: Optional[int] = None, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Transaction instance - :param currency: Name of the currency :param blockstamp: BlockUID timestamp of the block :param locktime: Lock time in seconds :param issuers: List of issuers public key @@ -566,6 +566,7 @@ class Transaction(Document): :param time: time when the transaction enters the blockchain :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=transaction.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(version, currency) self.blockstamp = blockstamp @@ -622,14 +623,13 @@ class Transaction(Document): @classmethod def from_bma_history( - cls: Type[TransactionType], currency: str, tx_data: Dict + cls: Type[TransactionType], tx_data: Dict, currency: str = G1_CURRENCY_CODENAME ) -> TransactionType: """ Get the transaction instance from json - :param currency: the currency of the tx :param tx_data: json data of the transaction - + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ tx_data = tx_data.copy() @@ -660,13 +660,13 @@ Comment: {comment} @classmethod def from_compact( - cls: Type[TransactionType], currency: str, compact: str + cls: Type[TransactionType], compact: str, currency: str = G1_CURRENCY_CODENAME ) -> TransactionType: """ Return Transaction instance from compact string format - :param currency: Name of the currency :param compact: Compact format string + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ lines = compact.splitlines(True) @@ -732,7 +732,6 @@ Comment: {comment} raise MalformedDocumentError("Compact TX Signatures") transaction = cls( - currency, blockstamp, locktime, issuers, @@ -741,6 +740,7 @@ Comment: {comment} outputs, comment, version=version, + currency=currency, ) # return transaction with signatures @@ -824,7 +824,6 @@ Comment: {comment} n += 1 transaction = cls( - currency, blockstamp, locktime, issuers, @@ -834,6 +833,7 @@ Comment: {comment} comment, time=time, version=version, + currency=currency, ) # return transaction with signatures @@ -992,7 +992,6 @@ class SimpleTransaction(Transaction): def __init__( self, - currency: str, blockstamp: BlockUID, locktime: int, issuer: str, @@ -1003,12 +1002,11 @@ class SimpleTransaction(Transaction): time: int = 0, signing_key: SigningKey = None, version: int = VERSION, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init instance - :param version: Version number of the document - :param currency: Name of the currency :param blockstamp: BlockUID timestamp :param locktime: Lock time in seconds :param issuer: Issuer public key @@ -1019,9 +1017,9 @@ class SimpleTransaction(Transaction): :param time: time when the transaction enters the blockchain (default=0) :param signing_key: SigningKey instance to sign the document (default=None) :param version: Document version (default=transaction.VERSION) + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__( - currency, blockstamp, locktime, [issuer], @@ -1032,6 +1030,7 @@ class SimpleTransaction(Transaction): time=time, signing_key=signing_key, version=version, + currency=currency, ) @staticmethod diff --git a/duniterpy/documents/ws2p/messages.py b/duniterpy/documents/ws2p/messages.py index 1a7b75a2..7312c80f 100644 --- a/duniterpy/documents/ws2p/messages.py +++ b/duniterpy/documents/ws2p/messages.py @@ -16,6 +16,7 @@ import json from typing import Optional +from duniterpy.constants import G1_CURRENCY_CODENAME from duniterpy.documents import Document from duniterpy.key import SigningKey from duniterpy.tools import get_ws2p_challenge @@ -27,18 +28,18 @@ class HandshakeMessage(Document): def __init__( self, - currency: str, pubkey: str, challenge: Optional[str] = None, signature: Optional[str] = None, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Connect message document - :param currency: Name of the currency :param pubkey: Public key of the node :param challenge: [Optional, default=None] Big random string, typically an uuid :param signature: [Optional, default=None] Base64 encoded signature of raw formated document + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ super().__init__(self.version, currency) @@ -97,20 +98,20 @@ class Ack(HandshakeMessage): def __init__( self, - currency: str, pubkey: str, challenge: str, signature: Optional[str] = None, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Connect message document - :param currency: Name of the currency :param pubkey: Public key of the node :param challenge: Big random string, typically an uuid :param signature: [Optional, default=None] Base64 encoded signature of raw formated document + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ - super().__init__(currency, pubkey, challenge, signature) + super().__init__(pubkey, challenge, signature, currency) def get_signed_json(self, signing_key: SigningKey) -> str: """ @@ -130,20 +131,20 @@ class Ok(HandshakeMessage): def __init__( self, - currency: str, pubkey: str, challenge: str, signature: Optional[str] = None, + currency: str = G1_CURRENCY_CODENAME, ) -> None: """ Init Connect message document - :param currency: Name of the currency :param pubkey: Public key of the node :param challenge: Big random string, typically an uuid :param signature: [Optional, default=None] Base64 encoded signature of raw formated document + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) """ - super().__init__(currency, pubkey, challenge, signature) + super().__init__(pubkey, challenge, signature, currency) def get_signed_json(self, signing_key: SigningKey) -> str: """ diff --git a/duniterpy/helpers/ws2p.py b/duniterpy/helpers/ws2p.py index 7aae54e3..7bc59efe 100644 --- a/duniterpy/helpers/ws2p.py +++ b/duniterpy/helpers/ws2p.py @@ -21,23 +21,26 @@ import jsonschema from duniterpy.api import bma, ws2p from duniterpy.api.client import Client, WSConnection from duniterpy.api.endpoint import BMAEndpoint, SecuredBMAEndpoint, WS2PEndpoint +from duniterpy.constants import G1_CURRENCY_CODENAME from duniterpy.documents.ws2p.messages import Ack, Connect, Ok from duniterpy.key import SigningKey -def handshake(ws: WSConnection, signing_key: SigningKey, currency: str): +def handshake( + ws: WSConnection, signing_key: SigningKey, currency: str = G1_CURRENCY_CODENAME +): """ Perform ws2p handshake on the web socket connection using the signing_key instance :param ws: Web socket connection instance :param signing_key: SigningKey instance - :param currency: Currency name + :param currency: Currency codename (default=constants.CURRENCY_CODENAME_G1) :return: """ # START HANDSHAKE ####################################################### logging.debug("\nSTART HANDSHAKE...") - connect_document = Connect(currency, signing_key.pubkey) + connect_document = Connect(signing_key.pubkey, currency=currency) connect_message = connect_document.get_signed_json(signing_key) logging.debug("Send CONNECT message") @@ -56,13 +59,16 @@ def handshake(ws: WSConnection, signing_key: SigningKey, currency: str): logging.debug("Received a CONNECT message") remote_connect_document = Connect( - currency, data["pub"], data["challenge"], data["sig"] + data["pub"], + challenge=data["challenge"], + signature=data["sig"], + currency=currency, ) logging.debug("Received CONNECT message signature is valid") ack_message = Ack( - currency, signing_key.pubkey, remote_connect_document.challenge + signing_key.pubkey, remote_connect_document.challenge, currency=currency ).get_signed_json(signing_key) # Send ACK message @@ -75,13 +81,18 @@ def handshake(ws: WSConnection, signing_key: SigningKey, currency: str): logging.debug("Received an ACK message") # Create ACK document from ACK response to verify signature - Ack(currency, data["pub"], connect_document.challenge, data["sig"]) + Ack( + data["pub"], + connect_document.challenge, + signature=data["sig"], + currency=currency, + ) logging.debug("Received ACK message signature is valid") # If ACK response is ok, create OK message ok_message = Ok( - currency, signing_key.pubkey, connect_document.challenge + signing_key.pubkey, connect_document.challenge, currency=currency ).get_signed_json(signing_key) # Send OK message @@ -98,10 +109,10 @@ def handshake(ws: WSConnection, signing_key: SigningKey, currency: str): logging.debug("Received an OK message") Ok( - currency, remote_connect_document.pubkey, connect_document.challenge, - data["sig"], + signature=data["sig"], + currency=currency, ) logging.debug("Received OK message signature is valid") diff --git a/examples/listen_ws2p.py b/examples/listen_ws2p.py index e0e56098..d45a8469 100644 --- a/examples/listen_ws2p.py +++ b/examples/listen_ws2p.py @@ -18,6 +18,7 @@ import json import jsonschema from duniterpy.api.client import Client +from duniterpy.constants import G1_TEST_CURRENCY_CODENAME from duniterpy.helpers.ws2p import generate_ws2p_endpoint, handshake from duniterpy.key import SigningKey @@ -27,7 +28,7 @@ from duniterpy.key import SigningKey # or the simple definition : [NAME_OF_THE_API] [DOMAIN] [PORT] [PATH] # Here we use the WS2P API (WS2P [UUID] [DOMAIN] [PORT] [PATH]) BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" -CURRENCY = "g1-test" +CURRENCY = G1_TEST_CURRENCY_CODENAME ################################################ diff --git a/examples/request_ws2p.py b/examples/request_ws2p.py index 0da0eb23..d4b22b4c 100644 --- a/examples/request_ws2p.py +++ b/examples/request_ws2p.py @@ -22,6 +22,7 @@ from jsonschema import ValidationError from duniterpy.api.client import Client, WSConnection from duniterpy.api.ws2p import requests +from duniterpy.constants import G1_TEST_CURRENCY_CODENAME from duniterpy.helpers.ws2p import generate_ws2p_endpoint, handshake from duniterpy.key import SigningKey from duniterpy.tools import get_ws2p_challenge @@ -32,7 +33,7 @@ from duniterpy.tools import get_ws2p_challenge # or the simple definition : [NAME_OF_THE_API] [DOMAIN] [PORT] [PATH] # Here we use the WS2P API (WS2P [UUID] [DOMAIN] [PORT] [PATH]) BMAS_ENDPOINT = "BMAS g1-test.duniter.org 443" -CURRENCY = "g1-test" +CURRENCY = G1_TEST_CURRENCY_CODENAME ################################################ diff --git a/examples/save_revoke_document.py b/examples/save_revoke_document.py index ea98a883..b34325f6 100644 --- a/examples/save_revoke_document.py +++ b/examples/save_revoke_document.py @@ -81,7 +81,7 @@ def get_signed_raw_revocation_document( :rtype: str """ key = SigningKey.from_credentials(salt, password) - revocation = Revocation(identity.currency, identity, key) + revocation = Revocation(identity, key, currency=identity.currency) return revocation.signed_raw() diff --git a/examples/send_certification.py b/examples/send_certification.py index dc08e99a..c0143425 100644 --- a/examples/send_certification.py +++ b/examples/send_certification.py @@ -66,11 +66,11 @@ def get_certification_document( """ # construct Certification Document return Certification( - currency=current_block["currency"], pubkey_from=signing_key.pubkey, identity=identity, timestamp=BlockUID(current_block["number"], current_block["hash"]), signing_key=signing_key, + currency=current_block["currency"], ) diff --git a/examples/send_identity.py b/examples/send_identity.py index c87e15f1..3f805c13 100644 --- a/examples/send_identity.py +++ b/examples/send_identity.py @@ -52,11 +52,11 @@ def get_identity_document( # create identity document identity = Identity( - currency=current_block["currency"], pubkey=key.pubkey, uid=uid, timestamp=timestamp, signing_key=key, + currency=current_block["currency"], ) return identity diff --git a/examples/send_membership.py b/examples/send_membership.py index 8ff26c63..68a45eda 100644 --- a/examples/send_membership.py +++ b/examples/send_membership.py @@ -58,13 +58,13 @@ def get_membership_document( # create membership document membership = Membership( - currency=current_block["currency"], issuer=key.pubkey, membership_ts=timestamp, membership_type=membership_type, uid=uid, identity_ts=identity_timestamp, signing_key=key, + currency=current_block["currency"], ) return membership diff --git a/examples/send_transaction.py b/examples/send_transaction.py index 9e5dd0e9..7560facd 100644 --- a/examples/send_transaction.py +++ b/examples/send_transaction.py @@ -89,7 +89,6 @@ def get_transaction_document( ] transaction = Transaction( - currency=current_block["currency"], blockstamp=BlockUID(current_block["number"], current_block["hash"]), locktime=0, issuers=issuers, @@ -98,6 +97,7 @@ def get_transaction_document( outputs=outputs, comment="", signing_key=signing_key, + currency=current_block["currency"], ) return transaction diff --git a/tests/api/ws2p/test_ws2p.py b/tests/api/ws2p/test_ws2p.py index 63216808..45761b97 100644 --- a/tests/api/ws2p/test_ws2p.py +++ b/tests/api/ws2p/test_ws2p.py @@ -188,11 +188,11 @@ class TestWs2p(unittest.TestCase): document_message = DocumentMessage() # prepare document identity_document = Identity( - "beta_brousouf", "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd", "lolcat", BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"), version=10, + currency="beta_brousouf", ) # get json string message json_document_message = document_message.get_json( diff --git a/tests/documents/test_certification.py b/tests/documents/test_certification.py index a9902267..a4f6b40e 100644 --- a/tests/documents/test_certification.py +++ b/tests/documents/test_certification.py @@ -45,7 +45,9 @@ class TestCertification(unittest.TestCase): def test_self_certification_from_inline(self): version = 2 currency = "beta_brousouf" - selfcert = Identity.from_inline(currency, selfcert_inlines[0], version) + selfcert = Identity.from_inline( + selfcert_inlines[0], version=version, currency=currency + ) self.assertEqual( selfcert.pubkey, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk" ) @@ -58,7 +60,9 @@ class TestCertification(unittest.TestCase): ) self.assertEqual(selfcert.uid, "lolcat") - selfcert = Identity.from_inline(currency, selfcert_inlines[1], version) + selfcert = Identity.from_inline( + selfcert_inlines[1], version=version, currency=currency + ) self.assertEqual(selfcert.pubkey, "RdrHvL179Rw62UuyBrqy2M1crx7RPajaViBatS59EGS") self.assertEqual( selfcert.signature, @@ -77,7 +81,7 @@ class TestCertification(unittest.TestCase): timestamp = BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD") signature = "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci" - selfcert = Identity(currency, issuer, uid, timestamp, version=version) + selfcert = Identity(issuer, uid, timestamp, version=version, currency=currency) selfcert.signature = signature result = """Version: 2 @@ -96,7 +100,7 @@ J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBf def test_certifications_from_inline(self): version = 2 currency = "zeta_brousouf" - cert = Certification.from_inline(currency, None, cert_inlines[0], version) + cert = Certification.from_inline(None, cert_inlines[0], version, currency) self.assertEqual( cert.pubkey_from, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU" ) @@ -109,10 +113,10 @@ J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBf ) cert = Certification.from_inline( - currency, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD", cert_inlines[1], version, + currency, ) self.assertEqual( cert.pubkey_from, "9fx25FmeBDJcikZLWxK5HuzKNbY6MaWYXoK1ajteE42Y" @@ -135,16 +139,16 @@ J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBf timestamp = BlockUID(36, "1076F10A7397715D2BEE82579861999EA1F274AC") signature = "SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk" identity = Identity( - currency, pubkey_to, "lolcat", BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"), version=version, + currency=currency, ) identity.signature = "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci" certification = Certification( - currency, pubkey_from, identity, timestamp, version=version + pubkey_from, identity, timestamp, version=version, currency=currency ) certification.signature = signature @@ -167,7 +171,9 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN def test_revokation_from_inline(self): version = 2 currency = "zeta_brousouf" - revokation = Revocation.from_inline(currency, revokation_inline, version) + revokation = Revocation.from_inline( + revokation_inline, version=version, currency=currency + ) self.assertEqual( revokation.pubkey, "8Fi1VSTbjkXguwThF4v2ZxC5whK7pwG2vcGTkPUPjPGU" ) @@ -182,15 +188,15 @@ SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneN pubkey = "HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd" signature = "SoKwoa8PFfCDJWZ6dNCv7XstezHcc2BbKiJgVDXv82R5zYR83nis9dShLgWJ5w48noVUHimdngzYQneNYSMV3rk" identity = Identity( - currency, pubkey, "lolcat", BlockUID(32, "DB30D958EE5CB75186972286ED3F4686B8A1C2CD"), version=version, + currency=currency, ) identity.signature = "J3G9oM5AKYZNLAB5Wx499w61NuUoS57JVccTShUbGpCMjCqj9yXXqNq7dyZpDWA6BxipsiaMZhujMeBfCznzyci" - revokation = Revocation(currency, identity, version=version) + revokation = Revocation(identity, version=version, currency=currency) revokation.signature = signature result = """Version: 2 diff --git a/tests/documents/test_membership.py b/tests/documents/test_membership.py index 0ec660a4..37830d0f 100644 --- a/tests/documents/test_membership.py +++ b/tests/documents/test_membership.py @@ -35,7 +35,9 @@ dkaXIiCYUJtCg8Feh/BKvPYf4uFH9CJ/zY6J4MlA9BsjmcMe4YAblvNt/gJy31b1aGq3ue3h14mLMCu8 class TestMembership(unittest.TestCase): def test_frominline(self): - membership = Membership.from_inline("zeta_brousouf", "IN", membership_inline, 2) + membership = Membership.from_inline( + "IN", membership_inline, version=2, currency="zeta_brousouf" + ) self.assertEqual( membership.issuer, "HnFcSms8jzwngtVomTTnzudZx7SHUQY8sVE1y8yBmULk" ) diff --git a/tests/documents/test_transaction.py b/tests/documents/test_transaction.py index 56994569..d9df0f75 100644 --- a/tests/documents/test_transaction.py +++ b/tests/documents/test_transaction.py @@ -152,7 +152,7 @@ output_source_str = "460:0:SIG(8kXygUHh1vLjmcRzXVM86t38EL8dfFJgfBeHmkaWLamu)" class TestTransaction(unittest.TestCase): def test_fromcompact(self): - tx = Transaction.from_compact("zeta_brousouf", tx_compact) + tx = Transaction.from_compact(tx_compact, "zeta_brousouf") self.assertEqual(tx.version, 10) self.assertEqual(tx.currency, "zeta_brousouf") self.assertEqual(len(tx.issuers), 3) @@ -368,7 +368,7 @@ class TestTransaction(unittest.TestCase): ) def test_compact_change(self): - tx = Transaction.from_compact("gtest", compact_change) + tx = Transaction.from_compact(compact_change, "gtest") rendered_tx = tx.signed_raw() self.assertEqual(tx_from_compact_change, rendered_tx) Transaction.from_signed_raw(rendered_tx) @@ -388,10 +388,10 @@ class TestTransaction(unittest.TestCase): self.assertEqual(computed[1], 5) def test_is_simple(self): - tx = Transaction.from_compact("zeta_brousouf", simple_tx_compact) + tx = Transaction.from_compact(simple_tx_compact, "zeta_brousouf") self.assertTrue(SimpleTransaction.is_simple(tx)) - tx = Transaction.from_compact("zeta_brousouf", tx_compact) + tx = Transaction.from_compact(tx_compact, "zeta_brousouf") self.assertFalse(SimpleTransaction.is_simple(tx)) def test_inputsource_from_inline(self): @@ -433,7 +433,6 @@ class TestTransaction(unittest.TestCase): def test_transaction_document_generation(self): transaction = Transaction( - currency="gtest", blockstamp=BlockUID( 8979, "000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC" ), @@ -443,6 +442,7 @@ class TestTransaction(unittest.TestCase): unlocks=[Unlock(index=0, parameters=[SIGParameter(0)])], outputs=[OutputSource.from_inline(output_source_str)], comment="", + currency="gtest", ) self.assertTrue(transaction.time is None) self.assertTrue(transaction.currency == "gtest") @@ -466,7 +466,6 @@ class TestTransaction(unittest.TestCase): ] transaction = Transaction( - currency="g1-test", blockstamp=BlockUID( 8979, "000041DF0CCA173F09B5FBA48F619D4BC934F12ADF1D0B798639EB2149C4A8CC" ), @@ -476,6 +475,7 @@ class TestTransaction(unittest.TestCase): unlocks=[Unlock(index=0, parameters=[SIGParameter(0)])], outputs=[OutputSource.from_inline(output_source_str)], comment="", + currency="g1-test", ) # multi-signature on the transaction diff --git a/tests/key/test_verifying_key.py b/tests/key/test_verifying_key.py index d0a3e79e..c6ffb7ae 100644 --- a/tests/key/test_verifying_key.py +++ b/tests/key/test_verifying_key.py @@ -146,5 +146,5 @@ Nonce: 10300000099432 Solde huile Millepertuis rgjOmzFH5h+hkDbJLk1b88X7Z83HMgTa5rBckeMSdF/yZtItN3zMn09MphcXjffdrKcK+MebwoisLJqV+jXrDg== """ - tx = Transaction.from_compact("g1", transaction_document) + tx = Transaction.from_compact(transaction_document, "g1") self.assertTrue(tx.check_signature(tx.issuers[0])) -- GitLab