You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
2
4
-
It is an ongoing work in progress, being updated periodically in paralel with the work happening to build Amaru.
3
+
This section details the ledger rules used in Cardano and, especially, some of the potential "land mines" one could run into when implementing these rules.
4
+
5
+
The ledger rules will be organized in a potentially unique way. Instead of grouping them based on inference rules defined in the [Cardano Ledger Specification](https://intersectmbo.github.io/formal-ledger-specifications/cardano-ledger.pdf) or some arbitrary implementation of said specification, they are grouped based on their responsibility throughout the validation process. For example, "Witness Validation" contains several rules related to validating the transaction witness set.
6
+
7
+
## What is a "Land Mine"?
8
+
In this context, a "Land Mine" is a part of the ledger rules that could cause confusion or are easy to get wrong. This could be a discrepency between the Haskell implementation and the formal specification (A bug or otherwise), some unintended behavior that resulted from an edge case that was not considered during initial implementation, or simply something that caused an issue for some alternative node implementors, and therefore should be documented for the future implementors.
Copy file name to clipboardExpand all lines: src/ledger/ledger-rules/witness-validation.md
+33-6Lines changed: 33 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,33 @@
1
1
# Witness Validation
2
2
3
-
TODO: provide a description of the ledger rules relevant to this domain specific concept.
3
+
### Key Definitions
4
+
**`Witness`**: A witness is a piece of data that allows you to verify the authenticity of the transaction. There are many different witness types, depending on what the transaction requires, such as vkey witnesses, bootstrap witnesses, and script witnesses.
4
5
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.
6
+
**`Vkey Witness`**: A vkey witness is a specific witness type. It is used to verify that the transaction has the authority to consume a UTxO(s) locked at the assosciated `pkh` address. It includes the signature and the vkey (instead of the key hash, which is encoded in the address).
7
+
8
+
**`Bootstrap Witness`**: A bootstrap witness is a specific witness type. It is used to verify that the transaction has the authority to consume a UTxO(s) locked at the associated Byron-era address. It includes the assosciated public key, the signature, the 32 byte chain code, and a set of attributes encoded in the address.
9
+
10
+
*TODO: script witnesses*
11
+
12
+
### Process
13
+
14
+
Witness validation is the process of validating that all witnesses are:
15
+
1) Valid signatures given the tranasaction hash and the provided public key.
16
+
2) Present if required by the transaction. There cannot be any missing witnesses.
17
+
3)*TODO: script witness validation*
18
+
19
+
The process of witness validation is described in section 12.2 of the [Cardano Ledger Specification](https://intersectmbo.github.io/formal-ledger-specifications/cardano-ledger.pdf), in the UTXOW inference rules.
20
+
21
+
*TODO: provide links to the relevent sections of code in Amaru and Haskell node*
22
+
23
+
24
+
## "Land Mine" #1: Bootstrap Witnesses
25
+
26
+
### Context
27
+
After Shelley introduced the [`bootstrap_witness`](https://github.com/IntersectMBO/cardano-ledger/blob/d71d7923a79cfcde8cac0b5db399a5427524d06a/eras/shelley/impl/cddl-files/shelley.cddl#L296-L301) field to the `transaction_witness_set`. One may reasonably assume that if a Byron-era address is present, the assosciated witness would be found in the `bootstrap_witness` field. However, it is possible to construct a valid transaction such that it includes a Byron-era address, but the `bootstrap_witness` field is an empty list.
28
+
29
+
### Solution
30
+
A node must consider the set of bootstrap root hashes and vkey hashes together when validating that there are no missing required witnesses, instead of isolating the handling of bootstrap addresses and `BootstrapWitness`es from shelley-era addresses and `VkeyWitness`es.
Consider the following [transaction](https://preprod.cexplorer.io/tx/0c22edee0ffd7c8f32d2fe4da1f144e9ef78dfb51e1678d5198493a83d6cf8ec) on Preprod. In JSON, it looks like this:
@@ -60,7 +84,7 @@ Consider the following [transaction](https://preprod.cexplorer.io/tx/0c22edee0ff
60
84
}
61
85
```
62
86
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.
87
+
Notably, there is only one signature, and it is a `VkeyWitness`. Examining the logic that collects required key hashes ([`getShelleyWitsVkeyNeededNoGov`](https://github.com/IntersectMBO/cardano-ledger/blob/d71d7923a79cfcde8cac0b5db399a5427524d06a/eras/shelley/impl/src/Cardano/Ledger/Shelley/UTxO.hs#L226-L249)), the reason becomes apparent:
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.
103
+
The Haskell node is inserting hashes from both `AddrBootstrap` and `Addr` into the same set, since they are both just hash digests of the same size. The hash digest inserted in the case of an `AddrBootstrap` is the bytes that are found at the first field of the `BYRON_ADDRESS_PAYLOAD`. In theory, this is the digest of the `blake2b_224(sha3_256(BYRON_ADDRESS_ROOT))` and that should never be the same digest as a `Addr` vkey hash digest, so there would be no complexity introduced here. However one could, and clearly did, manually construct a Byron-era address where the bytes that are suppose to be the digest of the `BYRON_ADDRESS_ROOT` are instead the digest of a vkey. In that case, a vkey witness present with the assosciated public key would satifsy the required witness, even though that requirement came from an Byron-era bootstrap address.
80
104
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.
105
+
> [!TIP]
106
+
>
107
+
> The provided solution already handles this case, but it's worth noting that this could, theoretically, also apply the other direction. If one were to construct a shelley era address where the payment part is the digest of some `BYRON_ADDRESS_ROOT` instead of a verification key, they could have a `BootstrapWitness` present instead of a `VkeyWitness`.
108
+
> Author's note: I only just thought of this case while writing up this information and haven't verified that it's true. But, off the top of my head, there is no reason this wouldn't be the case.
0 commit comments