From f498228bb9030d643fd2deb23da1a91f68906bf2 Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Wed, 17 Mar 2021 12:53:30 +0100 Subject: [PATCH] Replace Channel by ChannelId --- nitro/destination.nim | 2 ++ nitro/wallet.nim | 25 ++++++++++++++----------- tests/nitro/testWallet.nim | 29 +++++++++++------------------ 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/nitro/destination.nim b/nitro/destination.nim index 44ee379..0bc6de2 100644 --- a/nitro/destination.nim +++ b/nitro/destination.nim @@ -1,3 +1,4 @@ +import std/hashes import pkg/questionable import pkg/questionable/results import pkg/stew/byteutils @@ -17,6 +18,7 @@ func parse*(_: type Destination, s: string): ?Destination = Destination(array[32, byte].fromHex(s)).catch.option func `==`*(a, b: Destination): bool {.borrow.} +func hash*(destination: Destination): Hash {.borrow.} func toDestination*(address: EthAddress): Destination = var bytes: array[32, byte] diff --git a/nitro/wallet.nim b/nitro/wallet.nim index f831177..a2a91e3 100644 --- a/nitro/wallet.nim +++ b/nitro/wallet.nim @@ -1,3 +1,4 @@ +import std/tables import ./basics import ./keys import ./protocol @@ -13,9 +14,8 @@ export channelupdate type Wallet* = object key: PrivateKey - channels*: seq[Channel] - Channel* = object - latest*: ChannelUpdate + channels: Table[ChannelId, ChannelUpdate] + ChannelId* = Destination func init*(_: type Wallet, key: PrivateKey): Wallet = result.key = key @@ -23,31 +23,34 @@ func init*(_: type Wallet, key: PrivateKey): Wallet = func address*(wallet: Wallet): EthAddress = wallet.key.toPublicKey.toAddress +func `[]`*(wallet: Wallet, channel: ChannelId): ?ChannelUpdate = + wallet.channels[channel].catch.option + func sign(wallet: Wallet, update: ChannelUpdate): ChannelUpdate = var signed = update signed.signatures &= @{wallet.address: wallet.key.sign(update.state)} signed -func createChannel(wallet: var Wallet, update: ChannelUpdate): Channel = +func createChannel(wallet: var Wallet, update: ChannelUpdate): ChannelId = let signed = wallet.sign(update) - let channel = Channel(latest: signed) - wallet.channels.add(channel) - channel + let id = getChannelId(signed.state.channel) + wallet.channels[id] = signed + id func openLedgerChannel*(wallet: var Wallet, hub: EthAddress, chainId: UInt256, nonce: UInt48, asset: EthAddress, - amount: UInt256): Channel = + amount: UInt256): ChannelId = let update = startLedger(wallet.address, hub, chainId, nonce, asset, amount) wallet.createChannel(update) -func acceptChannel*(wallet: var Wallet, update: ChannelUpdate): ?!Channel = +func acceptChannel*(wallet: var Wallet, update: ChannelUpdate): ?!ChannelId = if not update.participants.contains(wallet.address): - return Channel.failure "wallet owner is not a participant" + return ChannelId.failure "wallet owner is not a participant" if not verifySignatures(update): - return Channel.failure "incorrect signatures" + return ChannelId.failure "incorrect signatures" wallet.createChannel(update).success diff --git a/tests/nitro/testWallet.nim b/tests/nitro/testWallet.nim index 5753711..759ed9c 100644 --- a/tests/nitro/testWallet.nim +++ b/tests/nitro/testWallet.nim @@ -17,34 +17,31 @@ suite "wallet: opening ledger channel": let nonce = UInt48.example var wallet: Wallet - var channel: Channel + var channel: ChannelId setup: wallet = Wallet.init(key) channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, amount) test "sets correct channel definition": - let definition = channel.latest.state.channel + let definition = wallet[channel].get.state.channel check definition.chainId == chainId check definition.nonce == nonce check definition.participants == @[wallet.address, hub] test "provides correct outcome": - let outcome = channel.latest.state.outcome + let outcome = wallet[channel].get.state.outcome let destination = wallet.address.toDestination check outcome == Outcome.init(asset, {destination: amount}) - test "signs the upcoming state": - let state = channel.latest.state - let signatures = channel.latest.signatures + test "signs the state": + let state = wallet[channel].get.state + let signatures = wallet[channel].get.signatures check signatures == @{wallet.address: key.sign(state)} test "sets app definition and app data to zero": - check channel.latest.state.appDefinition == EthAddress.zero - check channel.latest.state.appData.len == 0 - - test "updates the list of channels": - check wallet.channels == @[channel] + check wallet[channel].get.state.appDefinition == EthAddress.zero + check wallet[channel].get.state.appData.len == 0 suite "wallet: accepting incoming channel": @@ -57,18 +54,14 @@ suite "wallet: accepting incoming channel": update = ChannelUpdate(state: State.example) update.state.channel.participants &= @[wallet.address] - test "returns the new channel instance": + test "returns the new channel id": let channel = wallet.acceptChannel(update).get - check channel.latest.state == update.state - - test "updates the list of channels": - let channel = wallet.acceptChannel(update).get - check wallet.channels == @[channel] + check wallet[channel].get.state == update.state test "signs the channel state": let channel = wallet.acceptChannel(update).get let expectedSignatures = @{wallet.address: key.sign(update.state)} - check channel.latest.signatures == expectedSignatures + check wallet[channel].get.signatures == expectedSignatures test "fails when wallet address is not a participant": let wrongParticipants = seq[EthAddress].example