-
Notifications
You must be signed in to change notification settings - Fork 11
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
Week 06 #43
Merged
Merged
Week 06 #43
Changes from 79 commits
Commits
Show all changes
84 commits
Select commit
Hold shift + click to select a range
8aae2ec
create lecture dir with negative r timed
juliusfrost b2fd4f2
create mock chain context and mock user
juliusfrost b7ed9f9
attempt to use code from script context builder to evaluate script
juliusfrost bcc20b0
Fix data generation
nielstron d857c38
make pyaiken optional
juliusfrost 4f94168
install all optional dependencies in the test workflow
juliusfrost 782f834
create pyaiken extra dependency
juliusfrost 51615cc
update poetry.lock
juliusfrost 5182718
use default max tx memsteps and max tx cpu steps
juliusfrost c83368c
Add some logic to generate the tx context from the tx and context alone
nielstron e3b9318
Attach script to tx, catch iteration error
nielstron 49aedda
Formatting, do not attach script in UTxO
nielstron 47a9b4a
Handle UTxO attached scripts
nielstron 0ba761f
Small fix
nielstron 62fcf5a
Take into account all scripts from all inputs
nielstron 8cd7be7
Restructuring
nielstron 8d59746
Set execution steps to maximum if 0 and should_estimate
nielstron da485cd
Print script debug logs a bit nicer
nielstron 1039eb0
Remove unused mockcontext creator
nielstron 529f113
Fix redeemer assignment
nielstron 8b7752c
Fix consumed vs avail cpu
nielstron 8abbaff
use correct submit methods
juliusfrost 81e0400
fix redeemer list
juliusfrost 1f8c5b8
use pycardano main branch with fixes until 0.9.0
juliusfrost 7bb5c5a
fix submit_tx call
juliusfrost a2629d4
fix context.utxos
juliusfrost e552cae
fix parameter order and make redeemer purpose
juliusfrost 3dd39fa
Make bytes actually bytes
nielstron 1839094
use pycardano serialization fix
juliusfrost 1efdcc6
add posix time conversion methods
juliusfrost b59f5ac
fix property tests
juliusfrost a3c23d7
fix dependency installation step
juliusfrost 1e8c60b
keep extras installed
juliusfrost 3866fb1
update pycardano
juliusfrost 8882c52
only build script once
juliusfrost 573746f
cache unflat
juliusfrost 5cd7ddf
update pyaiken and hypothesis, add pytest-xdist
juliusfrost cd5950e
use maximum cores for pytest
juliusfrost 82e7760
use python 3.11 to run tests
juliusfrost f48e607
require python 3.9+ for newest features
juliusfrost 1b90b9c
reset cache
juliusfrost 468c375
test remove hypothesis deadline
juliusfrost e063144
create exploitable_swap.py
juliusfrost 0d5725a
add compile test
juliusfrost 8d72380
add unit tests
juliusfrost b121521
A very simple setup to invoke the actual python script when submitting
nielstron a2b8614
Merge pull request #48 from OpShin/feat/invoke_opshin_script_when_bui…
juliusfrost a37e25f
black format
juliusfrost bdb28e1
catch assertion error for opshin validator
juliusfrost 8dc70ab
refactor transactions into individual methods
juliusfrost 5c3d5a3
fix context hash, add arbitrary user funds
juliusfrost 28d1880
Revert "test remove hypothesis deadline"
juliusfrost 0c96f87
Fix minting and spending redeemer
nielstron ab4e2e9
fix hash (again)
juliusfrost 1b4cea2
Merge branch 'week06' of https://github.com/OpShin/opshin-pioneer-pro…
juliusfrost 6e657ee
Fix reported step usage in new pyaiken version
nielstron dc5f554
remove unused import
juliusfrost 4b4d8b0
init homework test
juliusfrost f8ab967
fix multiasset
juliusfrost 2698768
add missing minting datum
juliusfrost bc516de
correct hash
juliusfrost 15daaf3
use deepcopy and single setup, use methods instead of module for opsh…
juliusfrost 1f62e90
add callable arguments (force 3)
juliusfrost b010cf3
fix hw test validator
juliusfrost 8416b0b
use single cached setup
juliusfrost ce28144
fix hw tests
juliusfrost 5fcc3be
speed up typeguard with PYTHONOPTIMIZE=2
juliusfrost 8dc7679
set PYTHONOPTIMIZE=1 to pass tests
juliusfrost 5aac5f6
Revert "set PYTHONOPTIMIZE=1 to pass tests"
juliusfrost db37f83
Revert "speed up typeguard with PYTHONOPTIMIZE=2"
juliusfrost 1663954
add double spending test
juliusfrost be3eefb
typo
juliusfrost 7247ae1
create and test fixed_swap_solution.py
juliusfrost d1387c3
rename test
juliusfrost 9f5a1e9
add homework template
juliusfrost 67315f3
catch value error
juliusfrost 8eaae06
compile test, rename to solved
juliusfrost 50973b0
create test mock to introduce the mock api
juliusfrost 305d5c2
week06 instructions
juliusfrost 68b0f53
Merge branch 'main' into week06
juliusfrost 659268c
remove week06 solutions
juliusfrost b972aa0
instructions for installing pyaiken
juliusfrost 89f67f6
update pre-commit
juliusfrost f8c91cd
update dependencies
juliusfrost File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
from collections import defaultdict | ||
from typing import Any, Callable, Dict, List, Optional, Union | ||
|
||
from pycardano import ( | ||
Address, | ||
ChainContext, | ||
ExecutionUnits, | ||
GenesisParameters, | ||
Network, | ||
PaymentSigningKey, | ||
PaymentVerificationKey, | ||
ProtocolParameters, | ||
ScriptType, | ||
Transaction, | ||
TransactionId, | ||
TransactionInput, | ||
TransactionOutput, | ||
UTxO, | ||
Value, | ||
) | ||
|
||
from src.utils.protocol_params import ( | ||
DEFAULT_GENESIS_PARAMETERS, | ||
DEFAULT_PROTOCOL_PARAMETERS, | ||
) | ||
from src.utils.tx_tools import evaluate_script, generate_script_contexts_resolved | ||
|
||
|
||
class MockChainContext(ChainContext): | ||
def __init__( | ||
self, | ||
protocol_param: Optional[ProtocolParameters] = None, | ||
genesis_param: Optional[GenesisParameters] = None, | ||
): | ||
self._protocol_param = ( | ||
protocol_param if protocol_param else DEFAULT_PROTOCOL_PARAMETERS | ||
) | ||
self._genesis_param = ( | ||
genesis_param if genesis_param else DEFAULT_GENESIS_PARAMETERS | ||
) | ||
self._utxo_state: Dict[str, List[UTxO]] = defaultdict(list) | ||
self._address_lookup: Dict[UTxO, str] = {} | ||
self._utxo_from_txid: Dict[TransactionId, Dict[int, UTxO]] = defaultdict(dict) | ||
self._network = Network.TESTNET | ||
self._epoch = 0 | ||
self._last_block_slot = 0 | ||
self.opshin_scripts: Dict[ScriptType, Callable[[Any, Any, Any], Any]] = {} | ||
|
||
@property | ||
def protocol_param(self) -> ProtocolParameters: | ||
return self._protocol_param | ||
|
||
@property | ||
def genesis_param(self) -> GenesisParameters: | ||
return self._genesis_param | ||
|
||
@property | ||
def network(self) -> Network: | ||
return self._network | ||
|
||
@property | ||
def epoch(self) -> int: | ||
return self._epoch | ||
|
||
@property | ||
def last_block_slot(self) -> int: | ||
return self._last_block_slot | ||
|
||
def _utxos(self, address: str) -> List[UTxO]: | ||
return self._utxo_state.get(address, []) | ||
|
||
def add_utxo(self, utxo: UTxO): | ||
address = str(utxo.output.address) | ||
self._utxo_state[address].append(utxo) | ||
self._address_lookup[utxo] = address | ||
self._utxo_from_txid[utxo.input.transaction_id][utxo.input.index] = utxo | ||
|
||
def get_address(self, utxo: UTxO) -> str: | ||
return self._address_lookup[utxo] | ||
|
||
def remove_utxo(self, utxo: UTxO): | ||
del self._utxo_from_txid[utxo.input.transaction_id][utxo.input.index] | ||
address = self._address_lookup[utxo] | ||
del self._address_lookup[utxo] | ||
i = self._utxo_state[address].index(utxo) | ||
self._utxo_state[address].pop(i) | ||
|
||
def get_utxo_from_txid(self, transaction_id: TransactionId, index: int) -> UTxO: | ||
return self._utxo_from_txid[transaction_id][index] | ||
|
||
def submit_tx(self, tx: Transaction): | ||
self.evaluate_tx(tx) | ||
self.submit_tx_mock(tx) | ||
|
||
def submit_tx_mock(self, tx: Transaction): | ||
for input in tx.transaction_body.inputs: | ||
utxo = self.get_utxo_from_txid(input.transaction_id, input.index) | ||
self.remove_utxo(utxo) | ||
for i, output in enumerate(tx.transaction_body.outputs): | ||
utxo = UTxO(TransactionInput(tx.id, i), output) | ||
self.add_utxo(utxo) | ||
|
||
def submit_tx_cbor(self, cbor: Union[bytes, str]): | ||
return self.submit_tx(Transaction.from_cbor(cbor)) | ||
|
||
def evaluate_tx(self, tx: Transaction) -> Dict[str, ExecutionUnits]: | ||
input_utxos = [ | ||
self.get_utxo_from_txid(input.transaction_id, input.index) | ||
for input in tx.transaction_body.inputs | ||
] | ||
ref_input_utxos = ( | ||
[ | ||
self.get_utxo_from_txid(input.transaction_id, input.index) | ||
for input in tx.transaction_body.reference_inputs | ||
] | ||
if tx.transaction_body.reference_inputs is not None | ||
else [] | ||
) | ||
script_invocations = generate_script_contexts_resolved( | ||
tx, input_utxos, ref_input_utxos, lambda s: self.posix_from_slot(s) | ||
) | ||
ret = {} | ||
for invocation in script_invocations: | ||
# run opshin script if available | ||
if self.opshin_scripts.get(invocation.script) is not None: | ||
opshin_validator = self.opshin_scripts[invocation.script] | ||
opshin_validator( | ||
invocation.datum, | ||
invocation.redeemer.data, | ||
invocation.script_context, | ||
) | ||
redeemer = invocation.redeemer | ||
if redeemer.ex_units.steps <= 0 and redeemer.ex_units.mem <= 0: | ||
redeemer.ex_units = ExecutionUnits( | ||
self.protocol_param.max_tx_ex_mem, | ||
self.protocol_param.max_tx_ex_steps, | ||
) | ||
|
||
(suc, err), (cpu, mem), logs = evaluate_script(invocation) | ||
if err: | ||
raise ValueError(err, logs) | ||
key = f"{redeemer.tag.name.lower()}:{redeemer.index}" | ||
ret[key] = ExecutionUnits(mem, cpu) | ||
return ret | ||
|
||
def evaluate_tx_cbor(self, cbor: Union[bytes, str]) -> Dict[str, ExecutionUnits]: | ||
return self.evaluate_tx(Transaction.from_cbor(cbor)) | ||
|
||
def wait(self, slots): | ||
self._last_block_slot += slots | ||
|
||
def posix_from_slot(self, slot: int) -> int: | ||
"""Convert a slot to POSIX time (seconds)""" | ||
return self.genesis_param.system_start + self.genesis_param.slot_length * slot | ||
|
||
def slot_from_posix(self, posix: int) -> int: | ||
"""Convert POSIX time (seconds) to the last slot""" | ||
return ( | ||
posix - self.genesis_param.system_start | ||
) // self.genesis_param.slot_length | ||
|
||
|
||
class MockUser: | ||
def __init__(self, context: MockChainContext): | ||
self.context = context | ||
self.signing_key = PaymentSigningKey.generate() | ||
self.verification_key = PaymentVerificationKey.from_signing_key( | ||
self.signing_key | ||
) | ||
self.network = Network.TESTNET | ||
self.address = Address( | ||
payment_part=self.verification_key.hash(), network=self.network | ||
) | ||
|
||
def fund(self, amount: Union[int, Value]): | ||
if isinstance(amount, int): | ||
value = Value(coin=amount) | ||
else: | ||
value = amount | ||
self.context.add_utxo( | ||
# not sure what the correct genesis transaction is | ||
UTxO( | ||
TransactionInput(TransactionId(self.verification_key.payload), 0), | ||
TransactionOutput(self.address, value), | ||
), | ||
) | ||
|
||
def utxos(self): | ||
return self.context.utxos(self.address) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! I think it may be a good idea to port this to pycardano.