# Predicate

This package contains the predicate data structure and its encoding and helper functions to unpack/pack the data structure.

## Encoding

A byte slice of size N is encoded as:

1. Slice of N bytes
2. Delimiter byte `0xff`
3. Appended 0s to the nearest multiple of 32 bytes


## Results

This defines how to encode `PredicateResults` within the block header's `Extra` data field.

For more information on the motivation for encoding the results of predicate verification within a block, see [here](../../../vms/platformvm/warp/README.md#processing-historical-lux-interchain-messages).

### Serialization

Results have a maximum size of 1MB enforced by the codec. The actual size depends on how much data the Precompile predicates may put into the results, the gas cost they charge, and the block gas limit. PredicateResults are encoded using the Lux Node codec, which serializes a map by serializing the length of the map as a `uint32` and then serializes each key-value pair sequentially.

PredicateResults:

| Field | Type | Size |
|-------|------|------|
| codecID | uint16 | 2 bytes |
| results | map[[32]byte]TxPredicateResults | 4 + size(results) bytes |
| **Total** | | **6 + size(results)** |

- `codecID` is the codec version used to serialize the payload and is hardcoded to `0x0000`
- `results` is a map of transaction hashes to the corresponding `TxPredicateResults`

TxPredicateResults

| Field | Type | Size |
|-------|------|------|
| txPredicateResults | map[[20]byte][]byte | 4 + size(txPredicateResults) bytes |

- `txPredicateResults` is a map of precompile addresses to the corresponding byte array returned by the predicate

#### Examples

##### Empty Predicate Results Map

```
// codecID
0x00, 0x00,
// results length
0x00, 0x00, 0x00, 0x00
```

##### Predicate Map with a Single Transaction Result

```
// codecID
0x00, 0x00,
// Results length
0x00, 0x00, 0x00, 0x01,
// txHash (key in results map)
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
// TxPredicateResults (value in results map)
// TxPredicateResults length
0x00, 0x00, 0x00, 0x01,
// precompile address (key in TxPredicateResults map)
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Byte array results (value in TxPredicateResults map)
// Length of bytes result
0x00, 0x00, 0x00, 0x03,
// bytes
0x01, 0x02, 0x03
```

##### Predicate Map with Two Transaction Results

```
// codecID
0x00, 0x00,
// Results length
0x00, 0x00, 0x00, 0x02,
// txHash (key in results map)
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
// TxPredicateResults (value in results map)
// TxPredicateResults length
0x00, 0x00, 0x00, 0x01,
// precompile address (key in TxPredicateResults map)
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Byte array results (value in TxPredicateResults map)
// Length of bytes result
0x00, 0x00, 0x00, 0x03,
// bytes
0x01, 0x02, 0x03
// txHash2 (key in results map)
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
// TxPredicateResults (value in results map)
// TxPredicateResults length
0x00, 0x00, 0x00, 0x01,
// precompile address (key in TxPredicateResults map)
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
// Byte array results (value in TxPredicateResults map)
// Length of bytes result
0x00, 0x00, 0x00, 0x03,
// bytes
0x01, 0x02, 0x03
```
