Skip to content

Commit 18940ac

Browse files
committed
feat: ledger rule footgun scaffolding
1 parent 68ee1bf commit 18940ac

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

src/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
- [`cardano-node`'s ChainDB](storage/cardano-node-chaindb/README.md)
2020
- [Mempool](mempool/README.md)
2121
- [Ledger](ledger/README.md)
22+
- [Ledger Rules](ledger/ledger-rules/README.md)
23+
- [Witness Validation](ledger/ledger-rules/witness-validation.md)
2224
- [Transaction fee](ledger/transaction-fee.md)
2325
- [Block Validation](ledger/block-validation.md)
2426
- [CDDL Specs](ledger/cddls.md)

src/ledger/ledger-rules/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Ledger Rules
2+
This section details the ledger rules used in Cardano and, especially, some of the potential "foot guns" one could run into when implementing these rules. Those "foot guns" could be discrepencies between the specification and the ledger, some undefined behavior, or a bug that was fixed at some point, but is still relevant for syncing historical data.
3+
4+
It is an ongoing work in progress, being updated periodically in paralel with the work happening to build Amaru.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Witness Validation
2+
3+
TODO: provide a description of the ledger rules relevant to this domain specific concept.
4+
5+
## Footgun #1: Bootstrap Witnesses
6+
Alonzo introduced a [`bootstrap_witness`](https://github.com/IntersectMBO/cardano-ledger/blob/d71d7923a79cfcde8cac0b5db399a5427524d06a/eras/allegra/impl/cddl-files/allegra.cddl#L314-L319), which is a different structure for witnesses from a bootstrap address. One would, perhaps reasonably, assume that all witnesses from bootstrap addresses would be provided in this list. However, that is not an assumption that can be made.
7+
8+
### Example: `0c22edee0ffd7c8f32d2fe4da1f144e9ef78dfb51e1678d5198493a83d6cf8ec`
9+
Consider the following [transaction](https://preprod.cexplorer.io/tx/0c22edee0ffd7c8f32d2fe4da1f144e9ef78dfb51e1678d5198493a83d6cf8ec) on Preprod. In JSON, it looks like this:
10+
```json
11+
{
12+
"id": "0c22edee0ffd7c8f32d2fe4da1f144e9ef78dfb51e1678d5198493a83d6cf8ec",
13+
"spends": "inputs",
14+
"inputs": [
15+
{
16+
"transaction": {
17+
"id": "4a0f0fd2ea2e91b34065e3085448b211afdcf72f9db0b2d74d1f99246e16c860"
18+
},
19+
"index": 1
20+
},
21+
{
22+
"transaction": {
23+
"id": "9157ee358b91c319a2e9dd087fe612d1c3d72d34fa4104bec13c8d37fd40b854"
24+
},
25+
"index": 1
26+
}
27+
],
28+
"outputs": [
29+
{
30+
"address": "FHnt4NL7yPXtiYgxWx33wH6JXA9cYxzGAgVG1iMmaX9muBogARkHTRkUox4g4aR",
31+
"value": {
32+
"ada": {
33+
"lovelace": 4832251
34+
}
35+
}
36+
},
37+
{
38+
"address": "addr_test1vpfnhjud440uspylt4pewj7uy8tr0adh84sjqgmnq09xssca7lf4g",
39+
"value": {
40+
"ada": {
41+
"lovelace": 5000000
42+
}
43+
}
44+
}
45+
],
46+
"fee": {
47+
"ada": {
48+
"lovelace": 167749
49+
}
50+
},
51+
"validityInterval": {},
52+
"treasury": {},
53+
"signatories": [
54+
{
55+
"key": "b1ef2a278ebe7cfd563c30f1bb642fb6b5616e040792527e6cd58f119895d657",
56+
"signature": "4110259fb4433f462512d6fa69958070f9e365831962744e7e2e7a2f6a721a707ec4f213ff736fcc195490254dc9d22e0fe0552ae1781b965fc4d05bd5ebb304"
57+
}
58+
],
59+
"cbor": "84a300828258204a0f0fd2ea2e91b34065e3085448b211afdcf72f9db0b2d74d1f99246e16c860018258209157ee358b91c319a2e9dd087fe612d1c3d72d34fa4104bec13c8d37fd40b85401018282582e82d818582483581c533bcb8dad5fc8049f5d43974bdc21d637f5b73d6120237303ca6843a1024101001a63bbc5a61a0049bbfb82581d60533bcb8dad5fc8049f5d43974bdc21d637f5b73d6120237303ca68431a004c4b40021a00028f45a10081825820b1ef2a278ebe7cfd563c30f1bb642fb6b5616e040792527e6cd58f119895d65758404110259fb4433f462512d6fa69958070f9e365831962744e7e2e7a2f6a721a707ec4f213ff736fcc195490254dc9d22e0fe0552ae1781b965fc4d05bd5ebb304f5f6"
60+
}
61+
```
62+
63+
Notably, there is only one signature, and it is not in the form of a bootstrap witness. If we look at the logic that collects vkey hashes that must be present in the witness set ([`getShelleyWitsVkeyNeededNoGov`](https://github.com/IntersectMBO/cardano-ledger/blob/d71d7923a79cfcde8cac0b5db399a5427524d06a/eras/shelley/impl/src/Cardano/Ledger/Shelley/UTxO.hs#L226-L249)), we can understand why.
64+
```hs
65+
inputAuthors :: Set (KeyHash 'Witness)
66+
inputAuthors = foldr' accum Set.empty (txBody ^. spendableInputsTxBodyF)
67+
where
68+
accum txin !ans =
69+
case txinLookup txin utxo' of
70+
Just txOut ->
71+
case txOut ^. addrTxOutL of
72+
Addr _ (KeyHashObj pay) _ -> Set.insert (asWitness pay) ans
73+
AddrBootstrap bootAddr ->
74+
Set.insert (asWitness (bootstrapKeyHash bootAddr)) ans
75+
_ -> ans
76+
Nothing -> ans
77+
```
78+
79+
Bootstrap witnesses and vkey witnesses are combined in the same set, since they are both just hash digests of the same size. That means, if one were to construct a bootstrap address with a payload containing only the keyhash, the validation would pass with a regular vkey witness, instead of a bootstrap witness.
80+
81+
The witnesses themselves are valdiated in isolation–just that they are valid signatures on the required data–so the presence of a boostrap address does not necessarily require the presence of a bootstrap witness.

0 commit comments

Comments
 (0)