genlayer-test 0.6.0__py3-none-any.whl → 0.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: genlayer-test
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: GenLayer Testing Suite
5
5
  Author: GenLayer
6
6
  License-Expression: MIT
@@ -1,4 +1,4 @@
1
- genlayer_test-0.6.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
1
+ genlayer_test-0.7.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
2
2
  gltest/__init__.py,sha256=qoBV3IgDJr8uh9262XsWNMhi-ilkSgMqKVC9FVMk7cw,372
3
3
  gltest/accounts.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
4
4
  gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
@@ -6,16 +6,16 @@ gltest/clients.py,sha256=1dX6wmG3QCevQRLbSaFlHymZSb-sJ5aYwet1IoX2nbA,1554
6
6
  gltest/exceptions.py,sha256=deJPmrTe5gF33qkkKF2IVJY7lc_knI7Ql3N7jZ8aLZs,510
7
7
  gltest/fixtures.py,sha256=EJXmqcC3LD03v07mepacFl58lAdhbLj6bP5rtALYISk,2507
8
8
  gltest/logging.py,sha256=jAkHsuMm-AEx1Xu1srU6W-0YzTwXJB48mCK-OVzAiN4,342
9
- gltest/types.py,sha256=Kj6UuTpRXkA4c5ystKfwgXuCiRJ1VMkbgvP7Auvznhw,184
9
+ gltest/types.py,sha256=LJogYw6jQGoZnmE9Kx-YjNBRHWe3-mGsVIFP6R-zwSw,636
10
10
  gltest/utils.py,sha256=-gHhjrS7i_GhDG3sKOq2qsTtYBt4HHgXHEXh-3RB_rI,573
11
11
  gltest/artifacts/__init__.py,sha256=qTt3TE19gVNWnQLUlt5aDe4nNvJ2YJ1jzDkMmYIsCG0,194
12
12
  gltest/artifacts/contract.py,sha256=KChpmfjZod_0dVB8y-dvWz6IVm7QlIJsgG2ArtvVDaU,6457
13
13
  gltest/contracts/__init__.py,sha256=A9bvEtYOoqoHS8TLlFBfmNOnfwdsJPEf-AZuikagCHM,166
14
- gltest/contracts/contract.py,sha256=hYuugaV_gNFk58mGyLRPKkKVKIjsCDlVpKLvwRBf7sM,6743
15
- gltest/contracts/contract_factory.py,sha256=SCmhp2DRfD8FRejOqa6-_UF-yJaJr0ShB9lDkLLBzU0,8264
16
- gltest/contracts/contract_functions.py,sha256=5gNQYzN47rCJtmcMtUkl4ZK-yDifdZup2YhtlFlrx7E,2203
14
+ gltest/contracts/contract.py,sha256=jLF_ojSM6IIbdGO2_DhsO79r2wZ2Z8eBAJRrZk2qVTI,7748
15
+ gltest/contracts/contract_factory.py,sha256=PpWh4mKf1hDMv_yms5lwFV_EoXxXiuNfdXbwD74hbAU,8929
16
+ gltest/contracts/contract_functions.py,sha256=W6Dpw1z-n9EeJxlNtIbeVnzpv4BPABhtgmgjnS8-P0w,2573
17
17
  gltest/contracts/method_stats.py,sha256=zWWjvf7K5VC4yrHpDIR717VF7LYp1RaZ1Hr_RZvWxJA,5150
18
- gltest/contracts/stats_collector.py,sha256=fuCc8L8hd0tsVGzH4adtZWwPa7ORf0A0zR5Dt1w92Qk,9033
18
+ gltest/contracts/stats_collector.py,sha256=iwsnoYo5aZbI4SVMH7dR-5CQgkglExXfsvaUDpwcdss,9286
19
19
  gltest/contracts/utils.py,sha256=TTXgcXn9BuRIlKJrjwmU7R3l1IgXsXk2luM-r3lfbbg,296
20
20
  gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,180
21
21
  gltest/helpers/fixture_snapshot.py,sha256=bMgvlEVQBGIQzj7NOyosXWlphI1H2C1o75Zo0C-kGfQ,1931
@@ -40,6 +40,7 @@ tests/examples/contracts/log_indexer.py,sha256=Nlf8XUt13ujam3k6hbbVrPHK-KJ366Csz
40
40
  tests/examples/contracts/multi_read_erc20.py,sha256=28qYqn191Ro3rP7YJtZwL6Sc7JDXTeh8_QoqvdVPdqM,864
41
41
  tests/examples/contracts/multi_tenant_storage.py,sha256=ceq3X4E7pkvSdy7eQMhAoHme4KFedjAcpkfUYBmcgVM,1941
42
42
  tests/examples/contracts/read_erc20.py,sha256=RgH269F0x482WuLLYcacBnZsGJjhgJp6sG_33cV6Z-w,454
43
+ tests/examples/contracts/simple_time_contract.py,sha256=-9p_umlzUW5X2NL6IknO6Khs_114izSWifP5D2bWCMo,2512
43
44
  tests/examples/contracts/storage.py,sha256=3DD3qvzb0JkVcBtu240e5kaZWgkh-bu6YExqBUYvfaw,501
44
45
  tests/examples/contracts/user_storage.py,sha256=2W2Iv-hQZMkAaPl2RY_F-OeJpD4IlPxgWzN6e1bTkKE,649
45
46
  tests/examples/contracts/wizard_of_coin.py,sha256=Y8daPpoSKdM8wfbCPOIgEdpkLIA1ZMmeg6Hu5fBB-kU,1624
@@ -49,12 +50,13 @@ tests/examples/tests/test_football_prediction_market.py,sha256=f2hfDK76WrNJZtFkT
49
50
  tests/examples/tests/test_intelligent_oracle_factory.py,sha256=sL26aeb84XpJPCSUSIX3yrbwQE8GZtvNcsaKTpngFmY,7611
50
51
  tests/examples/tests/test_invalid_deploy.py,sha256=pppM8_Vn4DXcWq9iyJXb0SpZnKXkIyJxoIDW5ApCS94,814
51
52
  tests/examples/tests/test_llm_erc20.py,sha256=zb5F_7NgvZXhvqL2nULwzuTT6LGDprSy0WgrdjY7pZc,2096
52
- tests/examples/tests/test_llm_erc20_analyze.py,sha256=ccWQenEOG-U4TJdu-0i-3qNM4xRRCHSr3Iwz7pxknws,1729
53
+ tests/examples/tests/test_llm_erc20_analyze.py,sha256=rVnC3iQW_1J3P6cczEVOOG84K6ldCzlZbMO9WXQdRds,1849
53
54
  tests/examples/tests/test_log_indexer.py,sha256=46AqL7qquNc9GX2wxFxVcQXLqruMnPmxXl1yeB0-KZ4,2869
54
55
  tests/examples/tests/test_multi_file_contract.py,sha256=1Emj6ze4f-OrpxvqExeJhPHjK0cNAQW54MXf6fy2Yuc,469
55
56
  tests/examples/tests/test_multi_read_erc20.py,sha256=pSZUxoB33Z2EBtcvXxfUgwGSi_h7ryPoovkiNIfNAVQ,3713
56
57
  tests/examples/tests/test_multi_tenant_storage.py,sha256=8B3tjnRbT8ATN5obtWkGsN3nOtBU9OSjuaH9aEat3vc,2935
57
58
  tests/examples/tests/test_read_erc20.py,sha256=vLGQwguaNnT497nSq-vt4LrXj4ehn5ZSgfPt0GVFoPc,1254
59
+ tests/examples/tests/test_simple_time_contract.py,sha256=HQCJNheFyaHh73jZHyGOhNItzg045o8XsW-jLnNp-xc,3199
58
60
  tests/examples/tests/test_storage.py,sha256=y46nPjM-Jd9FVJmaNE29RPqamzxVwYtPPWE_GlXUsls,774
59
61
  tests/examples/tests/test_user_storage.py,sha256=wk0r0AXfKNgI7Eeyc8noNlJKvZBFXDbXTQE_u19XxBQ,2927
60
62
  tests/examples/tests/test_wizard_of_coin.py,sha256=AOQTanDsfZt9zIGkqZass_4BsGcVKTHzqRejN4KhSPI,854
@@ -70,8 +72,8 @@ tests/gltest_cli/config/test_config_integration.py,sha256=vPTzr3_h9UMw7m72HogBJE
70
72
  tests/gltest_cli/config/test_general_config.py,sha256=UHtSwVnso-ZwNtYM0Z4v2sCLKwyrVbHlk6b1leVfV84,14703
71
73
  tests/gltest_cli/config/test_plugin.py,sha256=COrEK5tHP1BSzanWbZHmN3EQgE9VuTcPvB95pgOvKS4,7974
72
74
  tests/gltest_cli/config/test_user.py,sha256=JxR655oUFoM9quWQO68CVPKRpT0TMpzS3bF6j6NWyT4,14401
73
- genlayer_test-0.6.0.dist-info/METADATA,sha256=uHgafSUvII1G16UbdZ-26QwmtaV86EX1Pk-VwXsZAxs,32466
74
- genlayer_test-0.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
75
- genlayer_test-0.6.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
76
- genlayer_test-0.6.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
77
- genlayer_test-0.6.0.dist-info/RECORD,,
75
+ genlayer_test-0.7.0.dist-info/METADATA,sha256=o89bAkGCyeJbcOUVD1ElUDG37zLVClakUp3tvs6oKsc,32466
76
+ genlayer_test-0.7.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
77
+ genlayer_test-0.7.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
78
+ genlayer_test-0.7.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
79
+ genlayer_test-0.7.0.dist-info/RECORD,,
@@ -7,7 +7,9 @@ from gltest.types import (
7
7
  GenLayerTransaction,
8
8
  TransactionStatus,
9
9
  TransactionHashVariant,
10
+ TransactionContext,
10
11
  )
12
+ from genlayer_py.types import SimConfig
11
13
  from typing import List, Any, Optional, Dict, Callable
12
14
  from gltest_cli.config.general import get_general_config
13
15
  from .contract_functions import ContractFunction
@@ -25,14 +27,24 @@ def read_contract_wrapper(
25
27
 
26
28
  def call_method(
27
29
  transaction_hash_variant: TransactionHashVariant = TransactionHashVariant.LATEST_NONFINAL,
30
+ transaction_context: Optional[TransactionContext] = None,
28
31
  ):
29
32
  client = get_gl_client()
33
+ sim_config = None
34
+ if transaction_context:
35
+ try:
36
+ sim_config = SimConfig(**transaction_context)
37
+ except TypeError as e:
38
+ raise ValueError(
39
+ f"Invalid transaction_context keys: {sorted(transaction_context.keys())}"
40
+ ) from e
30
41
  return client.read_contract(
31
42
  address=self.address,
32
43
  function_name=method_name,
33
44
  account=self.account,
34
45
  args=args,
35
46
  transaction_hash_variant=transaction_hash_variant,
47
+ sim_config=sim_config,
36
48
  )
37
49
 
38
50
  return ContractFunction(
@@ -59,6 +71,7 @@ def write_contract_wrapper(
59
71
  wait_retries: Optional[int] = None,
60
72
  wait_triggered_transactions: bool = False,
61
73
  wait_triggered_transactions_status: TransactionStatus = TransactionStatus.ACCEPTED,
74
+ transaction_context: Optional[TransactionContext] = None,
62
75
  ):
63
76
  """
64
77
  Transact the contract method.
@@ -80,6 +93,14 @@ def write_contract_wrapper(
80
93
  else False
81
94
  )
82
95
  client = get_gl_client()
96
+ sim_config = None
97
+ if transaction_context:
98
+ try:
99
+ sim_config = SimConfig(**transaction_context)
100
+ except TypeError as e:
101
+ raise ValueError(
102
+ f"Invalid transaction_context keys: {sorted(transaction_context.keys())}"
103
+ ) from e
83
104
  tx_hash = client.write_contract(
84
105
  address=self.address,
85
106
  function_name=method_name,
@@ -88,6 +109,7 @@ def write_contract_wrapper(
88
109
  consensus_max_rotations=consensus_max_rotations,
89
110
  leader_only=leader_only,
90
111
  args=args,
112
+ sim_config=sim_config,
91
113
  )
92
114
  receipt = client.wait_for_transaction_receipt(
93
115
  transaction_hash=tx_hash,
@@ -113,6 +135,7 @@ def write_contract_wrapper(
113
135
  plugin: Optional[str] = None,
114
136
  plugin_config: Optional[Dict[str, Any]] = None,
115
137
  runs: int = 100,
138
+ genvm_datetime: Optional[str] = None,
116
139
  ):
117
140
  """
118
141
  Analyze the contract method using StatsCollector.
@@ -129,6 +152,7 @@ def write_contract_wrapper(
129
152
  config=config,
130
153
  plugin=plugin,
131
154
  plugin_config=plugin_config,
155
+ genvm_datetime=genvm_datetime,
132
156
  )
133
157
  sim_results = collector.run_simulations(sim_config, runs)
134
158
  return collector.analyze_results(sim_results, runs, sim_config)
@@ -15,6 +15,7 @@ from gltest.clients import (
15
15
  get_gl_hosted_studio_client,
16
16
  get_local_client,
17
17
  )
18
+ from genlayer_py.types import SimConfig
18
19
  from .contract import Contract
19
20
  from gltest.logging import logger
20
21
  from gltest.types import TransactionStatus, GenLayerTransaction, CalldataEncodable
@@ -22,6 +23,7 @@ from gltest.assertions import tx_execution_failed
22
23
  from gltest.exceptions import DeploymentError
23
24
  from gltest_cli.config.general import get_general_config
24
25
  from gltest.utils import extract_contract_address
26
+ from gltest.types import TransactionContext
25
27
 
26
28
 
27
29
  @dataclass
@@ -113,6 +115,7 @@ class ContractFactory:
113
115
  wait_transaction_status: TransactionStatus = TransactionStatus.ACCEPTED,
114
116
  wait_triggered_transactions: bool = False,
115
117
  wait_triggered_transactions_status: TransactionStatus = TransactionStatus.ACCEPTED,
118
+ transaction_context: Optional[TransactionContext] = None,
116
119
  ) -> Contract:
117
120
  """
118
121
  Deploy the contract and return a Contract instance (convenience method).
@@ -129,6 +132,7 @@ class ContractFactory:
129
132
  wait_transaction_status=wait_transaction_status,
130
133
  wait_triggered_transactions=wait_triggered_transactions,
131
134
  wait_triggered_transactions_status=wait_triggered_transactions_status,
135
+ transaction_context=transaction_context,
132
136
  )
133
137
 
134
138
  if tx_execution_failed(receipt):
@@ -147,6 +151,7 @@ class ContractFactory:
147
151
  wait_transaction_status: TransactionStatus = TransactionStatus.ACCEPTED,
148
152
  wait_triggered_transactions: bool = False,
149
153
  wait_triggered_transactions_status: TransactionStatus = TransactionStatus.ACCEPTED,
154
+ transaction_context: Optional[TransactionContext] = None,
150
155
  ) -> GenLayerTransaction:
151
156
  """
152
157
  Deploy the contract and return the transaction receipt.
@@ -170,12 +175,21 @@ class ContractFactory:
170
175
 
171
176
  client = get_gl_client()
172
177
  try:
178
+ sim_config = None
179
+ if transaction_context:
180
+ try:
181
+ sim_config = SimConfig(**transaction_context)
182
+ except TypeError as e:
183
+ raise ValueError(
184
+ f"Invalid transaction_context keys: {sorted(transaction_context.keys())}"
185
+ ) from e
173
186
  tx_hash = client.deploy_contract(
174
187
  code=self.contract_code,
175
188
  args=args,
176
189
  account=account,
177
190
  consensus_max_rotations=consensus_max_rotations,
178
191
  leader_only=leader_only,
192
+ sim_config=sim_config,
179
193
  )
180
194
  tx_receipt = client.wait_for_transaction_receipt(
181
195
  transaction_hash=tx_hash,
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Callable, Optional, Dict, Any
3
- from gltest.types import TransactionStatus, TransactionHashVariant
3
+ from gltest.types import TransactionStatus, TransactionHashVariant, TransactionContext
4
4
 
5
5
 
6
6
  @dataclass
@@ -14,10 +14,14 @@ class ContractFunction:
14
14
  def call(
15
15
  self,
16
16
  transaction_hash_variant: TransactionHashVariant = TransactionHashVariant.LATEST_NONFINAL,
17
+ transaction_context: Optional[TransactionContext] = None,
17
18
  ):
18
19
  if not self.read_only:
19
20
  raise ValueError("call() not implemented for non-readonly method")
20
- return self.call_method(transaction_hash_variant=transaction_hash_variant)
21
+ return self.call_method(
22
+ transaction_hash_variant=transaction_hash_variant,
23
+ transaction_context=transaction_context,
24
+ )
21
25
 
22
26
  def transact(
23
27
  self,
@@ -28,6 +32,7 @@ class ContractFunction:
28
32
  wait_retries: Optional[int] = None,
29
33
  wait_triggered_transactions: bool = False,
30
34
  wait_triggered_transactions_status: TransactionStatus = TransactionStatus.ACCEPTED,
35
+ transaction_context: Optional[TransactionContext] = None,
31
36
  ):
32
37
  if self.read_only:
33
38
  raise ValueError("Cannot transact read-only method")
@@ -39,6 +44,7 @@ class ContractFunction:
39
44
  wait_retries=wait_retries,
40
45
  wait_triggered_transactions=wait_triggered_transactions,
41
46
  wait_triggered_transactions_status=wait_triggered_transactions_status,
47
+ transaction_context=transaction_context,
42
48
  )
43
49
 
44
50
  def analyze(
@@ -49,6 +55,7 @@ class ContractFunction:
49
55
  plugin: Optional[str] = None,
50
56
  plugin_config: Optional[Dict[str, Any]] = None,
51
57
  runs: int = 100,
58
+ genvm_datetime: Optional[str] = None,
52
59
  ):
53
60
  if self.read_only:
54
61
  raise ValueError("Cannot analyze read-only method")
@@ -59,4 +66,5 @@ class ContractFunction:
59
66
  plugin=plugin,
60
67
  plugin_config=plugin_config,
61
68
  runs=runs,
69
+ genvm_datetime=genvm_datetime,
62
70
  )
@@ -29,6 +29,7 @@ class SimulationConfig:
29
29
  config: Optional[Dict[str, Any]] = None
30
30
  plugin: Optional[str] = None
31
31
  plugin_config: Optional[Dict[str, Any]] = None
32
+ genvm_datetime: Optional[str] = None
32
33
 
33
34
 
34
35
  @dataclass
@@ -103,7 +104,12 @@ class StatsCollector:
103
104
  self, sim_config: SimulationConfig
104
105
  ) -> Dict[str, Any]:
105
106
  """Execute a single simulation."""
106
- config_dict = {
107
+ config_dict = {}
108
+
109
+ if sim_config.genvm_datetime is not None:
110
+ config_dict["genvm_datetime"] = sim_config.genvm_datetime
111
+
112
+ validator_info = {
107
113
  "provider": sim_config.provider,
108
114
  "model": sim_config.model,
109
115
  }
@@ -113,9 +119,10 @@ class StatsCollector:
113
119
  and sim_config.plugin is not None
114
120
  and sim_config.plugin_config is not None
115
121
  ):
116
- config_dict["config"] = sim_config.config
117
- config_dict["plugin"] = sim_config.plugin
118
- config_dict["plugin_config"] = sim_config.plugin_config
122
+ validator_info["config"] = sim_config.config
123
+ validator_info["plugin"] = sim_config.plugin
124
+ validator_info["plugin_config"] = sim_config.plugin_config
125
+ config_dict["validators"] = [validator_info]
119
126
 
120
127
  return self.client.simulate_write_contract(
121
128
  address=self.contract_address,
gltest/types.py CHANGED
@@ -6,3 +6,21 @@ from genlayer_py.types import (
6
6
  CalldataEncodable,
7
7
  TransactionHashVariant,
8
8
  )
9
+ from typing import List, TypedDict, Dict, Any
10
+
11
+
12
+ class ValidatorConfig(TypedDict):
13
+ """Validator information."""
14
+
15
+ provider: str
16
+ model: str
17
+ config: Dict[str, Any]
18
+ plugin: str
19
+ plugin_config: Dict[str, Any]
20
+
21
+
22
+ class TransactionContext(TypedDict, total=False):
23
+ """Context for consensus operations."""
24
+
25
+ validators: List[ValidatorConfig] # List to create virtual validators
26
+ genvm_datetime: str # ISO format datetime string
@@ -0,0 +1,85 @@
1
+ # {
2
+ # "Seq": [
3
+ # { "Depends": "py-lib-genlayer-embeddings:09h0i209wrzh4xzq86f79c60x0ifs7xcjwl53ysrnw06i54ddxyi" },
4
+ # { "Depends": "py-genlayer:1j12s63yfjpva9ik2xgnffgrs6v44y1f52jvj9w7xvdn7qckd379" }
5
+ # ]
6
+ # }
7
+
8
+ from datetime import datetime, timezone
9
+ from genlayer import *
10
+
11
+
12
+ class SimpleTimeContract(gl.Contract):
13
+ """
14
+ A simple contract that demonstrates time-based function availability.
15
+ """
16
+
17
+ start_date: str # ISO format datetime string
18
+ data: str
19
+ is_active: bool
20
+
21
+ def __init__(self, start_datetime_iso: str):
22
+ """
23
+ Initialize the contract with a required start date (ISO 8601).
24
+ """
25
+ self.start_date = start_datetime_iso
26
+ self.is_active = False
27
+ self.data = ""
28
+
29
+ def _days_since_start(self) -> int:
30
+ """Calculate days elapsed since start date."""
31
+ current = datetime.now(timezone.utc)
32
+ start = datetime.fromisoformat(self.start_date)
33
+ print(f"Current: {current}, Start: {start}")
34
+ delta = current - start
35
+ print(f"Delta: {delta}")
36
+ return delta.days
37
+
38
+ @gl.public.write
39
+ def activate(self):
40
+ """
41
+ Activate the contract.
42
+ Only works if current date is after start date.
43
+ """
44
+ days = self._days_since_start()
45
+
46
+ if days < 0:
47
+ raise ValueError(
48
+ f"Cannot activate before start date. Days until start: {abs(days)}"
49
+ )
50
+
51
+ self.is_active = True
52
+
53
+ @gl.public.write
54
+ def set_data(self, value: str):
55
+ """
56
+ Set data in the contract.
57
+ Only works if contract is active and within 30 days of start.
58
+ """
59
+ if not self.is_active:
60
+ raise ValueError("Contract must be activated first")
61
+
62
+ days = self._days_since_start()
63
+
64
+ if days > 30:
65
+ raise ValueError(
66
+ f"Function expired. Was available for 30 days after start, now at day {days}"
67
+ )
68
+
69
+ self.data = value
70
+
71
+ @gl.public.view
72
+ def get_status(self) -> dict:
73
+ """Get current contract status."""
74
+ days = self._days_since_start()
75
+ current = datetime.now(timezone.utc)
76
+
77
+ return {
78
+ "start_date": self.start_date,
79
+ "current_time": current.isoformat(),
80
+ "days_since_start": days,
81
+ "is_active": self.is_active,
82
+ "data": self.data,
83
+ "can_activate": days >= 0 and not self.is_active,
84
+ "can_set_data": self.is_active and 0 <= days <= 30,
85
+ }
@@ -1,4 +1,5 @@
1
1
  from gltest import get_contract_factory, get_default_account, create_account
2
+ from datetime import datetime, timezone
2
3
 
3
4
 
4
5
  TOKEN_TOTAL_SUPPLY = 1000
@@ -21,7 +22,10 @@ def test_llm_erc20_analyze(setup_validators):
21
22
 
22
23
  # Transfer from User A to User B
23
24
  stats = contract.transfer(args=[TRANSFER_AMOUNT, from_account_b.address]).analyze(
24
- provider="openai", model="gpt-4o", runs=3
25
+ provider="openai",
26
+ model="gpt-4o",
27
+ runs=3,
28
+ genvm_datetime=datetime.now(timezone.utc).isoformat(),
25
29
  )
26
30
 
27
31
  # Verify it's a MethodStatsSummary object
@@ -0,0 +1,90 @@
1
+ from gltest import get_contract_factory
2
+ from datetime import datetime, timedelta, timezone
3
+ from gltest.assertions import tx_execution_succeeded, tx_execution_failed
4
+
5
+
6
+ def test_simple_time_contract():
7
+ """Test all time-based functionality in a single comprehensive test."""
8
+
9
+ factory = get_contract_factory("SimpleTimeContract")
10
+
11
+ # Test 1: Deploy with past start date (10 days ago)
12
+ now = datetime.now(timezone.utc)
13
+ past_date = (now - timedelta(days=10)).isoformat()
14
+ contract = factory.deploy(args=[past_date])
15
+
16
+ # Test 1: Check initial status (10 days after start)
17
+ status = contract.get_status().call()
18
+ assert status["is_active"] == False
19
+ assert status["days_since_start"] == 10
20
+ assert status["can_activate"] == True
21
+
22
+ # Test 2: Try to activate before start date (simulate going back in time)
23
+ before_start_date = now - timedelta(days=15) # 5 days before start
24
+ before_start_date_receipt = contract.activate().transact(
25
+ transaction_context={
26
+ "genvm_datetime": before_start_date.isoformat(),
27
+ },
28
+ )
29
+ assert tx_execution_failed(before_start_date_receipt)
30
+
31
+ # Test 3: Activate after start date
32
+ activate_date = now - timedelta(days=5) # 5 days after start (15 days ago + 10)
33
+ activate_receipt = contract.activate().transact(
34
+ transaction_context={
35
+ "genvm_datetime": activate_date.isoformat(),
36
+ },
37
+ )
38
+ assert tx_execution_succeeded(activate_receipt)
39
+
40
+ # Test 4: Verify activation and check status
41
+ status = contract.get_status().call(
42
+ transaction_context={
43
+ "genvm_datetime": activate_date.isoformat(),
44
+ },
45
+ )
46
+ assert status["is_active"] == True
47
+ assert status["days_since_start"] == 5
48
+ assert status["can_set_data"] == True
49
+
50
+ # Test 5: Set data within valid period (within 30 days)
51
+ set_data_date = now - timedelta(days=2) # 8 days after start
52
+ test_data = "Test data within valid period"
53
+ set_data_receipt = contract.set_data(
54
+ args=[test_data],
55
+ ).transact(
56
+ transaction_context={
57
+ "genvm_datetime": set_data_date.isoformat(),
58
+ }
59
+ )
60
+ assert tx_execution_succeeded(set_data_receipt)
61
+
62
+ # Test 6: Verify data was set
63
+ status = contract.get_status().call(
64
+ transaction_context={
65
+ "genvm_datetime": set_data_date.isoformat(),
66
+ },
67
+ )
68
+ assert status["data"] == test_data
69
+ assert status["days_since_start"] == 8
70
+
71
+ # Test 7: Try to set data after 30 days (should fail)
72
+ expired_date = now + timedelta(days=25) # 35 days after start
73
+ expired_date_receipt = contract.set_data(
74
+ args=["Should fail - expired"],
75
+ ).transact(
76
+ transaction_context={
77
+ "genvm_datetime": expired_date.isoformat(),
78
+ }
79
+ )
80
+ assert tx_execution_failed(expired_date_receipt)
81
+
82
+ # Test 8: Check status shows expired
83
+ status = contract.get_status().call(
84
+ transaction_context={
85
+ "genvm_datetime": expired_date.isoformat(),
86
+ },
87
+ )
88
+ assert status["is_active"] == True # Still active
89
+ assert status["can_set_data"] == False # But can't set data
90
+ assert status["days_since_start"] == 35