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
|
2021-08-05 08:16:38 +00:00
|
|
|
Ack* = ref object
|
2021-08-02 08:54:58 +00:00
|
|
|
previous: ?Hash
|
|
|
|
transactions: seq[Hash]
|
2021-07-05 09:07:47 +00:00
|
|
|
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
|
|
|
|
2021-09-01 11:00:32 +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
|
2021-09-01 11:00:32 +00:00
|
|
|
hashing.update(previous.toBytes)
|
|
|
|
hashing.update([ack.transactions.len.uint8])
|
2021-08-05 07:41:33 +00:00
|
|
|
for transaction in ack.transactions:
|
2021-09-01 11:00:32 +00:00
|
|
|
hashing.update(transaction.toBytes)
|
|
|
|
hashing.update(ack.validator.toBytes)
|
|
|
|
ack.hash = hashing.finish()
|
2021-08-05 07:41:33 +00:00
|
|
|
|
2021-08-05 08:16:38 +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
|
|
|
|
|
2021-08-02 08:54:58 +00:00
|
|
|
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
|
|
|
|
)
|
2021-09-01 11:00:32 +00:00
|
|
|
ack.calculateHash()
|
2021-08-05 07:41:33 +00:00
|
|
|
some ack
|
2021-06-30 15:18:19 +00:00
|
|
|
|
2021-08-05 08:16:38 +00:00
|
|
|
func new*(_: type Ack,
|
|
|
|
transactions: openArray[Hash],
|
|
|
|
validator: PublicKey): ?Ack =
|
|
|
|
Ack.new(Hash.none, transactions, validator)
|
2021-08-02 08:54:58 +00:00
|
|
|
|
2021-08-05 08:16:38 +00:00
|
|
|
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
|
|
|
|
2021-08-02 08:54:58 +00:00
|
|
|
func previous*(ack: Ack): ?Hash =
|
2021-06-30 15:18:19 +00:00
|
|
|
ack.previous
|
|
|
|
|
2021-08-02 08:54:58 +00:00
|
|
|
func transactions*(ack: Ack): seq[Hash] =
|
2021-06-30 15:18:19 +00:00
|
|
|
ack.transactions
|
|
|
|
|
2021-07-05 09:07:47 +00:00
|
|
|
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
|
|
|
|
|
2021-08-02 08:54:58 +00:00
|
|
|
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
|
2021-07-05 09:07:47 +00:00
|
|
|
|
|
|
|
func hasValidSignature*(ack: Ack): bool =
|
|
|
|
without signature =? ack.signature:
|
|
|
|
return false
|
|
|
|
|
|
|
|
let message = ack.hash.toBytes
|
|
|
|
let signee = ack.validator
|
|
|
|
signee.verify(message, signature)
|