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
39 changes: 32 additions & 7 deletions hathor/nanocontracts/resources/nc_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
from hathor.api_util import Resource, set_cors
from hathor.cli.openapi_files.register import register_resource
from hathor.manager import HathorManager
from hathor.nanocontracts.exception import NanoContractDoesNotExist
from hathor.nanocontracts.resources.on_chain import SortOrder
from hathor.nanocontracts.types import BlueprintId, VertexId
from hathor.transaction import Transaction
from hathor.transaction.storage.exceptions import TransactionDoesNotExist
from hathor.util import bytes_from_hex, collect_n, not_none
from hathor.utils.api import ErrorResponse, QueryParams, Response
Expand Down Expand Up @@ -136,8 +138,13 @@ def render_GET(self, request: Request) -> bytes:
)
iter_nc_ids = iter_getter2(tx_start=ref_tx)

iter_ncs = map(self._get_nc_creation_item_strict, iter_nc_ids)
nc_txs, has_more = collect_n(iter_ncs, params.count)
nc_id_txs, has_more = collect_n(iter_nc_ids, params.count)
nc_txs = []
for nc_id in nc_id_txs:
item = self._get_nc_creation_item(nc_id)
if item is not None:
nc_txs.append(item)

response = NCCreationResponse(
nc_creation_txs=nc_txs,
before=params.before,
Expand All @@ -147,7 +154,9 @@ def render_GET(self, request: Request) -> bytes:
)
return response.json_dumpb()

def _get_nc_creation_item(self, nc_id: bytes) -> NCCreationItem | None:
def _try_get_contract_creation_vertex(self, nc_id: bytes) -> Transaction | None:
"""Return a contract creation vertex if it exists. Otherwise, return None.
"""
try:
tx = self.tx_storage.get_transaction(nc_id)
except TransactionDoesNotExist:
Expand All @@ -156,16 +165,32 @@ def _get_nc_creation_item(self, nc_id: bytes) -> NCCreationItem | None:
if not tx.is_nano_contract():
return None

from hathor.transaction import Transaction
if not isinstance(tx, Transaction):
return None

nano_header = tx.get_nano_header()
if not nano_header.is_creating_a_new_contract():
return None

blueprint_id = BlueprintId(VertexId(nano_header.nc_id))
blueprint_class = self.tx_storage.get_blueprint_class(blueprint_id)
return tx

def _get_nc_creation_item(self, nc_id: bytes) -> NCCreationItem | None:
tx = self._try_get_contract_creation_vertex(nc_id)
if tx is not None:
nano_header = tx.get_nano_header()
blueprint_id = BlueprintId(VertexId(nano_header.nc_id))
blueprint_class = self.tx_storage.get_blueprint_class(blueprint_id)
created_at = tx.timestamp

else:
try:
nc_storage = self.manager.get_best_block_nc_storage(nc_id)
except NanoContractDoesNotExist:
return None

blueprint_id = nc_storage.get_blueprint_id()
blueprint_class = self.tx_storage.get_blueprint_class(blueprint_id)
created_at = 0

assert self.nc_history_index is not None
return NCCreationItem(
Expand All @@ -174,7 +199,7 @@ def _get_nc_creation_item(self, nc_id: bytes) -> NCCreationItem | None:
blueprint_name=blueprint_class.__name__,
last_tx_timestamp=not_none(self.nc_history_index.get_last_tx_timestamp(nc_id)),
total_txs=self.nc_history_index.get_transaction_count(nc_id),
created_at=tx.timestamp,
created_at=created_at,
)

def _get_nc_creation_item_strict(self, nc_id: bytes) -> NCCreationItem:
Expand Down
5 changes: 5 additions & 0 deletions tests/nanocontracts/test_blueprints/test_blueprint1.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ def initialize(self, ctx: Context, a: int) -> None:
@public
def nop(self, ctx: Context) -> None:
pass

@public
def create_child_contract(self, ctx: Context) -> None:
blueprint_id = self.syscall.get_blueprint_id()
self.syscall.create_contract(blueprint_id, b'', [], 0)
6 changes: 4 additions & 2 deletions tests/resources/nanocontracts/test_nc_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def prepare_ncs(self) -> tuple[Transaction, Transaction, Transaction, Transactio
password = unittest.OCB_TEST_PASSWORD.hex()
dag_builder = TestDAGBuilder.from_manager(self.manager)
artifacts = dag_builder.build_from_str(f'''
blockchain genesis b[1..11]
blockchain genesis b[1..12]
b10 < dummy

ocb1.ocb_private_key = "{private_key}"
Expand All @@ -72,6 +72,8 @@ def prepare_ncs(self) -> tuple[Transaction, Transaction, Transaction, Transactio
ocb1 <-- ocb2 <-- b11
b11 < nc1 < nc2 < nc3 < nc4 < nc5

nc1 <-- nc2 <-- nc3 <-- nc4 <-- nc5 <-- b12

ocb1.ocb_code = "{bet_code.encode().hex()}"
ocb2.ocb_code = ```
from hathor import Blueprint, Context, export, public
Expand Down Expand Up @@ -150,7 +152,7 @@ async def test_tx_aggregation(self) -> None:
nc2.nc_method = initialize(0)

nc3.nc_id = nc2
nc3.nc_method = nop()
nc3.nc_method = create_child_contract()

nc4.nc_id = nc1
nc4.nc_method = nop()
Expand Down