/testing/unit/tp/account/test_genesis.py

https://github.com/Remmeauth/remme-core · Python · 193 lines · 134 code · 43 blank · 16 comment · 3 complexity · 11ee76ca492df64ccd4dafd5788082be MD5 · raw file

  1. """
  2. Provide tests for account handler (transfer) apply method implementation.
  3. """
  4. import time
  5. import pytest
  6. from sawtooth_sdk.processor.exceptions import InvalidTransaction
  7. from sawtooth_sdk.protobuf.processor_pb2 import TpProcessRequest
  8. from sawtooth_sdk.protobuf.transaction_pb2 import (
  9. Transaction,
  10. TransactionHeader,
  11. )
  12. from remme.protos.account_pb2 import (
  13. Account,
  14. AccountMethod,
  15. GenesisPayload,
  16. GenesisStatus,
  17. TransferPayload,
  18. )
  19. from remme.protos.transaction_pb2 import TransactionPayload
  20. from remme.shared.utils import hash512
  21. from remme.tp.account import AccountHandler
  22. from testing.conftest import create_signer
  23. from testing.mocks.stub import StubContext
  24. from testing.utils.client import proto_error_msg
  25. TOKENS_AMOUNT_TO_SUPPLY = 1_000_000
  26. TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS = {
  27. 'family_name': AccountHandler().family_name,
  28. 'family_version': AccountHandler()._family_versions[0],
  29. }
  30. GENESIS_ADDRESS = '0000000000000000000000000000000000000000000000000000000000000000000001'
  31. ACCOUNT_ADDRESS_TO= '112007d71fa7e120c60fb392a64fd69de891a60c667d9ea9e5d9d9d617263be6c20202'
  32. INPUTS = OUTPUTS = [
  33. GENESIS_ADDRESS,
  34. ACCOUNT_ADDRESS_TO,
  35. ]
  36. NODE_PUBLIC_KEY = '039d6881f0a71d05659e1f40b443684b93c7b7c504ea23ea8949ef5216a2236940'
  37. NODE_PRIVATE_KEY = '1cb15ecfe1b3dc02df0003ac396037f85b98cf9f99b0beae000dc5e9e8b6dab4'
  38. def test_account_handler_genesis_apply_with_empty_proto():
  39. """
  40. Case: send transaction request of genesis with empty proto
  41. Expect: invalid transaction error
  42. """
  43. genesis_payload = GenesisPayload()
  44. transaction_payload = TransactionPayload()
  45. transaction_payload.method = AccountMethod.GENESIS
  46. transaction_payload.data = genesis_payload.SerializeToString()
  47. serialized_transaction_payload = transaction_payload.SerializeToString()
  48. transaction_header = TransactionHeader(
  49. signer_public_key=NODE_PUBLIC_KEY,
  50. family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
  51. family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
  52. inputs=INPUTS,
  53. outputs=OUTPUTS,
  54. dependencies=[],
  55. payload_sha512=hash512(data=serialized_transaction_payload),
  56. batcher_public_key=NODE_PUBLIC_KEY,
  57. nonce=time.time().hex().encode(),
  58. )
  59. serialized_header = transaction_header.SerializeToString()
  60. transaction_request = TpProcessRequest(
  61. header=transaction_header,
  62. payload=serialized_transaction_payload,
  63. signature=create_signer(private_key=NODE_PRIVATE_KEY).sign(serialized_header),
  64. )
  65. mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={})
  66. with pytest.raises(InvalidTransaction) as error:
  67. AccountHandler().apply(transaction=transaction_request, context=mock_context)
  68. assert proto_error_msg(
  69. GenesisPayload,
  70. {'total_supply': ['This field is required.']}
  71. ) == str(error.value)
  72. def test_account_handler_genesis_apply():
  73. """
  74. Case: send transaction request, to send tokens from genesis address, to the account handler.
  75. Expect:
  76. """
  77. account = Account()
  78. account.balance = TOKENS_AMOUNT_TO_SUPPLY
  79. expected_serialized_account_to_balance = account.SerializeToString()
  80. genesis_payload = GenesisPayload()
  81. genesis_payload.total_supply = TOKENS_AMOUNT_TO_SUPPLY
  82. transaction_payload = TransactionPayload()
  83. transaction_payload.method = AccountMethod.GENESIS
  84. transaction_payload.data = genesis_payload.SerializeToString()
  85. serialized_transaction_payload = transaction_payload.SerializeToString()
  86. transaction_header = TransactionHeader(
  87. signer_public_key=NODE_PUBLIC_KEY,
  88. family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
  89. family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
  90. inputs=INPUTS,
  91. outputs=OUTPUTS,
  92. dependencies=[],
  93. payload_sha512=hash512(data=serialized_transaction_payload),
  94. batcher_public_key=NODE_PUBLIC_KEY,
  95. nonce=time.time().hex().encode(),
  96. )
  97. serialized_header = transaction_header.SerializeToString()
  98. transaction_request = TpProcessRequest(
  99. header=transaction_header,
  100. payload=serialized_transaction_payload,
  101. signature=create_signer(private_key=NODE_PRIVATE_KEY).sign(serialized_header),
  102. )
  103. genesis_status = GenesisStatus()
  104. genesis_status.status = True
  105. expected_state = {
  106. GENESIS_ADDRESS: genesis_status.SerializeToString(),
  107. ACCOUNT_ADDRESS_TO: expected_serialized_account_to_balance,
  108. }
  109. mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={})
  110. AccountHandler().apply(transaction=transaction_request, context=mock_context)
  111. state_as_list = mock_context.get_state(addresses=[GENESIS_ADDRESS, ACCOUNT_ADDRESS_TO])
  112. state_as_dict = {entry.address: entry.data for entry in state_as_list}
  113. assert expected_state == state_as_dict
  114. def test_account_handler_genesis_already_initialized():
  115. """
  116. Case: send transaction request, to send tokens from genesis address,
  117. to the account handler when genesis was already initialized.
  118. Expect: invalid transaction error is raised with genesis is already initialized error message.
  119. """
  120. genesis_payload = GenesisPayload()
  121. genesis_payload.total_supply = TOKENS_AMOUNT_TO_SUPPLY
  122. transaction_payload = TransactionPayload()
  123. transaction_payload.method = AccountMethod.GENESIS
  124. transaction_payload.data = genesis_payload.SerializeToString()
  125. serialized_transaction_payload = transaction_payload.SerializeToString()
  126. transaction_header = TransactionHeader(
  127. signer_public_key=NODE_PUBLIC_KEY,
  128. family_name=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_name'),
  129. family_version=TRANSACTION_REQUEST_ACCOUNT_HANDLER_PARAMS.get('family_version'),
  130. inputs=INPUTS,
  131. outputs=OUTPUTS,
  132. dependencies=[],
  133. payload_sha512=hash512(data=serialized_transaction_payload),
  134. batcher_public_key=NODE_PUBLIC_KEY,
  135. nonce=time.time().hex().encode(),
  136. )
  137. serialized_header = transaction_header.SerializeToString()
  138. transaction_request = TpProcessRequest(
  139. header=transaction_header,
  140. payload=serialized_transaction_payload,
  141. signature=create_signer(private_key=NODE_PRIVATE_KEY).sign(serialized_header),
  142. )
  143. genesis_status = GenesisStatus()
  144. genesis_status.status = True
  145. mock_context = StubContext(inputs=INPUTS, outputs=OUTPUTS, initial_state={
  146. GENESIS_ADDRESS: genesis_status.SerializeToString()
  147. })
  148. with pytest.raises(InvalidTransaction) as error:
  149. AccountHandler().apply(transaction=transaction_request, context=mock_context)
  150. assert f'Genesis is already initialized.' == str(error.value)