mirror of
https://github.com/logos-storage/logos-storage-nim-validator.git
synced 2026-05-05 01:03:06 +00:00
deserialize transaction
This commit is contained in:
parent
4e86fcb581
commit
54d5c89122
@ -1,8 +1,10 @@
|
||||
import ./transaction/transaction
|
||||
import ./transaction/serialization
|
||||
import ./transaction/deserialization
|
||||
import ./transaction/hashing
|
||||
|
||||
export transaction except hash
|
||||
export serialization.toBytes
|
||||
export deserialization.fromBytes
|
||||
export hashing.hash
|
||||
export hashing.toBytes
|
||||
|
||||
90
codexvalidator/transaction/deserialization.nim
Normal file
90
codexvalidator/transaction/deserialization.nim
Normal file
@ -0,0 +1,90 @@
|
||||
import ../basics
|
||||
import ../signatures
|
||||
import ./transaction
|
||||
import ./groth16
|
||||
import ./serialization
|
||||
|
||||
func fromBytes(
|
||||
_: type array[32, byte],
|
||||
bytes: openArray[byte]
|
||||
): ?!array[32, byte] =
|
||||
if bytes.len != 32:
|
||||
failure "expected 32 bytes but got: " & $bytes.len
|
||||
else:
|
||||
var bytes32: array[32, byte]
|
||||
bytes32[0..<32] = bytes[0..<32]
|
||||
success bytes32
|
||||
|
||||
func fromBytes(
|
||||
_: type StorageRequestId,
|
||||
bytes: openArray[byte]
|
||||
): ?!StorageRequestId =
|
||||
success StorageRequestId(? array[32, byte].fromBytes(bytes))
|
||||
|
||||
func init(_: type Groth16Proof, message: Groth16ProofMessage): Groth16Proof =
|
||||
Groth16Proof.init(
|
||||
G1Point.init(
|
||||
UInt256.fromBytesBE(message.a.x),
|
||||
UInt256.fromBytesBE(message.a.y)
|
||||
),
|
||||
G2Point.init(
|
||||
Fp2Element.init(
|
||||
UInt256.fromBytesBE(message.b.x.real),
|
||||
UInt256.fromBytesBE(message.b.x.imag)
|
||||
),
|
||||
Fp2Element.init(
|
||||
UInt256.fromBytesBE(message.b.y.real),
|
||||
UInt256.fromBytesBE(message.b.y.imag)
|
||||
)
|
||||
),
|
||||
G1Point.init(
|
||||
UInt256.fromBytesBE(message.c.x),
|
||||
UInt256.fromBytesBE(message.c.y)
|
||||
)
|
||||
)
|
||||
|
||||
func init(_: type Transaction, message: TransactionMessage): ?!Transaction =
|
||||
if message.version != TransactionVersion.version0.uint32:
|
||||
return failure "unsupported transaction version: " & $message.version
|
||||
let requestId = ? StorageRequestId.fromBytes(message.requestId)
|
||||
let slotIndex = message.slotIndex
|
||||
let period = Period(message.period)
|
||||
let merkleRoot = ? array[32, byte].fromBytes(message.merkleRoot)
|
||||
let challenge = ? array[32, byte].fromBytes(message.challenge)
|
||||
case message.kind
|
||||
of TransactionKind.storageProof.uint32:
|
||||
success Transaction.storageProof(
|
||||
requestId,
|
||||
slotIndex,
|
||||
period,
|
||||
merkleRoot,
|
||||
challenge,
|
||||
Groth16Proof.init(message.proof)
|
||||
)
|
||||
of TransactionKind.missingProof.uint32:
|
||||
success Transaction.missingProof(
|
||||
requestId,
|
||||
message.slotIndex,
|
||||
period,
|
||||
merkleRoot,
|
||||
challenge,
|
||||
)
|
||||
else:
|
||||
failure "invalid transaction kind: " & $message.kind
|
||||
|
||||
func init(
|
||||
_: type Signed[Transaction],
|
||||
message: SignedTransactionMessage
|
||||
): ?!Signed[Transaction] =
|
||||
success Signed[Transaction].init(
|
||||
? Transaction.init(message.transaction),
|
||||
? Identifier.fromBytes(message.signer),
|
||||
? Signature.fromBytes(message.signature)
|
||||
)
|
||||
|
||||
func fromBytes*(
|
||||
_: type Signed[Transaction],
|
||||
bytes: openArray[byte]
|
||||
): ?!Signed[Transaction] =
|
||||
let message = ? Protobuf.decode(bytes, SignedTransactionMessage).catch()
|
||||
Signed[Transaction].init(message)
|
||||
@ -80,6 +80,9 @@ proc example*(_: type Identifier): Identifier =
|
||||
proc example*(_: type Signature): Signature =
|
||||
Identity.example.sign(seq[byte].example)
|
||||
|
||||
proc example*[T](_: type Signed[T]): Signed[T] =
|
||||
Signed.sign(Identity.example, T.example)
|
||||
|
||||
proc example*(_: type CommitteeMember): CommitteeMember =
|
||||
CommitteeMember(uint32.example.int)
|
||||
|
||||
|
||||
@ -41,11 +41,84 @@ suite "Transaction serialization":
|
||||
check protobuf.proof.c.y == transaction.proof.c.y.toBytesBE()
|
||||
|
||||
test "serializes a signed transaction with protobuf":
|
||||
let transaction = Transaction.example
|
||||
let identity = Identity.example
|
||||
let signed = Signed.sign(identity, transaction)
|
||||
let signed = Signed[Transaction].example
|
||||
let serialized = signed.toBytes()
|
||||
let protobuf = Protobuf.decode(serialized, SignedTransactionMessage)
|
||||
check protobuf.transaction == TransactionMessage.init(transaction)
|
||||
check protobuf.transaction == TransactionMessage.init(signed.value)
|
||||
check protobuf.signer == signed.signer.toBytes()
|
||||
check protobuf.signature == signed.signature.toBytes()
|
||||
|
||||
test "deserializes a signed transaction":
|
||||
let signed = Signed[Transaction].example
|
||||
let serialized = signed.toBytes()
|
||||
let deserialized = Signed[Transaction].fromBytes(serialized)
|
||||
check deserialized == success signed
|
||||
|
||||
test "deserialization fails when protobuf encoding is invalid":
|
||||
let invalid = seq[byte].example
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "Invalid wire type"
|
||||
|
||||
test "deserialization fails when signer is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.signer &= 42'u8
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "invalid identifier"
|
||||
|
||||
test "deserialization fails when signature is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.signature &= 42'u8
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "invalid signature"
|
||||
|
||||
test "deserialization fails when transaction version is unsupported":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.transaction.version = 42
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "unsupported transaction version: 42"
|
||||
|
||||
test "deserialization fails when transaction kind is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.transaction.kind = 42
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "invalid transaction kind: 42"
|
||||
|
||||
test "deserialization fails when storage request id is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.transaction.requestid &= 42'u8
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "expected 32 bytes but got: 33"
|
||||
|
||||
test "deserialization fails when merkle root is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.transaction.merkleRoot &= 42'u8
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "expected 32 bytes but got: 33"
|
||||
|
||||
test "deserialization fails when challenge is invalid":
|
||||
let signed = Signed[Transaction].example
|
||||
var message = SignedTransactionMessage.init(signed)
|
||||
message.transaction.challenge &= 42'u8
|
||||
let invalid = Protobuf.encode(message)
|
||||
let deserialized = Signed[Transaction].fromBytes(invalid)
|
||||
check deserialized.isFailure
|
||||
check deserialized.errorOption.?msg == some "expected 32 bytes but got: 33"
|
||||
|
||||
@ -1 +1,2 @@
|
||||
--path:".."
|
||||
--warning[DotLikeOps]:off
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user