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
1 change: 1 addition & 0 deletions integration-test/configs/local-chang/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"ShelleyGenesisFile": "./shelley-genesis.json",
"AlonzoGenesisFile": "./alonzo-genesis.json",
"ConwayGenesisFile": "./conway-genesis.json",
"DijkstraGenesisFile": "./dijkstra-genesis.json",
"SocketPath": "db/node.socket",
"Protocol": "Cardano",
"PBftSignatureThreshold": 0.6,
Expand Down
42 changes: 18 additions & 24 deletions integration-test/configs/local-chang/conway-genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,25 @@
}
},
"poolVotingThresholds": {
"committeeNormal": 0.65,
"committeeNoConfidence": 0.65,
"hardForkInitiation": 0.51,
"motionNoConfidence": 0.6,
"ppSecurityGroup": 0.6
"committeeNormal": 0,
"committeeNoConfidence": 0,
"hardForkInitiation": 0,
"motionNoConfidence": 0,
"ppSecurityGroup": 0
},
"dRepVotingThresholds": {
"motionNoConfidence": 0.67,
"committeeNormal": 0.67,
"committeeNoConfidence": 0.65,
"updateToConstitution": 0.75,
"hardForkInitiation": 0.6,
"ppNetworkGroup": 0.67,
"ppEconomicGroup": 0.67,
"ppTechnicalGroup": 0.67,
"ppGovGroup": 0.75,
"treasuryWithdrawal": 0.67
"motionNoConfidence": 0,
"committeeNormal": 0,
"committeeNoConfidence": 0,
"updateToConstitution": 0,
"hardForkInitiation": 0,
"ppNetworkGroup": 0,
"ppEconomicGroup": 0,
"ppTechnicalGroup": 0,
"ppGovGroup": 0,
"treasuryWithdrawal": 0
},
"committeeMinSize": 5,
"committeeMinSize": 0,
"committeeMaxTermLength": 146,
"govActionLifetime": 14,
"govActionDeposit": 100000000000,
Expand Down Expand Up @@ -291,13 +291,7 @@
}
},
"committee": {
"members": {
"scriptHash-7ceede7d6a89e006408e6b7c6acb3dd094b3f6817e43b4a36d01535b": 500,
"scriptHash-6095e643ea6f1cccb6e463ec34349026b3a48621aac5d512655ab1bf": 500,
"scriptHash-27999ed757d6dac217471ae61d69b1b067b8b240d9e3ff36eb66b5d0": 500,
"scriptHash-87f867a31c0f81360d4d7dcddb6b025ba8383db9bf77a2af7797799d": 500,
"scriptHash-a19a7ba1caede8f3ab3e5e2a928b3798d7d011af18fbd577f7aeb0ec": 500
},
"threshold": 0.67
"members": {},
"threshold": 0
}
}
6 changes: 6 additions & 0 deletions integration-test/configs/local-chang/dijkstra-genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"maxRefScriptSizePerBlock": 1048576,
"maxRefScriptSizePerTx": 204800,
"refScriptCostStride": 25600,
"refScriptCostMultiplier": 1.2
}
17 changes: 13 additions & 4 deletions integration-test/configs/local-chang/topology.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
{
"Producers": [
"bootstrapPeers": null,
"localRoots": [
{
"addr": "172.20.0.102",
"port": 3000,
"accessPoints": [
{
"address": "172.20.0.102",
"port": 3000
}
],
"advertise": false,
"trustable": true,
"valency": 1
}
]
],
"publicRoots": [],
"useLedgerAfterSlot": -1
}
4 changes: 2 additions & 2 deletions integration-test/docker-compose-chang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ networks:
services:

cardano-node:
image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-10.5.1}
image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-10.7.1}
platform: linux/amd64
entrypoint: bash
environment:
Expand All @@ -35,7 +35,7 @@ services:
max-file: "10"

cardano-pool:
image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-10.5.1}
image: ghcr.io/intersectmbo/cardano-node:${CARDANO_NODE_VERSION:-10.7.1}
platform: linux/amd64
entrypoint: bash
environment:
Expand Down
19 changes: 14 additions & 5 deletions integration-test/keys/pool/topology.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
{
"Producers": [
"bootstrapPeers": null,
"localRoots": [
{
"addr": "172.20.0.101",
"port": 3000,
"accessPoints": [
{
"address": "172.20.0.101",
"port": 3000
}
],
"advertise": false,
"trustable": true,
"valency": 1
}
]
}
],
"publicRoots": [],
"useLedgerAfterSlot": -1
}
4 changes: 4 additions & 0 deletions integration-test/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ while true; do
sleep 2
done

# cardano-node 10.7+ no longer auto-inits PlutusV2 cost model at Babbage HF.
# Submit a Conway parameter-update action to add it before running tests.
docker exec integration-test-cardano-pool-1 bash /code/setup_governance.sh

poetry run pytest -m "not (CardanoCLI)" -s -vv "$ROOT"/test --cov=pycardano --cov-config=../.coveragerc --cov-report=xml:../coverage.xml

# Cleanup
Expand Down
121 changes: 121 additions & 0 deletions integration-test/setup_governance.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/bin/bash
# Submit a Conway governance action to add PlutusV2 cost model.
# Runs inside the cardano-pool-1 container via `docker exec`.
# cardano-node 10.7+ no longer auto-initializes PlutusV2 cost model at
# the Babbage hard fork, so it has to be added by an explicit parameter
# update action. conway-genesis is set up with zero thresholds so the
# action ratifies trivially.

set -euo pipefail

NETWORK="${NETWORK:-local-chang}"
TESTNET_MAGIC="${TESTNET_MAGIC:-42}"
CFG=/code/tmp_configs/$NETWORK
POOL=/code/keys/pool
COST_MODEL_FILE=/tmp/v2-cost-model.json
ANCHOR_FILE=/tmp/anchor.json
ACTION_FILE=/tmp/v2.action
TX_RAW=/tmp/v2.tx.raw
TX_SIGNED=/tmp/v2.tx.signed
ANCHOR_PORT=18080

export CARDANO_NODE_SOCKET_PATH=/ipc/node.socket

# Submit the gov action from the pool's wallet (full.addr ≈ 450K ADA) rather
# than utxo1 (which the integration tests need intact). The deposit (100K)
# returns to the pool's own stake key after enactment, so funds stay within
# the pool wallet — utxo1 is never touched.
PAYMENT_ADDR=$(cat "$POOL/full.addr")

echo "[gov] Building V2 cost-model file from alonzo-genesis…"
# alonzo-genesis stores PlutusV2 either as a dict (legacy) or a list. Normalize
# to a list of values sorted by key (canonical order matches list form).
jq '.costModels.PlutusV2
| if type == "object"
then to_entries | sort_by(.key) | map(.value)
else .
end
| { PlutusV2: . }' "$CFG/alonzo-genesis.json" > "$COST_MODEL_FILE"
echo "[gov] V2 length: $(jq '.PlutusV2 | length' "$COST_MODEL_FILE")"

# cardano-cli `transaction build` always verifies that --anchor-url is
# fetchable and its body hashes to --anchor-data-hash. Serve a tiny static
# anchor file locally over http so the verification succeeds offline.
echo '{"title":"add PlutusV2 cost model","authors":["pycardano-tests"]}' > "$ANCHOR_FILE"
ANCHOR_HASH=$(cardano-cli hash anchor-data --file-text "$ANCHOR_FILE")
echo "[gov] anchor hash: $ANCHOR_HASH"

ANCHOR_LEN=$(stat -c%s "$ANCHOR_FILE")
RESPONSE_FILE=/tmp/anchor.http
{
printf 'HTTP/1.0 200 OK\r\n'
printf 'Content-Type: application/json\r\n'
printf 'Content-Length: %d\r\n' "$ANCHOR_LEN"
printf '\r\n'
cat "$ANCHOR_FILE"
} > "$RESPONSE_FILE"

socat -d TCP-LISTEN:"$ANCHOR_PORT",fork,reuseaddr SYSTEM:"cat $RESPONSE_FILE" &
SOCAT_PID=$!
trap 'kill $SOCAT_PID 2>/dev/null || true' EXIT
sleep 1
echo "[gov] anchor server up on :$ANCHOR_PORT (pid $SOCAT_PID)"

ANCHOR_URL="http://127.0.0.1:$ANCHOR_PORT/anchor.json"

echo "[gov] Creating parameter-update action…"
cardano-cli conway governance action create-protocol-parameters-update \
--testnet \
--governance-action-deposit 100000000000 \
--deposit-return-stake-verification-key-file "$POOL/stake.vkey" \
--anchor-url "$ANCHOR_URL" \
--anchor-data-hash "$ANCHOR_HASH" \
--cost-model-file "$COST_MODEL_FILE" \
--out-file "$ACTION_FILE"

echo "[gov] Selecting UTxO at $PAYMENT_ADDR…"
TX_IN=$(cardano-cli conway query utxo \
--address "$PAYMENT_ADDR" \
--testnet-magic "$TESTNET_MAGIC" \
--output-json | jq -r 'keys[0]')
echo "[gov] tx-in: $TX_IN"

echo "[gov] Building transaction with proposal…"
cardano-cli conway transaction build \
--testnet-magic "$TESTNET_MAGIC" \
--tx-in "$TX_IN" \
--change-address "$PAYMENT_ADDR" \
--proposal-file "$ACTION_FILE" \
--out-file "$TX_RAW"

echo "[gov] Signing…"
cardano-cli conway transaction sign \
--testnet-magic "$TESTNET_MAGIC" \
--tx-body-file "$TX_RAW" \
--signing-key-file "$POOL/payment.skey" \
--out-file "$TX_SIGNED"

echo "[gov] Submitting…"
cardano-cli conway transaction submit \
--testnet-magic "$TESTNET_MAGIC" \
--tx-file "$TX_SIGNED"

echo "[gov] Waiting for V2 cost model to appear on chain…"
for i in $(seq 1 60); do
if cardano-cli conway query protocol-parameters --testnet-magic "$TESTNET_MAGIC" 2>/dev/null \
| jq -e '.costModels.PlutusV2' >/dev/null; then
echo "[gov] V2 cost model is now on chain (after ${i} iterations)."
# Record the ratified action's id so test_governance can chain to it.
# `cardano-cli ... transaction txid` returns JSON like {"txhash":"..."}.
TX_ID=$(cardano-cli conway transaction txid --tx-file "$TX_SIGNED" | jq -r '.txhash // .')
printf '{"tx_id":"%s","index":0}\n' "$TX_ID" > "$CFG/last_param_action.json"
echo "[gov] wrote prev-action id to $CFG/last_param_action.json (tx=$TX_ID)"
exit 0
fi
sleep 5
done

echo "[gov] ERROR: V2 cost model did not appear within timeout." >&2
cardano-cli conway query protocol-parameters --testnet-magic "$TESTNET_MAGIC" \
| jq '.costModels | keys' >&2
exit 1
23 changes: 22 additions & 1 deletion integration-test/test/test_governance.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import os
import time

Expand All @@ -8,6 +9,24 @@
from .base import TEST_RETRIES, TestBase


def _load_prev_param_update_action():
"""Read the gov action id of the last ratified parameter update written by
setup_governance.sh (if any). Returns None if the file is absent — e.g. on
a chain that has never had a parameter update ratified."""
here = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(
here, "..", "tmp_configs", "local-chang", "last_param_action.json"
)
if not os.path.exists(path):
return None
with open(path) as f:
data = json.load(f)
return GovActionId(
transaction_id=TransactionId(bytes.fromhex(data["tx_id"])),
gov_action_index=data["index"],
)


class TestGovernanceAction(TestBase):
@retry(tries=TEST_RETRIES, backoff=1.3, delay=2, jitter=(0, 10))
def test_governance_action_and_voting(self):
Expand Down Expand Up @@ -90,7 +109,9 @@ def test_governance_action_and_voting(self):
max_transaction_size=26384,
)

parameter_change_action = ParameterChangeAction(None, param_update, None)
parameter_change_action = ParameterChangeAction(
_load_prev_param_update_action(), param_update, None
)

# Create transaction for parameter change
builder = TransactionBuilder(self.chain_context)
Expand Down
Loading