Skip to content

Commit

Permalink
Get cost model from context
Browse files Browse the repository at this point in the history
  • Loading branch information
cffls committed Sep 3, 2022
1 parent a1a66cb commit e8b88c4
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 16 deletions.
19 changes: 15 additions & 4 deletions examples/plutus/forty_two/forty_two.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def get_env_val(key):
payment_vkey = PaymentVerificationKey.from_signing_key(payment_skey)

chain_context = BlockFrostChainContext(
project_id=get_env_val("BLOCKFROST_ID"), network=NETWORK
project_id=get_env_val("BLOCKFROST_ID"),
network=NETWORK,
base_url="https://cardano-preview.blockfrost.io/api",
)


Expand Down Expand Up @@ -67,7 +69,7 @@ def create_collateral(target_address, skey):
script_hex = f.read()
forty_two_script = cbor2.loads(bytes.fromhex(script_hex))

script_hash = plutus_script_hash(forty_two_script)
script_hash = plutus_script_hash(PlutusV1Script(forty_two_script))

script_address = Address(script_hash, network=NETWORK)

Expand All @@ -94,11 +96,20 @@ def create_collateral(target_address, skey):
# Put integer 42 (the secret that unlocks the fund) in the redeemer.
redeemer = Redeemer(RedeemerTag.SPEND, 42)

utxo_to_spend = chain_context.utxos(str(script_address))[0]
utxo_to_spend = None
for utxo in chain_context.utxos(str(script_address)):
if utxo.output.datum_hash == datum_hash(datum):
utxo_to_spend = utxo
break

if utxo_to_spend is None:
raise Exception("Can't find utxo to spend! Please try again later.")

builder = TransactionBuilder(chain_context)

builder.add_script_input(utxo_to_spend, forty_two_script, datum, redeemer)
builder.add_script_input(
utxo_to_spend, PlutusV1Script(forty_two_script), datum, redeemer
)

# Send 5 ADA to taker address. The remaining ADA (~4.7) will be sent as change.
take_output = TransactionOutput(taker_address, 5000000)
Expand Down
4 changes: 4 additions & 0 deletions pycardano/backend/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ class ProtocolParameters:

coins_per_utxo_byte: int = None

cost_models: Dict[str, Dict[str, int]] = None
"""A dict contains cost models for Plutus. The key will be "PlutusV1", "PlutusV2", etc.
The value will be a dict of cost model parameters."""


@typechecked
class ChainContext:
Expand Down
14 changes: 5 additions & 9 deletions pycardano/backend/blockfrost.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import argparse
import os
import tempfile
import time
Expand Down Expand Up @@ -28,13 +27,6 @@
__all__ = ["BlockFrostChainContext"]


def _namespace_to_dict(namespace: argparse.Namespace) -> dict:
return {
k: _namespace_to_dict(v) if isinstance(v, argparse.Namespace) else v
for k, v in vars(namespace).items()
}


class BlockFrostChainContext(ChainContext):
"""A `BlockFrost <https://blockfrost.io/>`_ API wrapper for the client code to interact with.
Expand Down Expand Up @@ -119,8 +111,12 @@ def protocol_param(self) -> ProtocolParameters:
max_val_size=int(params.max_val_size),
collateral_percent=int(params.collateral_percent),
max_collateral_inputs=int(params.max_collateral_inputs),
coins_per_utxo_word=int(params.coins_per_utxo_word) or int(params.coins_per_utxo_size),
coins_per_utxo_word=int(params.coins_per_utxo_word)
or int(params.coins_per_utxo_size),
coins_per_utxo_byte=int(params.coins_per_utxo_size),
cost_models={
k: v.to_dict() for k, v in params.cost_models.to_dict().items()
},
)
return self._protocol_param

Expand Down
6 changes: 6 additions & 0 deletions pycardano/backend/ogmios.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,14 @@ def protocol_param(self) -> ProtocolParameters:
"coinsPerUtxoWord", ALONZO_COINS_PER_UTXO_WORD
),
coins_per_utxo_byte=result.get("coinsPerUtxoByte", 0),
cost_models=result.get("costModels", {}),
)

if "plutus:v1" in param.cost_models:
param.cost_models["PlutusV1"] = param.cost_models.pop("plutus:v1")
if "plutus:v2" in param.cost_models:
param.cost_models["PlutusV2"] = param.cost_models.pop("plutus:v2")

args = {"query": "genesisConfig"}
result = self._request(method, args)
param.min_utxo = result["protocolParameters"]["minUtxoValue"]
Expand Down
12 changes: 9 additions & 3 deletions pycardano/txbuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,16 @@ def script_data_hash(self) -> Optional[ScriptDataHash]:
if self.datums or self.redeemers:
cost_models = {}
for s in self.all_scripts:
if isinstance(s, PlutusV1Script):
cost_models[0] = PLUTUS_V1_COST_MODEL
if isinstance(s, PlutusV1Script) or type(s) == bytes:
cost_models[0] = (
self.context.protocol_param.cost_models.get("PlutusV1")
or PLUTUS_V1_COST_MODEL
)
if isinstance(s, PlutusV2Script):
cost_models[1] = PLUTUS_V2_COST_MODEL
cost_models[1] = (
self.context.protocol_param.cost_models.get("PlutusV2")
or PLUTUS_V2_COST_MODEL
)
return script_data_hash(
self.redeemers, list(self.datums.values()), CostModels(cost_models)
)
Expand Down
1 change: 1 addition & 0 deletions test/pycardano/backend/test_ogmios.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def test_protocol_param(self):
max_collateral_inputs=5,
coins_per_utxo_word=1,
coins_per_utxo_byte=1,
cost_models={},
)
== self.chain_context.protocol_param
)
Expand Down
1 change: 1 addition & 0 deletions test/pycardano/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class FixedChainContext(ChainContext):
max_collateral_inputs=3,
coins_per_utxo_word=34482,
coins_per_utxo_byte=4310,
cost_models={},
)

_genesis_param = GenesisParameters(
Expand Down

0 comments on commit e8b88c4

Please sign in to comment.