Skip to content
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

Relayed v3 cleanup #114

Merged
merged 3 commits into from
Oct 22, 2024
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
64 changes: 0 additions & 64 deletions examples/Cookbook.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -789,70 +789,6 @@
"print(transaction_converter.transaction_to_dictionary(relayed_tx))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Relayed V3\n",
"\n",
"This is the latest iteration of relayed transactions and we highly recommend using this version over the previous ones as soon as it becomes available on the network."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'nonce': 0, 'value': '0', 'receiver': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'sender': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 110000, 'data': '', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '', 'guardianSignature': '', 'relayer': '', 'innerTransactions': [{'nonce': 15, 'value': '0', 'receiver': 'erd1qqqqqqqqqqqqqpgqqczn0ccd2gh8eqdswln7w9vzctv0dwq7d8ssm4y34z', 'sender': 'erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx', 'senderUsername': '', 'receiverUsername': '', 'gasPrice': 1000000000, 'gasLimit': 60000, 'data': 'aGVsbG8=', 'chainID': 'D', 'version': 2, 'options': 0, 'guardian': '', 'signature': '730ae25bda39d5aaa25cc6f8e27c1cc5fa67869464559187dcdd02e22b88e561bf4660718791200a37290d2ff8c73449c1ef6ef38ddce7b36c89931d8fa2f10b', 'guardianSignature': '', 'relayer': 'erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th', 'innerTransactions': []}]}\n"
]
}
],
"source": [
"from pathlib import Path\n",
"\n",
"from multiversx_sdk import (Address, RelayedTransactionsFactory, Transaction,\n",
" TransactionComputer, TransactionsFactoryConfig,\n",
" UserSigner)\n",
"\n",
"bob = UserSigner.from_pem_file(Path(\"../multiversx_sdk/testutils/testwallets/bob.pem\"))\n",
"relayer = Address.new_from_bech32(\"erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th\")\n",
"\n",
"inner_tx = Transaction(\n",
" chain_id=network_config.chain_id,\n",
" sender=\"erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx\",\n",
" receiver=\"erd1qqqqqqqqqqqqqpgqqczn0ccd2gh8eqdswln7w9vzctv0dwq7d8ssm4y34z\",\n",
" gas_limit=60000,\n",
" nonce=15,\n",
" data=b\"hello\",\n",
" relayer=relayer.to_bech32()\n",
" )\n",
"transaction_computer = TransactionComputer()\n",
"inner_tx.signature = bob.sign(transaction_computer.compute_bytes_for_signing(inner_tx))\n",
"\n",
"config = TransactionsFactoryConfig(chain_id=\"D\")\n",
"factory = RelayedTransactionsFactory(config=config)\n",
"\n",
"relayed_tx = factory.create_relayed_v3_transaction(\n",
" relayer_address=relayer,\n",
" inner_transactions=[inner_tx]\n",
")\n",
"\n",
"print(transaction_converter.transaction_to_dictionary(relayed_tx))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A few things worth mentioning before moving further, the `data` field of the relayer's transaction **should not** be set and the relayer should be in the same shard as the sender of the inner transaction.\n",
"\n",
"Don't forget, after the Relayed V3 transaction is created, the `nonce` needs to be set and the transaction should be signed before broadcasting it."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
6 changes: 1 addition & 5 deletions multiversx_sdk/converters/transactions_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ def transaction_to_dictionary(self, transaction: ITransaction) -> Dict[str, Any]
"options": transaction.options,
"guardian": transaction.guardian,
"signature": self._value_to_hex_or_empty(transaction.signature),
"guardianSignature": self._value_to_hex_or_empty(transaction.guardian_signature),
"relayer": transaction.relayer,
"innerTransactions": [self.transaction_to_dictionary(inner_tx) for inner_tx in transaction.inner_transactions]
"guardianSignature": self._value_to_hex_or_empty(transaction.guardian_signature)
}

def dictionary_to_transaction(self, dictionary: Dict[str, Any]) -> Transaction:
Expand All @@ -57,8 +55,6 @@ def dictionary_to_transaction(self, dictionary: Dict[str, Any]) -> Transaction:
options=dictionary.get("options", None),
signature=self._bytes_from_hex(dictionary.get("signature", "")),
guardian_signature=self._bytes_from_hex(dictionary.get("guardianSignature", "")),
relayer=dictionary.get("relayer", None),
inner_transactions=[self.dictionary_to_transaction(inner_tx) for inner_tx in dictionary.get("innerTransactions", [])],
)

def transaction_on_network_to_outcome(self, transaction_on_network: TransactionOnNetwork) -> TransactionOutcome:
Expand Down
31 changes: 0 additions & 31 deletions multiversx_sdk/converters/transactions_converter_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,6 @@ def test_transaction_converter():
assert transaction == restored_tx


def test_transaction_from_dictionary_with_inner_transaction():
converter = TransactionsConverter()

inner_transaction = Transaction(
nonce=90,
value=123456789000000000000000000000,
sender="erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th",
receiver="erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx",
sender_username="alice",
receiver_username="bob",
gas_limit=80000,
data=b"hello",
chain_id="localnet",
relayer="erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8"
)

relayed_transaction = Transaction(
nonce=77,
sender="erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8",
receiver="erd1k2s324ww2g0yj38qn2ch2jwctdy8mnfxep94q9arncc6xecg3xaq6mjse8",
gas_limit=180000,
chain_id="localnet",
inner_transactions=[inner_transaction]
)

tx_as_dict = converter.transaction_to_dictionary(relayed_transaction)
restored_tx = converter.dictionary_to_transaction(tx_as_dict)

assert relayed_transaction == restored_tx


def test_convert_tx_on_network_to_outcome():
converter = TransactionsConverter()

Expand Down
7 changes: 1 addition & 6 deletions multiversx_sdk/core/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, Protocol, Sequence
from typing import Optional, Protocol


class IAddress(Protocol):
Expand All @@ -25,11 +25,6 @@ class ITransaction(Protocol):
guardian: str
signature: bytes
guardian_signature: bytes
relayer: str

@property
def inner_transactions(self) -> Sequence["ITransaction"]:
...


class IMessage(Protocol):
Expand Down
2 changes: 0 additions & 2 deletions multiversx_sdk/core/proto/transaction.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ message Transaction {
uint32 Options = 13;
bytes GuardAddr = 14;
bytes GuardSignature = 15;
bytes Relayer = 16;
repeated Transaction InnerTransactions = 17;
}
13 changes: 7 additions & 6 deletions multiversx_sdk/core/proto/transaction_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 3 additions & 8 deletions multiversx_sdk/core/proto/transaction_pb2.pyi
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from google.protobuf.internal import containers as _containers
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
from typing import ClassVar as _ClassVar, Optional as _Optional

DESCRIPTOR: _descriptor.FileDescriptor

class Transaction(_message.Message):
__slots__ = ["ChainID", "Data", "GasLimit", "GasPrice", "GuardAddr", "GuardSignature", "InnerTransactions", "Nonce", "Options", "RcvAddr", "RcvUserName", "Relayer", "Signature", "SndAddr", "SndUserName", "Value", "Version"]
__slots__ = ["ChainID", "Data", "GasLimit", "GasPrice", "GuardAddr", "GuardSignature", "Nonce", "Options", "RcvAddr", "RcvUserName", "Signature", "SndAddr", "SndUserName", "Value", "Version"]
CHAINID_FIELD_NUMBER: _ClassVar[int]
ChainID: bytes
DATA_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -19,18 +18,14 @@ class Transaction(_message.Message):
GasPrice: int
GuardAddr: bytes
GuardSignature: bytes
INNERTRANSACTIONS_FIELD_NUMBER: _ClassVar[int]
InnerTransactions: _containers.RepeatedCompositeFieldContainer[Transaction]
NONCE_FIELD_NUMBER: _ClassVar[int]
Nonce: int
OPTIONS_FIELD_NUMBER: _ClassVar[int]
Options: int
RCVADDR_FIELD_NUMBER: _ClassVar[int]
RCVUSERNAME_FIELD_NUMBER: _ClassVar[int]
RELAYER_FIELD_NUMBER: _ClassVar[int]
RcvAddr: bytes
RcvUserName: bytes
Relayer: bytes
SIGNATURE_FIELD_NUMBER: _ClassVar[int]
SNDADDR_FIELD_NUMBER: _ClassVar[int]
SNDUSERNAME_FIELD_NUMBER: _ClassVar[int]
Expand All @@ -41,4 +36,4 @@ class Transaction(_message.Message):
VERSION_FIELD_NUMBER: _ClassVar[int]
Value: bytes
Version: int
def __init__(self, Nonce: _Optional[int] = ..., Value: _Optional[bytes] = ..., RcvAddr: _Optional[bytes] = ..., RcvUserName: _Optional[bytes] = ..., SndAddr: _Optional[bytes] = ..., SndUserName: _Optional[bytes] = ..., GasPrice: _Optional[int] = ..., GasLimit: _Optional[int] = ..., Data: _Optional[bytes] = ..., ChainID: _Optional[bytes] = ..., Version: _Optional[int] = ..., Signature: _Optional[bytes] = ..., Options: _Optional[int] = ..., GuardAddr: _Optional[bytes] = ..., GuardSignature: _Optional[bytes] = ..., Relayer: _Optional[bytes] = ..., InnerTransactions: _Optional[_Iterable[_Union[Transaction, _Mapping]]] = ...) -> None: ... # pyright: ignore
def __init__(self, Nonce: _Optional[int] = ..., Value: _Optional[bytes] = ..., RcvAddr: _Optional[bytes] = ..., RcvUserName: _Optional[bytes] = ..., SndAddr: _Optional[bytes] = ..., SndUserName: _Optional[bytes] = ..., GasPrice: _Optional[int] = ..., GasLimit: _Optional[int] = ..., Data: _Optional[bytes] = ..., ChainID: _Optional[bytes] = ..., Version: _Optional[int] = ..., Signature: _Optional[bytes] = ..., Options: _Optional[int] = ..., GuardAddr: _Optional[bytes] = ..., GuardSignature: _Optional[bytes] = ...) -> None: ...
13 changes: 1 addition & 12 deletions multiversx_sdk/core/proto/transaction_serializer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Protocol, Sequence
from typing import Protocol

import multiversx_sdk.core.proto.transaction_pb2 as ProtoTransaction
from multiversx_sdk.core.address import Address
Expand All @@ -21,11 +21,6 @@ class ITransaction(Protocol):
guardian: str
signature: bytes
guardian_signature: bytes
relayer: str

@property
def inner_transactions(self) -> Sequence["ITransaction"]:
...


class ProtoSerializer:
Expand Down Expand Up @@ -71,10 +66,4 @@ def convert_to_proto_message(self, transaction: ITransaction) -> ProtoTransactio
proto_transaction.GuardAddr = Address.new_from_bech32(guardian_address).get_public_key()
proto_transaction.GuardSignature = transaction.guardian_signature

if transaction.relayer != "":
proto_transaction.Relayer = Address.new_from_bech32(transaction.relayer).get_public_key()

proto_transaction.InnerTransactions.extend(
[self.convert_to_proto_message(inner_tx) for inner_tx in transaction.inner_transactions])

return proto_transaction
31 changes: 0 additions & 31 deletions multiversx_sdk/core/proto/transaction_serializer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,34 +86,3 @@ def test_serialized_tx_with_usernames(self):

serialized_transaction = self.proto_serializer.serialize_transaction(transaction)
assert serialized_transaction.hex() == "08cc011209000de0b6b3a76400001a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e12205616c6963652a20b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba32056361726f6c388094ebdc0340d086035201545802624051e6cd78fb3ab4b53ff7ad6864df27cb4a56d70603332869d47a5cf6ea977c30e696103e41e8dddf2582996ad335229fdf4acb726564dbc1a0bc9e705b511f06"

def test_serialized_tx_with_inner_txs(self):
inner_transaction = Transaction(
sender=self.carol.label,
receiver=self.alice.label,
gas_limit=50000,
chain_id="T",
nonce=204,
value=1000000000000000000,
sender_username="carol",
receiver_username="alice"
)
inner_transaction.signature = self.carol.secret_key.sign(self.transaction_computer.compute_bytes_for_signing(inner_transaction))

relayed_transaction = Transaction(
sender=self.carol.label,
receiver=self.alice.label,
gas_limit=50000,
chain_id="T",
nonce=204,
value=1000000000000000000,
sender_username="carol",
receiver_username="alice",
relayer=self.carol.label,
inner_transactions=[inner_transaction]
)

relayed_transaction.signature = self.carol.secret_key.sign(self.transaction_computer.compute_bytes_for_signing(
relayed_transaction))
serialized_transaction = self.proto_serializer.serialize_transaction(relayed_transaction)
assert serialized_transaction.hex() == "08cc011209000de0b6b3a76400001a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e12205616c6963652a20b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba32056361726f6c388094ebdc0340d0860352015458026240901a6a974d6ab36546e7881c6e0364ec4c61a891aa70e5eb60f818d6c92a39cfa0beac6fab73f503853cfe8fe6149b4be207ddb93788f8450d75a07fa8759d06820120b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba8a01b10108cc011209000de0b6b3a76400001a200139472eff6886771a982f3083da5d421f24c29181e63888228dc81ca60d69e12205616c6963652a20b2a11555ce521e4944e09ab17549d85b487dcd26c84b5017a39e31a3670889ba32056361726f6c388094ebdc0340d086035201545802624051e6cd78fb3ab4b53ff7ad6864df27cb4a56d70603332869d47a5cf6ea977c30e696103e41e8dddf2582996ad335229fdf4acb726564dbc1a0bc9e705b511f06"
9 changes: 2 additions & 7 deletions multiversx_sdk/core/transaction.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from typing import Optional, Sequence
from typing import Optional

from multiversx_sdk.core.constants import (TRANSACTION_MIN_GAS_PRICE,
TRANSACTION_OPTIONS_DEFAULT,
TRANSACTION_VERSION_DEFAULT)
from multiversx_sdk.core.interfaces import ITransaction


class Transaction:
Expand All @@ -22,9 +21,7 @@ def __init__(self,
options: Optional[int] = None,
guardian: Optional[str] = None,
signature: Optional[bytes] = None,
guardian_signature: Optional[bytes] = None,
relayer: Optional[str] = None,
inner_transactions: Optional[Sequence[ITransaction]] = None) -> None:
guardian_signature: Optional[bytes] = None) -> None:
self.chain_id = chain_id
self.sender = sender
self.receiver = receiver
Expand All @@ -44,8 +41,6 @@ def __init__(self,

self.guardian = guardian or ""
self.guardian_signature = guardian_signature or bytes()
self.relayer = relayer or ""
self.inner_transactions = inner_transactions or []

def __eq__(self, other: object) -> bool:
if not isinstance(other, Transaction):
Expand Down
8 changes: 0 additions & 8 deletions multiversx_sdk/core/transaction_computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,6 @@ def _to_dictionary(self, transaction: ITransaction, with_signature: bool = False
if transaction.guardian:
dictionary["guardian"] = transaction.guardian

if transaction.relayer:
dictionary["relayer"] = transaction.relayer

if len(transaction.inner_transactions):
dictionary["innerTransactions"] = [
self._to_dictionary(transaction=tx, with_signature=True) for tx in transaction.inner_transactions
]

return dictionary

def _dict_to_json(self, dictionary: Dict[str, Any]) -> bytes:
Expand Down
8 changes: 4 additions & 4 deletions multiversx_sdk/core/transaction_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ def test_compute_bytes_for_verifying_signature(self):
signature=tx.signature
)

assert is_signed_by_alice == True
assert is_signed_by_bob == False
assert is_signed_by_alice
assert is_signed_by_bob is False

def test_compute_bytes_for_verifying_transaction_signed_by_hash(self):
tx = Transaction(
Expand All @@ -343,5 +343,5 @@ def test_compute_bytes_for_verifying_transaction_signed_by_hash(self):
signature=tx.signature
)

assert is_signed_by_alice == True
assert is_signed_by_bob == False
assert is_signed_by_alice
assert is_signed_by_bob is False
Loading
Loading