diff --git a/codexvalidator/transaction.nim b/codexvalidator/transaction.nim index 50efd9f..b9d5029 100644 --- a/codexvalidator/transaction.nim +++ b/codexvalidator/transaction.nim @@ -1,7 +1,10 @@ import ./transaction/transaction -import ./transaction/signed import ./transaction/serialization +import ./transaction/hashing +import ./transaction/signed -export transaction -export signed +export transaction except hash export serialization.toBytes +export hashing.hash +export hashing.toBytes +export signed diff --git a/codexvalidator/transaction/hashing.nim b/codexvalidator/transaction/hashing.nim new file mode 100644 index 0000000..bbed162 --- /dev/null +++ b/codexvalidator/transaction/hashing.nim @@ -0,0 +1,12 @@ +import ../basics +import ../hashing +import ./transaction +import ./serialization + +export hashing.toBytes + +func hash*(tx: Transaction): Hash = + without var hash =? transaction.hash(tx): + hash = Hash.hash(tx.toBytes()) + tx.hash = hash + hash diff --git a/codexvalidator/transaction/signed.nim b/codexvalidator/transaction/signed.nim index 63cd42f..84a5519 100644 --- a/codexvalidator/transaction/signed.nim +++ b/codexvalidator/transaction/signed.nim @@ -1,6 +1,6 @@ import ../signatures import ./transaction -import ./serialization +import ./hashing type SignedTransaction* = object transaction: Transaction @@ -20,7 +20,8 @@ func init*( ) func sign*(identity: Identity, transaction: Transaction): SignedTransaction = - let signature = identity.sign(transaction.toBytes()) + let hash = hashing.hash(transaction) + let signature = identity.sign(hash.toBytes()) SignedTransaction.init(transaction, identity.identifier, signature) func transaction*(signed: SignedTransaction): Transaction = @@ -33,4 +34,5 @@ func signature*(signed: SignedTransaction): Signature = signed.signature func verifySignature*(signed: SignedTransaction): bool = - signed.signer.verify(signed.transaction.toBytes(), signed.signature) + let hash = hashing.hash(signed.transaction) + signed.signer.verify(hash.toBytes(), signed.signature) diff --git a/codexvalidator/transaction/transaction.nim b/codexvalidator/transaction/transaction.nim index b0c04cb..637200f 100644 --- a/codexvalidator/transaction/transaction.nim +++ b/codexvalidator/transaction/transaction.nim @@ -1,4 +1,5 @@ import ../basics +import ../hashing import ./storagerequest import ./period import ./groth16 @@ -13,7 +14,7 @@ type TransactionKind* {.pure.} = enum storageProof missingProof - Transaction* = object + Transaction* = ref object requestId: StorageRequestId slotIndex: uint32 period: Period @@ -24,6 +25,7 @@ type proof: Groth16Proof of missingProof: discard + hash: ?Hash func storageProof*( _: type Transaction, @@ -85,6 +87,12 @@ func challenge*(transaction: Transaction): array[32, byte] = func proof*(transaction: Transaction): Groth16Proof = transaction.proof +func `hash=`*(transaction: Transaction, hash: Hash) = + transaction.hash = some hash + +func hash*(transaction: Transaction): ?Hash = + transaction.hash + func `==`*(a, b: Transaction): bool = if a.kind != b.kind: return false diff --git a/tests/codexvalidator/transaction/testHashing.nim b/tests/codexvalidator/transaction/testHashing.nim new file mode 100644 index 0000000..f42d1e4 --- /dev/null +++ b/tests/codexvalidator/transaction/testHashing.nim @@ -0,0 +1,9 @@ +import ../basics +import codexvalidator/transaction +import codexvalidator/hashing + +suite "Transaction hashing": + + test "transactions have a hash derived from the serialized bytes": + let transaction = Transaction.example + check transaction.hash == Hash.hash(transaction.toBytes()) diff --git a/tests/codexvalidator/transaction/testSigning.nim b/tests/codexvalidator/transaction/testSigning.nim index e0b4694..0ee1a21 100644 --- a/tests/codexvalidator/transaction/testSigning.nim +++ b/tests/codexvalidator/transaction/testSigning.nim @@ -1,6 +1,7 @@ import ../basics import codexvalidator/signatures import codexvalidator/transaction +import codexvalidator/hashing suite "Transaction signing": @@ -10,7 +11,7 @@ suite "Transaction signing": let signed = identity.sign(transaction) check signed.transaction == transaction check signed.signer == identity.identifier - check signed.signature == identity.sign(transaction.toBytes()) + check signed.signature == identity.sign(transaction.hash.toBytes()) test "transaction signature can be verified": let identity = Identity.example diff --git a/tests/tests.nim b/tests/tests.nim index a48f16d..fc46414 100644 --- a/tests/tests.nim +++ b/tests/tests.nim @@ -1,7 +1,8 @@ import ./codexvalidator/testSignatures import ./codexvalidator/transaction/testTransaction -import ./codexvalidator/transaction/testSigning import ./codexvalidator/transaction/testSerialization +import ./codexvalidator/transaction/testHashing +import ./codexvalidator/transaction/testSigning import ./codexvalidator/blocks/testBlock import ./codexvalidator/blocks/testSerialization