Skip to content

Commit

Permalink
Merge pull request #91 from xian-network/fix-state-stuff
Browse files Browse the repository at this point in the history
Add depth to context
  • Loading branch information
crosschainer authored Nov 4, 2024
2 parents bfc1f3e + 049d35d commit 1fe75d9
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 3 deletions.
11 changes: 11 additions & 0 deletions src/contracting/contracts/proxythis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@export
def proxythis(con: str):
return importlib.import_module(con).getthis()

@export
def nestedproxythis(con: str):
return importlib.import_module(con).nested_exported()

@export
def noproxy():
return ctx.this, ctx.caller
11 changes: 11 additions & 0 deletions src/contracting/contracts/thistest2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@export
def exported():
return ctx.this, ctx.caller

@export
def getthis():
return ctx.this, ctx.caller

@export
def nested_exported():
return exported()
15 changes: 12 additions & 3 deletions src/contracting/execution/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
class Context:
def __init__(self, base_state, maxlen=constants.RECURSION_LIMIT):
self._state = []
self._depth = []
self._base_state = base_state
self._maxlen = maxlen

Expand All @@ -25,13 +26,22 @@ def _get_state(self):
def _add_state(self, state: dict):
if self._context_changed(state['this']) and len(self._state) < self._maxlen:
self._state.append(state)
self._depth.append(1)

def _ins_state(self):
if len(self._depth) > 0:
self._depth[-1] += 1

def _pop_state(self):
if len(self._state) > 0:
self._state.pop(-1)
if len(self._state) > 0: #len(self._state) should equal len(self._depth)
self._depth[-1] -= 1
if self._depth[-1] == 0:
self._state.pop(-1)
self._depth.pop(-1)

def _reset(self):
self._state = []
self._depth = []

@property
def this(self):
Expand All @@ -57,7 +67,6 @@ def entry(self):
def submission_name(self):
return self._get_state()['submission_name']


_context = Context({
'this': None,
'caller': None,
Expand Down
2 changes: 2 additions & 0 deletions src/contracting/stdlib/bridge/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def __enter__(self, *args, **kwargs):

if state['owner'] is not None and state['owner'] != state['caller']:
raise Exception('Caller is not the owner!')
else:
rt.context._ins_state()

def __exit__(self, *args, **kwargs):
rt.context._pop_state()
Expand Down
77 changes: 77 additions & 0 deletions tests/test_state_management.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import unittest
from xian.processor import TxProcessor
from contracting.client import ContractingClient
from xian.services.simulator import Simulator
from xian.constants import Constants
import os
import pathlib
class MyTestCase(unittest.TestCase):

def setUp(self):
constants = Constants()
self.c = ContractingClient(storage_home=constants.STORAGE_HOME)
self.tx_processor = TxProcessor(client=self.c)
self.stamp_calculator = Simulator()
self.d = self.c.raw_driver
self.d.flush_full()

# Get the directory where the script is located
script_dir = os.path.dirname(os.path.abspath(__file__))

# Construct absolute paths for the contract files
submission_contract_path = os.path.abspath(
os.path.join(
script_dir,
"../../contracting/src/contracting/contracts/submission.s.py",
)
)

with open(submission_contract_path) as f:
contract = f.read()
self.d.set_contract(name="submission", code=contract)

def deploy_broken_stuff(self):
# Get the directory where the script is located
script_dir = os.path.dirname(os.path.abspath(__file__))

proxythis_path = os.path.abspath(
os.path.join(
script_dir,
"../../contracting/src/contracting/contracts/proxythis.py",
)
)
with open(proxythis_path) as f:
contract = f.read()

self.c.submit(
contract,
name="con_proxythis",
)

self.proxythis = self.c.get_contract("con_proxythis")

thistest2_path = os.path.abspath(
os.path.join(
script_dir,
"../../contracting/src/contracting/contracts/thistest2.py",
)
)

with open(thistest2_path) as f:
contract = f.read()

self.c.submit(
contract,
name="con_thistest2",
)

self.thistest2 = self.c.get_contract("con_thistest2")

def test_submit(self):
self.deploy_broken_stuff()
self.assertEqual(self.proxythis.proxythis(con="con_thistest2", signer="address"), ("con_thistest2", "con_proxythis"))
self.assertEqual(self.proxythis.noproxy(signer="address"), ("con_proxythis", "address"))
self.assertEqual(self.proxythis.nestedproxythis(con="con_thistest2", signer="address"), ("con_thistest2", "con_proxythis"))

if __name__ == '__main__':
unittest.main()

0 comments on commit 1fe75d9

Please sign in to comment.