transaction types

This commit is contained in:
Mark Spanbroek 2024-12-02 15:45:44 +01:00
parent f28be8d326
commit 943aa07cd7
10 changed files with 224 additions and 0 deletions

View File

@ -4,3 +4,4 @@ description = "Validation network for Codex"
license = "MIT"
requires "https://github.com/codex-storage/nim-mysticeti >= 0.1.0 & < 0.2.0"
requires "https://github.com/codex-storage/nim-stint-versioned.git >= 1.0.0 & < 2.0.0"

View File

@ -0,0 +1,7 @@
import std/sequtils
export sequtils
import pkg/stint
export stint

View File

@ -0,0 +1,67 @@
import ./basics
import ./transaction/slotid
import ./transaction/period
import ./transaction/groth16
export slotid
export period
export groth16
type
TransactionVersion* {.pure.} = enum
version0
TransactionKind* {.pure.} = enum
storageProof
missingProof
Transaction* = object
slotId: SlotId
period: Period
inputs: seq[UInt256]
case kind: TransactionKind
of storageProof:
proof: Groth16Proof
of missingProof:
discard
proc storageProof*(
_: type Transaction,
slotId: SlotId,
period: Period,
inputs: seq[UInt256],
proof: Groth16Proof
): Transaction =
Transaction(
kind: TransactionKind.storageProof,
slotId: slotId,
period: period,
inputs: inputs,
proof: proof
)
proc missingProof*(
_: type Transaction,
slotId: SlotId,
period: Period,
inputs: seq[UInt256],
): Transaction =
Transaction(
kind: TransactionKind.missingProof,
slotId: slotId,
period: period,
inputs: inputs
)
func version*(transaction: Transaction): TransactionVersion =
TransactionVersion.version0
func slotId*(transaction: Transaction): SlotId =
transaction.slotId
func period*(transaction: Transaction): Period =
transaction.period
func inputs*(transaction: Transaction): seq[UInt256] =
transaction.inputs
func proof*(transaction: Transaction): Groth16Proof =
transaction.proof

View File

@ -0,0 +1,56 @@
import ../basics
type
Groth16Proof* = object
a: G1Point
b: G2Point
c: G1Point
G1Point* = object
x: UInt256
y: UInt256
Fp2Element* = object
## A field element F_{p^2} encoded as `real + i * imag`
real: UInt256
imag: UInt256
G2Point* = object
x: Fp2Element
y: Fp2Element
func init*(_: type Groth16Proof, a: G1Point, b: G2Point, c: G1Point): Groth16Proof =
Groth16Proof(a: a, b: b, c: c)
func a*(proof: Groth16Proof): G1Point =
proof.a
func b*(proof: Groth16Proof): G2Point =
proof.b
func c*(proof: Groth16Proof): G1Point =
proof.c
func init*(_: type G1Point, x, y: UInt256): G1Point =
G1Point(x: x, y: y)
func x*(point: G1Point): UInt256 =
point.x
func y*(point: G1Point): UInt256 =
point.y
func init*(_: type G2Point, x, y: Fp2Element): G2Point =
G2Point(x: x, y: y)
func x*(point: G2Point): Fp2Element =
point.x
func y*(point: G2Point): Fp2Element =
point.y
func init*(_: type Fp2Element, real, imag: UInt256): Fp2Element =
Fp2Element(real: real, imag: imag)
func real*(element: Fp2Element): UInt256 =
element.real
func imag*(element: Fp2Element): UInt256 =
element.imag

View File

@ -0,0 +1,4 @@
type Period* = distinct uint64
func `$`*(period: Period): string {.borrow.}
func `==`*(a, b: Period): bool {.borrow.}

View File

@ -0,0 +1,4 @@
type SlotId* = distinct array[32, byte]
func `$`*(slotId: SlotId): string {.borrow.}
func `==`*(a, b: SlotId): bool {.borrow.}

View File

@ -0,0 +1,54 @@
import std/random
import codexvalidator/basics
import codexvalidator/transaction
proc example*[T: SomeInteger](_: type T): T =
rand(T)
proc example*(_: type UInt256): UInt256 =
UInt256.fromBytesBE(array[32, byte].example)
proc example*[T, length](_: type array[length, T]): array[length, T] =
for i in result.low..result.high:
result[i] = T.example
proc example*[T](_: type seq[T], length = 0..10): seq[T] =
let len = rand(length)
newSeqWith(len, T.example)
proc example*(_: type SlotId): SlotId =
SlotId(array[32, byte].example)
proc example*(_: type Period): Period =
Period(uint64.example)
proc example*(_: type G1Point): G1Point =
G1Point.init(UInt256.example, UInt256.example)
proc example*(_: type Fp2Element): Fp2Element =
Fp2Element.init(UInt256.example, UInt256.example)
proc example*(_: type G2Point): G2Point =
G2Point.init(
Fp2Element.example,
Fp2Element.example
)
proc example*(_: type Groth16Proof): Groth16Proof =
Groth16Proof.init(
G1Point.example,
G2Point.example,
G1Point.example
)
proc example*(_: type Transaction): Transaction =
let kind = [TransactionKind.storageProof, TransactionKind.missingProof].sample
let slotId = SlotId.example
let period = Period.example
let inputs = seq[UInt256].example
case kind
of TransactionKind.missingProof:
Transaction.missingProof(slotId, period, inputs)
of TransactionKind.storageProof:
let proof = Groth16Proof.example
Transaction.storageProof(slotId, period, inputs, proof)

View File

@ -0,0 +1,27 @@
import std/unittest
import codexvalidator/basics
import codexvalidator/transaction
import ./examples
suite "Transaction":
test "a transaction can contain a storage proof":
let slotId = SlotId.example
let period = Period.example
let inputs = seq[UInt256].example
let proof = Groth16Proof.example
let transaction = Transaction.storageProof(slotId, period, inputs, proof)
check transaction.proof == proof
test "a transaction can indicate a missing storage proof":
let slotId = SlotId.example
let period = Period.example
let inputs = seq[UInt256].example
let transaction = Transaction.missingProof(slotId, period, inputs)
check transaction.slotId == slotId
check transaction.period == period
check transaction.inputs == inputs
test "transactions have a fixed version":
let transaction = Transaction.example
check transaction.version == TransactionVersion.version0

1
tests/nim.cfg Normal file
View File

@ -0,0 +1 @@
--path:".."

3
tests/tests.nim Normal file
View File

@ -0,0 +1,3 @@
import ./codexvalidator/testTransaction
{.warning[UnusedImport]:off.}