Pass TxStore instances by reference

This commit is contained in:
Mark Spanbroek 2021-07-14 17:10:26 +02:00
parent 6c4fc39acf
commit 76006f4b73
3 changed files with 16 additions and 24 deletions

View File

@ -4,7 +4,7 @@ import ./transactions
import ./acks import ./acks
type type
TxStore* = object TxStore* = ref object
genesis: TxHash genesis: TxHash
transactions: Table[TxHash, Transaction] transactions: Table[TxHash, Transaction]
acks: Table[AckHash, Ack] acks: Table[AckHash, Ack]
@ -13,17 +13,18 @@ export questionable
export transactions export transactions
export acks export acks
func add*(store: var TxStore, transactions: varargs[Transaction]) = func add*(store: TxStore, transactions: varargs[Transaction]) =
for transaction in transactions: for transaction in transactions:
store.transactions[transaction.hash] = transaction store.transactions[transaction.hash] = transaction
func add*(store: var TxStore, acks: varargs[Ack]) = func add*(store: TxStore, acks: varargs[Ack]) =
for ack in acks: for ack in acks:
store.acks[ack.hash] = ack store.acks[ack.hash] = ack
func init*(_: type TxStore, genesis: Transaction): TxStore = func new*(_: type TxStore, genesis: Transaction): TxStore =
result.genesis = genesis.hash let store = TxStore(genesis: genesis.hash)
result.add(genesis) store.add(genesis)
store
func genesis*(store: TxStore): TxHash = func genesis*(store: TxStore): TxHash =
store.genesis store.genesis

View File

@ -12,10 +12,12 @@ suite "Past transactions and acknowledgements":
let alice = PublicKey.alice let alice = PublicKey.alice
let bob = PublicKey.bob let bob = PublicKey.bob
let victor = PublicKey.victor let victor = PublicKey.victor
var store: TxStore
var tx1, tx2, tx3: Transaction var tx1, tx2, tx3: Transaction
var ack1, ack2, ack3: Ack var ack1, ack2, ack3: Ack
setup: setup:
store = TxStore.new(genesis)
tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor) tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor)
tx2 = !Transaction.init({genesis.hash: bob}, {alice: 100.u256}, victor) tx2 = !Transaction.init({genesis.hash: bob}, {alice: 100.u256}, victor)
tx3 = !Transaction.init( tx3 = !Transaction.init(
@ -35,7 +37,6 @@ suite "Past transactions and acknowledgements":
PrivateKey.victor.sign(ack3) PrivateKey.victor.sign(ack3)
test "finds all transactions that precede a transaction": test "finds all transactions that precede a transaction":
var store = TxStore.init(genesis)
store.add(tx1, tx2, tx3) store.add(tx1, tx2, tx3)
check store.past(tx1.hash).transactions == set(genesis.hash) check store.past(tx1.hash).transactions == set(genesis.hash)
check store.past(tx2.hash).transactions == set(genesis.hash) check store.past(tx2.hash).transactions == set(genesis.hash)
@ -43,11 +44,9 @@ suite "Past transactions and acknowledgements":
set(genesis.hash, tx1.hash, tx2.hash) set(genesis.hash, tx1.hash, tx2.hash)
test "past is empty when transaction cannot be found": test "past is empty when transaction cannot be found":
let store = TxStore.init(genesis)
check store.past(tx1.hash).transactions == set[TxHash]() check store.past(tx1.hash).transactions == set[TxHash]()
test "finds all transactions that precede an acknowledgement": test "finds all transactions that precede an acknowledgement":
var store = TxStore.init(genesis)
store.add(tx1, tx2, tx3) store.add(tx1, tx2, tx3)
store.add(ack1, ack2, ack3) store.add(ack1, ack2, ack3)
check store.past(ack1.hash).transactions == set(genesis.hash, tx1.hash) check store.past(ack1.hash).transactions == set(genesis.hash, tx1.hash)
@ -56,14 +55,12 @@ suite "Past transactions and acknowledgements":
set(genesis.hash, tx1.hash, tx2.hash, tx3.hash) set(genesis.hash, tx1.hash, tx2.hash, tx3.hash)
test "finds all transactions that precede a set of acknowledgements": test "finds all transactions that precede a set of acknowledgements":
var store = TxStore.init(genesis)
store.add(tx1, tx2, tx3) store.add(tx1, tx2, tx3)
store.add(ack1, ack2, ack3) store.add(ack1, ack2, ack3)
check store.past(ack1.hash, ack2.hash).transactions == check store.past(ack1.hash, ack2.hash).transactions ==
set(genesis.hash, tx1.hash, tx2.hash) set(genesis.hash, tx1.hash, tx2.hash)
test "past contains the genesis hash": test "past contains the genesis hash":
var store = TxStore.init(genesis)
store.add(tx1, tx3) store.add(tx1, tx3)
store.add(ack3) store.add(ack3)
check store.past(tx1.hash).genesis == store.genesis check store.past(tx1.hash).genesis == store.genesis
@ -76,30 +73,29 @@ suite "Transaction validation":
let bob = PublicKey.bob let bob = PublicKey.bob
let victor = PublicKey.victor let victor = PublicKey.victor
let genesis = Transaction.genesis let genesis = Transaction.genesis
var store: TxStore
var tx1, tx2: Transaction var tx1, tx2: Transaction
setup: setup:
store = TxStore.new(genesis)
tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor) tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor)
tx2 = !Transaction.init({tx1.hash: bob}, {alice: 100.u256}, victor) tx2 = !Transaction.init({tx1.hash: bob}, {alice: 100.u256}, victor)
PrivateKey.alice.sign(tx1) PrivateKey.alice.sign(tx1)
PrivateKey.bob.sign(tx2) PrivateKey.bob.sign(tx2)
test "checks validity of transactions": test "checks validity of transactions":
var store = TxStore.init(genesis)
store.add(tx1, tx2) store.add(tx1, tx2)
check isValid store.past(genesis.hash) check isValid store.past(genesis.hash)
check isValid store.past(tx1.hash) check isValid store.past(tx1.hash)
check isValid store.past(tx2.hash) check isValid store.past(tx2.hash)
test "checks that no input is missing": test "checks that no input is missing":
var store = TxStore.init(genesis)
store.add(tx2) # tx2 depends on tx1, which is missing store.add(tx2) # tx2 depends on tx1, which is missing
let past = store.past(tx2.hash) let past = store.past(tx2.hash)
check not isValid past check not isValid past
check past.missingTx == set(tx1.hash) check past.missingTx == set(tx1.hash)
test "checks that inputs and outputs match": test "checks that inputs and outputs match":
var store = TxStore.init(genesis)
var bad1 = !Transaction.init({genesis.hash: alice}, {bob: 999.u256}, victor) var bad1 = !Transaction.init({genesis.hash: alice}, {bob: 999.u256}, victor)
var bad2 = !Transaction.init({bad1.hash: bob}, {alice: 999.u256}, victor) var bad2 = !Transaction.init({bad1.hash: bob}, {alice: 999.u256}, victor)
PrivateKey.alice.sign(bad1) PrivateKey.alice.sign(bad1)
@ -111,7 +107,6 @@ suite "Transaction validation":
check past.invalidTx == set(bad1.hash) check past.invalidTx == set(bad1.hash)
test "checks that signatures match": test "checks that signatures match":
var store = TxStore.init(genesis)
var bad1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor) var bad1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor)
var bad2 = !Transaction.init({bad1.hash: bob}, {alice: 100.u256}, victor) var bad2 = !Transaction.init({bad1.hash: bob}, {alice: 100.u256}, victor)
PrivateKey.bob.sign(bad1) # invalid signature, should be signed by alice PrivateKey.bob.sign(bad1) # invalid signature, should be signed by alice
@ -128,10 +123,12 @@ suite "Acknowledgement validation":
let bob = PublicKey.bob let bob = PublicKey.bob
let victor = PublicKey.victor let victor = PublicKey.victor
let genesis = Transaction.genesis let genesis = Transaction.genesis
var store: TxStore
var tx1, tx2: Transaction var tx1, tx2: Transaction
var ack1, ack2: Ack var ack1, ack2: Ack
setup: setup:
store = TxStore.new(genesis)
tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor) tx1 = !Transaction.init({genesis.hash: alice}, {bob: 100.u256}, victor)
tx2 = !Transaction.init({tx1.hash: bob}, {alice: 100.u256}, victor) tx2 = !Transaction.init({tx1.hash: bob}, {alice: 100.u256}, victor)
ack1 = !Ack.init([tx1.hash], victor) ack1 = !Ack.init([tx1.hash], victor)
@ -142,14 +139,12 @@ suite "Acknowledgement validation":
PrivateKey.victor.sign(ack2) PrivateKey.victor.sign(ack2)
test "checks validity of acknowledgements": test "checks validity of acknowledgements":
var store = TxStore.init(genesis)
store.add(tx1, tx2) store.add(tx1, tx2)
store.add(ack1, ack2) store.add(ack1, ack2)
check isValid store.past(ack1.hash) check isValid store.past(ack1.hash)
check isValid store.past(ack2.hash) check isValid store.past(ack2.hash)
test "checks that no previous acknowledgement is missing": test "checks that no previous acknowledgement is missing":
var store = TxStore.init(genesis)
store.add(tx1, tx2) store.add(tx1, tx2)
store.add(ack2) # ack2 depends on ack1, which is missing store.add(ack2) # ack2 depends on ack1, which is missing
let past = store.past(ack2.hash) let past = store.past(ack2.hash)
@ -157,7 +152,6 @@ suite "Acknowledgement validation":
check past.missingAck == set(ack1.hash) check past.missingAck == set(ack1.hash)
test "checks that no transaction is missing": test "checks that no transaction is missing":
var store = TxStore.init(genesis)
store.add(tx2) # tx2 depends on tx1, which is missing store.add(tx2) # tx2 depends on tx1, which is missing
store.add(ack1, ack2) store.add(ack1, ack2)
let past = store.past(ack2.hash) let past = store.past(ack2.hash)
@ -165,7 +159,6 @@ suite "Acknowledgement validation":
check past.missingTx == set(tx1.hash) check past.missingTx == set(tx1.hash)
test "checks that no transaction is invalid": test "checks that no transaction is invalid":
var store = TxStore.init(genesis)
var bad = !Transaction.init({genesis.hash: alice}, {bob: 999.u256}, victor) var bad = !Transaction.init({genesis.hash: alice}, {bob: 999.u256}, victor)
var ack = !Ack.init([bad.hash], victor) var ack = !Ack.init([bad.hash], victor)
PrivateKey.alice.sign(bad) PrivateKey.alice.sign(bad)
@ -177,7 +170,6 @@ suite "Acknowledgement validation":
check past.invalidTx == set(bad.hash) check past.invalidTx == set(bad.hash)
test "checks that signatures match": test "checks that signatures match":
var store = TxStore.init(genesis)
var bad1 = !Ack.init([tx1.hash], victor) var bad1 = !Ack.init([tx1.hash], victor)
var bad2 = !Ack.init(bad1.hash, [tx2.hash], victor) var bad2 = !Ack.init(bad1.hash, [tx2.hash], victor)
PrivateKey.bob.sign(bad1) # invalid signature, should be signed by victor PrivateKey.bob.sign(bad1) # invalid signature, should be signed by victor
@ -190,7 +182,6 @@ suite "Acknowledgement validation":
check past.invalidAck == set(bad1.hash) check past.invalidAck == set(bad1.hash)
test "checks validity of a set of acknowledgements": test "checks validity of a set of acknowledgements":
var store = TxStore.init(genesis)
store.add(tx1, tx2) store.add(tx1, tx2)
store.add(ack2) store.add(ack2)
check not isValid store.past(ack1.hash, ack2.hash) check not isValid store.past(ack1.hash, ack2.hash)

View File

@ -9,17 +9,17 @@ suite "Transaction Store":
let ack = Ack.example let ack = Ack.example
test "is initialized with a genesis transaction": test "is initialized with a genesis transaction":
let store = TxStore.init(genesis) let store = TxStore.new(genesis)
check store[genesis.hash] == genesis.some check store[genesis.hash] == genesis.some
test "stores transactions": test "stores transactions":
var store = TxStore.init(genesis) let store = TxStore.new(genesis)
check store[transaction.hash].isNone check store[transaction.hash].isNone
store.add(transaction) store.add(transaction)
check store[transaction.hash] == transaction.some check store[transaction.hash] == transaction.some
test "stores acks": test "stores acks":
var store = TxStore.init(genesis) let store = TxStore.new(genesis)
check store[ack.hash].isNone check store[ack.hash].isNone
store.add(ack) store.add(ack)
check store[ack.hash] == ack.some check store[ack.hash] == ack.some