Calculate hashes only once

This commit is contained in:
Mark Spanbroek 2021-08-05 09:41:33 +02:00
parent 669b322311
commit db1e8b805b
2 changed files with 50 additions and 34 deletions

View File

@ -10,11 +10,24 @@ type
previous: ?Hash
transactions: seq[Hash]
validator: PublicKey
hash: Hash
signature: ?Signature
func init*(_: type Ack,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
func toBytes*(ack: Ack): seq[byte] =
let previous = ack.previous |? Hash.default
result.add(previous.toBytes)
result.add(ack.transactions.len.uint8)
for transaction in ack.transactions:
result.add(transaction.toBytes)
result.add(ack.validator.toBytes)
func init(_: type Ack,
previous: ?Hash,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
if previous =? previous and previous.kind != HashKind.Ack:
return none Ack
if transactions.len == 0:
return none Ack
@ -22,20 +35,24 @@ func init*(_: type Ack,
if transaction.kind != HashKind.Tx:
return none Ack
some Ack(transactions: @transactions, validator: validator)
var ack = Ack(
previous: previous,
transactions: @transactions,
validator: validator
)
ack.hash = hash(ack.toBytes, HashKind.Ack)
some ack
func init*(_: type Ack,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
Ack.init(Hash.none, transactions, validator)
func init*(_: type Ack,
previous: Hash,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
if previous.kind != HashKind.Ack:
return none Ack
without var ack =? Ack.init(transactions, validator):
return none Ack
ack.previous = previous.some
some ack
Ack.init(previous.some, transactions, validator)
func previous*(ack: Ack): ?Hash =
ack.previous
@ -52,16 +69,8 @@ func signature*(ack: Ack): ?Signature =
func `signature=`*(ack: var Ack, signature: Signature) =
ack.signature = signature.some
func toBytes*(ack: Ack): seq[byte] =
let previous = ack.previous |? Hash.default
result.add(previous.toBytes)
result.add(ack.transactions.len.uint8)
for transaction in ack.transactions:
result.add(transaction.toBytes)
result.add(ack.validator.toBytes)
func hash*(ack: Ack): Hash =
hash(ack.toBytes, HashKind.Ack)
ack.hash
func sign*(key: PrivateKey, ack: var Ack) =
ack.signature = key.sign(ack.hash.toBytes).some

View File

@ -16,6 +16,7 @@ type
inputs: seq[TxInput]
outputs: seq[TxOutput]
validator: PublicKey
hash: Hash
signature: Signature
TxInput* = tuple
transaction: Hash
@ -24,6 +25,17 @@ type
owner: PublicKey
value: UInt256
func toBytes*(transaction: Transaction): seq[byte] =
result.add(transaction.inputs.len.uint8)
for (txHash, owner) in transaction.inputs:
result.add(txHash.toBytes)
result.add(owner.toBytes)
result.add(transaction.outputs.len.uint8)
for (owner, value) in transaction.outputs:
result.add(owner.toBytes)
result.add(value.toBytes)
result.add(transaction.validator.toBytes)
func init*(_: type Transaction,
inputs: openArray[TxInput],
outputs: openArray[TxOutput],
@ -38,7 +50,13 @@ func init*(_: type Transaction,
if input.transaction.kind != HashKind.Tx:
return none Transaction
some Transaction(inputs: @inputs, outputs: @outputs, validator: validator)
var transaction = Transaction(
inputs: @inputs,
outputs: @outputs,
validator: validator
)
transaction.hash = hash(transaction.toBytes, HashKind.Tx)
some transaction
func init*(_: type Transaction,
outputs: openArray[TxOutput],
@ -60,19 +78,8 @@ func validator*(transaction: Transaction): PublicKey =
func add*(transaction: var Transaction, signature: Signature) =
transaction.signature = aggregate(transaction.signature, signature)
func toBytes*(transaction: Transaction): seq[byte] =
result.add(transaction.inputs.len.uint8)
for (txHash, owner) in transaction.inputs:
result.add(txHash.toBytes)
result.add(owner.toBytes)
result.add(transaction.outputs.len.uint8)
for (owner, value) in transaction.outputs:
result.add(owner.toBytes)
result.add(value.toBytes)
result.add(transaction.validator.toBytes)
func hash*(transaction: Transaction): Hash =
hash(transaction.toBytes, HashKind.Tx)
transaction.hash
func sign*(key: PrivateKey, transaction: var Transaction) =
transaction.add(key.sign(transaction.hash.toBytes))