mirror of
https://github.com/logos-storage/logos-storage-nim-validator.git
synced 2026-01-03 14:03:07 +00:00
transaction signing
This commit is contained in:
parent
ac4413fce5
commit
56ec9a03c2
@ -1,28 +0,0 @@
|
||||
import pkg/protobuf_serialization
|
||||
|
||||
export protobuf_serialization
|
||||
|
||||
type
|
||||
TransactionMessage* {.proto3.} = object
|
||||
version* {.fieldNumber: 1, pint.}: uint32
|
||||
kind* {.fieldNumber: 2, pint.}: uint32
|
||||
requestId* {.fieldNumber: 3.}: seq[byte]
|
||||
slotIndex* {.fieldNumber: 4, pint.}: uint32
|
||||
period* {.fieldNumber: 5, pint.}: uint64
|
||||
merkleRoot* {.fieldNumber: 6.}: seq[byte]
|
||||
challenge* {.fieldNumber: 7.}: seq[byte]
|
||||
proof* {.fieldNumber: 8.}: Groth16ProofMessage
|
||||
Groth16ProofMessage* {.proto3.} = object
|
||||
a* {.fieldNumber: 1.}: G1PointMessage
|
||||
b* {.fieldNumber: 2.}: G2PointMessage
|
||||
c* {.fieldNumber: 3.}: G1PointMessage
|
||||
G1PointMessage* {.proto3.} = object
|
||||
x* {.fieldNumber: 1.}: seq[byte]
|
||||
y* {.fieldNumber: 2.}: seq[byte]
|
||||
G2PointMessage* {.proto3.} = object
|
||||
x* {.fieldNumber: 1.}: Fp2ElementMessage
|
||||
y* {.fieldNumber: 2.}: Fp2ElementMessage
|
||||
Fp2ElementMessage* {.proto3.} = object
|
||||
real* {.fieldNumber: 1.}: seq[byte]
|
||||
imag* {.fieldNumber: 2.}: seq[byte]
|
||||
|
||||
@ -1,86 +1,7 @@
|
||||
import ./basics
|
||||
import ./transaction/storagerequest
|
||||
import ./transaction/period
|
||||
import ./transaction/groth16
|
||||
import ./transaction/transaction
|
||||
import ./transaction/signed
|
||||
import ./transaction/serialization
|
||||
|
||||
export storagerequest
|
||||
export period
|
||||
export groth16
|
||||
|
||||
type
|
||||
TransactionVersion* {.pure.} = enum
|
||||
version0
|
||||
TransactionKind* {.pure.} = enum
|
||||
storageProof
|
||||
missingProof
|
||||
Transaction* = object
|
||||
requestId: StorageRequestId
|
||||
slotIndex: uint32
|
||||
period: Period
|
||||
merkleRoot: UInt256
|
||||
challenge: UInt256
|
||||
case kind: TransactionKind
|
||||
of storageProof:
|
||||
proof: Groth16Proof
|
||||
of missingProof:
|
||||
discard
|
||||
|
||||
func storageProof*(
|
||||
_: type Transaction,
|
||||
requestId: StorageRequestId,
|
||||
slotIndex: uint32,
|
||||
period: Period,
|
||||
merkleRoot: UInt256,
|
||||
challenge: UInt256,
|
||||
proof: Groth16Proof
|
||||
): Transaction =
|
||||
Transaction(
|
||||
kind: TransactionKind.storageProof,
|
||||
requestId: requestId,
|
||||
period: period,
|
||||
slotIndex: slotIndex,
|
||||
merkleRoot: merkleRoot,
|
||||
challenge: challenge,
|
||||
proof: proof
|
||||
)
|
||||
|
||||
func missingProof*(
|
||||
_: type Transaction,
|
||||
requestId: StorageRequestId,
|
||||
slotIndex: uint32,
|
||||
period: Period,
|
||||
merkleRoot: UInt256,
|
||||
challenge: UInt256,
|
||||
): Transaction =
|
||||
Transaction(
|
||||
kind: TransactionKind.missingProof,
|
||||
requestId: requestId,
|
||||
slotIndex: slotIndex,
|
||||
period: period,
|
||||
merkleRoot: merkleRoot,
|
||||
challenge: challenge
|
||||
)
|
||||
|
||||
func version*(transaction: Transaction): TransactionVersion =
|
||||
TransactionVersion.version0
|
||||
|
||||
func kind*(transaction: Transaction): TransactionKind =
|
||||
transaction.kind
|
||||
|
||||
func requestId*(transaction: Transaction): StorageRequestId =
|
||||
transaction.requestId
|
||||
|
||||
func slotIndex*(transaction: Transaction): uint32 =
|
||||
transaction.slotIndex
|
||||
|
||||
func period*(transaction: Transaction): Period =
|
||||
transaction.period
|
||||
|
||||
func merkleRoot*(transaction: Transaction): UInt256 =
|
||||
transaction.merkleRoot
|
||||
|
||||
func challenge*(transaction: Transaction): UInt256 =
|
||||
transaction.challenge
|
||||
|
||||
func proof*(transaction: Transaction): Groth16Proof =
|
||||
transaction.proof
|
||||
export transaction
|
||||
export signed
|
||||
export serialization.toBytes
|
||||
|
||||
@ -1,6 +1,33 @@
|
||||
import ./basics
|
||||
import pkg/protobuf_serialization
|
||||
import ../basics
|
||||
import ./transaction
|
||||
import ./serialization/protobuf
|
||||
|
||||
export protobuf_serialization
|
||||
|
||||
type
|
||||
TransactionMessage* {.proto3.} = object
|
||||
version* {.fieldNumber: 1, pint.}: uint32
|
||||
kind* {.fieldNumber: 2, pint.}: uint32
|
||||
requestId* {.fieldNumber: 3.}: seq[byte]
|
||||
slotIndex* {.fieldNumber: 4, pint.}: uint32
|
||||
period* {.fieldNumber: 5, pint.}: uint64
|
||||
merkleRoot* {.fieldNumber: 6.}: seq[byte]
|
||||
challenge* {.fieldNumber: 7.}: seq[byte]
|
||||
proof* {.fieldNumber: 8.}: Groth16ProofMessage
|
||||
Groth16ProofMessage* {.proto3.} = object
|
||||
a* {.fieldNumber: 1.}: G1PointMessage
|
||||
b* {.fieldNumber: 2.}: G2PointMessage
|
||||
c* {.fieldNumber: 3.}: G1PointMessage
|
||||
G1PointMessage* {.proto3.} = object
|
||||
x* {.fieldNumber: 1.}: seq[byte]
|
||||
y* {.fieldNumber: 2.}: seq[byte]
|
||||
G2PointMessage* {.proto3.} = object
|
||||
x* {.fieldNumber: 1.}: Fp2ElementMessage
|
||||
y* {.fieldNumber: 2.}: Fp2ElementMessage
|
||||
Fp2ElementMessage* {.proto3.} = object
|
||||
real* {.fieldNumber: 1.}: seq[byte]
|
||||
imag* {.fieldNumber: 2.}: seq[byte]
|
||||
|
||||
|
||||
func toBytes*(transaction: Transaction): seq[byte] =
|
||||
var message = TransactionMessage(
|
||||
36
codexvalidator/transaction/signed.nim
Normal file
36
codexvalidator/transaction/signed.nim
Normal file
@ -0,0 +1,36 @@
|
||||
import ../signatures
|
||||
import ./transaction
|
||||
import ./serialization
|
||||
|
||||
type SignedTransaction* = object
|
||||
transaction: Transaction
|
||||
signer: Identifier
|
||||
signature: Signature
|
||||
|
||||
func init*(
|
||||
_: type SignedTransaction,
|
||||
transaction: Transaction,
|
||||
signer: Identifier,
|
||||
signature: Signature
|
||||
): SignedTransaction =
|
||||
SignedTransaction(
|
||||
transaction: transaction,
|
||||
signer: signer,
|
||||
signature: signature
|
||||
)
|
||||
|
||||
func sign*(identity: Identity, transaction: Transaction): SignedTransaction =
|
||||
let signature = identity.sign(transaction.toBytes())
|
||||
SignedTransaction.init(transaction, identity.identifier, signature)
|
||||
|
||||
func transaction*(signed: SignedTransaction): Transaction =
|
||||
signed.transaction
|
||||
|
||||
func signer*(signed: SignedTransaction): Identifier =
|
||||
signed.signer
|
||||
|
||||
func signature*(signed: SignedTransaction): Signature =
|
||||
signed.signature
|
||||
|
||||
func verifySignature*(signed: SignedTransaction): bool =
|
||||
signed.signer.verify(signed.transaction.toBytes(), signed.signature)
|
||||
105
codexvalidator/transaction/transaction.nim
Normal file
105
codexvalidator/transaction/transaction.nim
Normal file
@ -0,0 +1,105 @@
|
||||
import ../basics
|
||||
import ./storagerequest
|
||||
import ./period
|
||||
import ./groth16
|
||||
|
||||
export storagerequest
|
||||
export period
|
||||
export groth16
|
||||
|
||||
type
|
||||
TransactionVersion* {.pure.} = enum
|
||||
version0
|
||||
TransactionKind* {.pure.} = enum
|
||||
storageProof
|
||||
missingProof
|
||||
Transaction* = object
|
||||
requestId: StorageRequestId
|
||||
slotIndex: uint32
|
||||
period: Period
|
||||
merkleRoot: UInt256
|
||||
challenge: UInt256
|
||||
case kind: TransactionKind
|
||||
of storageProof:
|
||||
proof: Groth16Proof
|
||||
of missingProof:
|
||||
discard
|
||||
|
||||
func storageProof*(
|
||||
_: type Transaction,
|
||||
requestId: StorageRequestId,
|
||||
slotIndex: uint32,
|
||||
period: Period,
|
||||
merkleRoot: UInt256,
|
||||
challenge: UInt256,
|
||||
proof: Groth16Proof
|
||||
): Transaction =
|
||||
Transaction(
|
||||
kind: TransactionKind.storageProof,
|
||||
requestId: requestId,
|
||||
period: period,
|
||||
slotIndex: slotIndex,
|
||||
merkleRoot: merkleRoot,
|
||||
challenge: challenge,
|
||||
proof: proof
|
||||
)
|
||||
|
||||
func missingProof*(
|
||||
_: type Transaction,
|
||||
requestId: StorageRequestId,
|
||||
slotIndex: uint32,
|
||||
period: Period,
|
||||
merkleRoot: UInt256,
|
||||
challenge: UInt256,
|
||||
): Transaction =
|
||||
Transaction(
|
||||
kind: TransactionKind.missingProof,
|
||||
requestId: requestId,
|
||||
slotIndex: slotIndex,
|
||||
period: period,
|
||||
merkleRoot: merkleRoot,
|
||||
challenge: challenge
|
||||
)
|
||||
|
||||
func version*(transaction: Transaction): TransactionVersion =
|
||||
TransactionVersion.version0
|
||||
|
||||
func kind*(transaction: Transaction): TransactionKind =
|
||||
transaction.kind
|
||||
|
||||
func requestId*(transaction: Transaction): StorageRequestId =
|
||||
transaction.requestId
|
||||
|
||||
func slotIndex*(transaction: Transaction): uint32 =
|
||||
transaction.slotIndex
|
||||
|
||||
func period*(transaction: Transaction): Period =
|
||||
transaction.period
|
||||
|
||||
func merkleRoot*(transaction: Transaction): UInt256 =
|
||||
transaction.merkleRoot
|
||||
|
||||
func challenge*(transaction: Transaction): UInt256 =
|
||||
transaction.challenge
|
||||
|
||||
func proof*(transaction: Transaction): Groth16Proof =
|
||||
transaction.proof
|
||||
|
||||
func `==`*(a, b: Transaction): bool =
|
||||
if a.kind != b.kind:
|
||||
return false
|
||||
if a.requestId != b.requestId:
|
||||
return false
|
||||
if a.slotIndex != b.slotIndex:
|
||||
return false
|
||||
if a.period != b.period:
|
||||
return false
|
||||
if a.merkleRoot != b.merkleRoot:
|
||||
return false
|
||||
if a.challenge != b.challenge:
|
||||
return false
|
||||
case a.kind
|
||||
of TransactionKind.storageProof:
|
||||
a.proof == b.proof
|
||||
of TransactionKind.missingProof:
|
||||
true
|
||||
@ -1,6 +1,7 @@
|
||||
import std/random
|
||||
import codexvalidator/basics
|
||||
import codexvalidator/transaction
|
||||
import codexvalidator/signatures
|
||||
|
||||
proc example*[T: SomeInteger](_: type T): T =
|
||||
rand(T)
|
||||
@ -67,3 +68,6 @@ proc example*(_: type Transaction): Transaction =
|
||||
challenge,
|
||||
proof
|
||||
)
|
||||
|
||||
proc example*(_: type Identity): Identity =
|
||||
Identity.random(result)
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import std/unittest
|
||||
import codexvalidator/basics
|
||||
import codexvalidator/transaction
|
||||
import codexvalidator/serialization
|
||||
import codexvalidator/serialization/protobuf
|
||||
import codexvalidator/transaction/serialization
|
||||
import ./examples
|
||||
|
||||
suite "Serialization":
|
||||
suite "Transaction serialization":
|
||||
|
||||
test "serializes a transaction with protobuf":
|
||||
let transaction = Transaction.example
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import std/unittest
|
||||
import codexvalidator/basics
|
||||
import codexvalidator/signatures
|
||||
import codexvalidator/transaction
|
||||
import ./examples
|
||||
|
||||
@ -40,3 +41,20 @@ suite "Transaction":
|
||||
test "transactions have a fixed version":
|
||||
let transaction = Transaction.example
|
||||
check transaction.version == TransactionVersion.version0
|
||||
|
||||
test "transactions can be signed":
|
||||
let identity = Identity.example
|
||||
let transaction = Transaction.example
|
||||
let signed = identity.sign(transaction)
|
||||
check signed.transaction == transaction
|
||||
check signed.signer == identity.identifier
|
||||
check signed.signature == identity.sign(transaction.toBytes())
|
||||
|
||||
test "transaction signature can be verified":
|
||||
let identity = Identity.example
|
||||
let transaction = Transaction.example
|
||||
let signed = identity.sign(transaction)
|
||||
check signed.verifySignature()
|
||||
let forger = Identity.example.identifier
|
||||
let forged = SignedTransaction.init(transaction, forger, signed.signature)
|
||||
check not forged.verifySignature()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user