nim-abc/abc/acks.nim

87 lines
2.0 KiB
Nim
Raw Normal View History

2021-06-30 15:18:19 +00:00
import pkg/questionable
import ./hash
2021-06-30 15:32:24 +00:00
import ./keys
2021-06-30 15:18:19 +00:00
export hash
2021-06-30 15:32:24 +00:00
export keys
2021-06-30 15:18:19 +00:00
type
Ack* = ref object
previous: ?Hash
transactions: seq[Hash]
validator: PublicKey
2021-08-05 07:41:33 +00:00
hash: Hash
2021-06-30 15:32:24 +00:00
signature: ?Signature
2021-06-30 15:18:19 +00:00
func calculateHash(ack: Ack) =
var hashing = Hashing.init(HashKind.Ack)
2021-08-05 07:41:33 +00:00
let previous = ack.previous |? Hash.default
hashing.update(previous.toBytes)
hashing.update([ack.transactions.len.uint8])
2021-08-05 07:41:33 +00:00
for transaction in ack.transactions:
hashing.update(transaction.toBytes)
hashing.update(ack.validator.toBytes)
ack.hash = hashing.finish()
2021-08-05 07:41:33 +00:00
func new(_: type Ack,
previous: ?Hash,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
2021-08-05 07:41:33 +00:00
if previous =? previous and previous.kind != HashKind.Ack:
return none Ack
2021-06-30 15:18:19 +00:00
if transactions.len == 0:
return none Ack
for transaction in transactions:
if transaction.kind != HashKind.Tx:
return none Ack
2021-08-05 07:41:33 +00:00
var ack = Ack(
previous: previous,
transactions: @transactions,
validator: validator
)
ack.calculateHash()
2021-08-05 07:41:33 +00:00
some ack
2021-06-30 15:18:19 +00:00
func new*(_: type Ack,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
Ack.new(Hash.none, transactions, validator)
func new*(_: type Ack,
previous: Hash,
transactions: openArray[Hash],
validator: PublicKey): ?Ack =
Ack.new(previous.some, transactions, validator)
2021-06-30 15:18:19 +00:00
func previous*(ack: Ack): ?Hash =
2021-06-30 15:18:19 +00:00
ack.previous
func transactions*(ack: Ack): seq[Hash] =
2021-06-30 15:18:19 +00:00
ack.transactions
func validator*(ack: Ack): PublicKey =
ack.validator
2021-06-30 15:32:24 +00:00
func signature*(ack: Ack): ?Signature =
ack.signature
func `signature=`*(ack: var Ack, signature: Signature) =
ack.signature = signature.some
func hash*(ack: Ack): Hash =
2021-08-05 07:41:33 +00:00
ack.hash
2021-06-30 15:32:24 +00:00
func sign*(key: PrivateKey, ack: var Ack) =
ack.signature = key.sign(ack.hash.toBytes).some
func hasValidSignature*(ack: Ack): bool =
without signature =? ack.signature:
return false
let message = ack.hash.toBytes
let signee = ack.validator
signee.verify(message, signature)