mirror of
https://github.com/logos-storage/nim-nitro.git
synced 2026-01-05 23:23:07 +00:00
Update to latest version of questionable
This commit is contained in:
parent
76cc0a9bcc
commit
85ffad6fb1
@ -1,11 +1,11 @@
|
|||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
author = "Nim Nitro developers"
|
author = "Nim Nitro developers"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
description = "Nitro state channels"
|
description = "Nitro state channels"
|
||||||
|
|
||||||
requires "nim >= 1.2.6 & < 2.0.0"
|
requires "nim >= 1.2.6 & < 2.0.0"
|
||||||
requires "nimcrypto >= 0.5.4 & < 0.6.0"
|
requires "nimcrypto >= 0.5.4 & < 0.6.0"
|
||||||
requires "questionable >= 0.5.0 & < 0.6.0"
|
requires "questionable >= 0.6.2 & < 0.7.0"
|
||||||
requires "upraises >= 0.1.0 & < 0.2.0"
|
requires "upraises >= 0.1.0 & < 0.2.0"
|
||||||
requires "secp256k1"
|
requires "secp256k1"
|
||||||
requires "stint"
|
requires "stint"
|
||||||
|
|||||||
@ -31,7 +31,7 @@ func move*(balances: var Balances,
|
|||||||
amount: UInt256): ?!void =
|
amount: UInt256): ?!void =
|
||||||
try:
|
try:
|
||||||
if balances[source] < amount:
|
if balances[source] < amount:
|
||||||
return void.failure "insufficient funds"
|
return failure "insufficient funds"
|
||||||
|
|
||||||
balances[source] -= amount
|
balances[source] -= amount
|
||||||
if (balances.contains(destination)):
|
if (balances.contains(destination)):
|
||||||
@ -39,6 +39,6 @@ func move*(balances: var Balances,
|
|||||||
else:
|
else:
|
||||||
balances[destination] = amount
|
balances[destination] = amount
|
||||||
|
|
||||||
ok()
|
success()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
void.failure "no funds"
|
failure "no funds"
|
||||||
|
|||||||
@ -48,10 +48,10 @@ func incNonce(wallet: var Wallet, state: SignedState) =
|
|||||||
func createChannel(wallet: var Wallet, state: SignedState): ?!ChannelId =
|
func createChannel(wallet: var Wallet, state: SignedState): ?!ChannelId =
|
||||||
let id = getChannelId(state.state.channel)
|
let id = getChannelId(state.state.channel)
|
||||||
if wallet.channels.contains(id):
|
if wallet.channels.contains(id):
|
||||||
return ChannelId.failure("channel with id " & $id & " already exists")
|
return failure "channel with id " & $id & " already exists"
|
||||||
wallet.channels[id] = wallet.sign(state)
|
wallet.channels[id] = wallet.sign(state)
|
||||||
wallet.incNonce(state)
|
wallet.incNonce(state)
|
||||||
ok id
|
success id
|
||||||
|
|
||||||
func updateChannel(wallet: var Wallet, state: SignedState) =
|
func updateChannel(wallet: var Wallet, state: SignedState) =
|
||||||
let signed = wallet.sign(state)
|
let signed = wallet.sign(state)
|
||||||
@ -77,10 +77,10 @@ func openLedgerChannel*(wallet: var Wallet,
|
|||||||
|
|
||||||
func acceptChannel*(wallet: var Wallet, signed: SignedState): ?!ChannelId =
|
func acceptChannel*(wallet: var Wallet, signed: SignedState): ?!ChannelId =
|
||||||
if not signed.hasParticipant(wallet.address):
|
if not signed.hasParticipant(wallet.address):
|
||||||
return ChannelId.failure "wallet owner is not a participant"
|
return failure "wallet owner is not a participant"
|
||||||
|
|
||||||
if not verifySignatures(signed):
|
if not verifySignatures(signed):
|
||||||
return ChannelId.failure "incorrect signatures"
|
return failure "incorrect signatures"
|
||||||
|
|
||||||
wallet.createChannel(signed)
|
wallet.createChannel(signed)
|
||||||
|
|
||||||
@ -155,11 +155,11 @@ func pay*(wallet: var Wallet,
|
|||||||
?balances.move(wallet.destination, receiver, amount)
|
?balances.move(wallet.destination, receiver, amount)
|
||||||
state.outcome.update(asset, balances)
|
state.outcome.update(asset, balances)
|
||||||
wallet.updateChannel(SignedState(state: state))
|
wallet.updateChannel(SignedState(state: state))
|
||||||
ok(wallet.channels.?[channel].get)
|
success wallet.channels.?[channel].get
|
||||||
else:
|
else:
|
||||||
SignedState.failure "asset not found"
|
failure "asset not found"
|
||||||
else:
|
else:
|
||||||
SignedState.failure "channel not found"
|
failure "channel not found"
|
||||||
|
|
||||||
func pay*(wallet: var Wallet,
|
func pay*(wallet: var Wallet,
|
||||||
channel: ChannelId,
|
channel: ChannelId,
|
||||||
@ -174,31 +174,31 @@ func acceptPayment*(wallet: var Wallet,
|
|||||||
sender: EthAddress,
|
sender: EthAddress,
|
||||||
payment: SignedState): ?!void =
|
payment: SignedState): ?!void =
|
||||||
if not wallet.channels.contains(channel):
|
if not wallet.channels.contains(channel):
|
||||||
return void.failure "unknown channel"
|
return failure "unknown channel"
|
||||||
|
|
||||||
if not (getChannelId(payment.state.channel) == channel):
|
if not (getChannelId(payment.state.channel) == channel):
|
||||||
return void.failure "payment does not match channel"
|
return failure "payment does not match channel"
|
||||||
|
|
||||||
let currentBalance = wallet.balance(channel, asset)
|
let currentBalance = wallet.balance(channel, asset)
|
||||||
let futureBalance = payment.state.balance(asset, wallet.destination)
|
let futureBalance = payment.state.balance(asset, wallet.destination)
|
||||||
if futureBalance <= currentBalance:
|
if futureBalance <= currentBalance:
|
||||||
return void.failure "payment should not decrease balance"
|
return failure "payment should not decrease balance"
|
||||||
|
|
||||||
let currentTotal = wallet.total(channel, asset)
|
let currentTotal = wallet.total(channel, asset)
|
||||||
let futureTotal = payment.state.total(asset)
|
let futureTotal = payment.state.total(asset)
|
||||||
if futureTotal != currentTotal:
|
if futureTotal != currentTotal:
|
||||||
return void.failure "total supply of asset should not change"
|
return failure "total supply of asset should not change"
|
||||||
|
|
||||||
if not payment.isSignedBy(sender):
|
if not payment.isSignedBy(sender):
|
||||||
return void.failure "missing signature on payment"
|
return failure "missing signature on payment"
|
||||||
|
|
||||||
if updatedBalances =? payment.state.outcome.balances(asset):
|
if updatedBalances =? payment.state.outcome.balances(asset):
|
||||||
var expectedState: State = wallet.channels.?[channel].?state.get
|
var expectedState: State = wallet.channels.?[channel].?state.get
|
||||||
expectedState.outcome.update(asset, updatedBalances)
|
expectedState.outcome.update(asset, updatedBalances)
|
||||||
if payment.state != expectedState:
|
if payment.state != expectedState:
|
||||||
return void.failure "payment has unexpected changes in state"
|
return failure "payment has unexpected changes in state"
|
||||||
else:
|
else:
|
||||||
return void.failure "payment misses balances for asset"
|
return failure "payment misses balances for asset"
|
||||||
|
|
||||||
wallet.channels[channel] = payment
|
wallet.channels[channel] = payment
|
||||||
ok()
|
success()
|
||||||
|
|||||||
@ -51,7 +51,7 @@ suite "wallet: opening ledger channel":
|
|||||||
check wallet.state(channel).get.appData.len == 0
|
check wallet.state(channel).get.appData.len == 0
|
||||||
|
|
||||||
test "does not allow opening a channel that already exists":
|
test "does not allow opening a channel that already exists":
|
||||||
check wallet.openLedgerChannel(hub, chainId, nonce, asset, amount).isErr
|
check wallet.openLedgerChannel(hub, chainId, nonce, asset, amount).isFailure
|
||||||
|
|
||||||
suite "wallet: accepting incoming channel":
|
suite "wallet: accepting incoming channel":
|
||||||
|
|
||||||
@ -76,15 +76,15 @@ suite "wallet: accepting incoming channel":
|
|||||||
test "fails when wallet address is not a participant":
|
test "fails when wallet address is not a participant":
|
||||||
let wrongParticipants = seq[EthAddress].example
|
let wrongParticipants = seq[EthAddress].example
|
||||||
signed.state.channel.participants = wrongParticipants
|
signed.state.channel.participants = wrongParticipants
|
||||||
check wallet.acceptChannel(signed).isErr
|
check wallet.acceptChannel(signed).isFailure
|
||||||
|
|
||||||
test "fails when signatures are incorrect":
|
test "fails when signatures are incorrect":
|
||||||
signed.signatures = @[key.sign(State.example)]
|
signed.signatures = @[key.sign(State.example)]
|
||||||
check wallet.acceptChannel(signed).isErr
|
check wallet.acceptChannel(signed).isFailure
|
||||||
|
|
||||||
test "fails when channel with this id already exists":
|
test "fails when channel with this id already exists":
|
||||||
check wallet.acceptChannel(signed).isOk
|
check wallet.acceptChannel(signed).isSuccess
|
||||||
check wallet.acceptChannel(signed).isErr
|
check wallet.acceptChannel(signed).isFailure
|
||||||
|
|
||||||
suite "wallet: making payments":
|
suite "wallet: making payments":
|
||||||
|
|
||||||
@ -101,18 +101,18 @@ suite "wallet: making payments":
|
|||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 100.u256).get
|
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 100.u256).get
|
||||||
|
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isOk
|
check wallet.pay(channel, asset, hub, 1.u256).isSuccess
|
||||||
check wallet.balance(channel, asset) == 99.u256
|
check wallet.balance(channel, asset) == 99.u256
|
||||||
check wallet.balance(channel, asset, hub) == 1.u256
|
check wallet.balance(channel, asset, hub) == 1.u256
|
||||||
|
|
||||||
check wallet.pay(channel, asset, hub, 2.u256).isOk
|
check wallet.pay(channel, asset, hub, 2.u256).isSuccess
|
||||||
check wallet.balance(channel, asset) == 97.u256
|
check wallet.balance(channel, asset) == 97.u256
|
||||||
check wallet.balance(channel, asset, hub) == 3.u256
|
check wallet.balance(channel, asset, hub) == 3.u256
|
||||||
|
|
||||||
test "paying updates signatures":
|
test "paying updates signatures":
|
||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 100.u256).get
|
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 100.u256).get
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isOk
|
check wallet.pay(channel, asset, hub, 1.u256).isSuccess
|
||||||
let expectedSignature = key.sign(wallet.state(channel).get)
|
let expectedSignature = key.sign(wallet.state(channel).get)
|
||||||
check wallet.signature(channel, wallet.address) == expectedSignature.some
|
check wallet.signature(channel, wallet.address) == expectedSignature.some
|
||||||
|
|
||||||
@ -125,14 +125,14 @@ suite "wallet: making payments":
|
|||||||
|
|
||||||
test "payment fails when channel not found":
|
test "payment fails when channel not found":
|
||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isErr
|
check wallet.pay(channel, asset, hub, 1.u256).isFailure
|
||||||
|
|
||||||
test "payment fails when asset not found":
|
test "payment fails when asset not found":
|
||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
var state = State.example
|
var state = State.example
|
||||||
state.channel.participants &= wallet.address
|
state.channel.participants &= wallet.address
|
||||||
channel = wallet.acceptChannel(SignedState(state: state)).get
|
channel = wallet.acceptChannel(SignedState(state: state)).get
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isErr
|
check wallet.pay(channel, asset, hub, 1.u256).isFailure
|
||||||
|
|
||||||
test "payment fails when payer has no allocation":
|
test "payment fails when payer has no allocation":
|
||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
@ -140,13 +140,13 @@ suite "wallet: making payments":
|
|||||||
state.channel = ChannelDefinition(participants: @[wallet.address])
|
state.channel = ChannelDefinition(participants: @[wallet.address])
|
||||||
state.outcome = Outcome.init(asset, @[])
|
state.outcome = Outcome.init(asset, @[])
|
||||||
channel = wallet.acceptChannel(SignedState(state: state)).get
|
channel = wallet.acceptChannel(SignedState(state: state)).get
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isErr
|
check wallet.pay(channel, asset, hub, 1.u256).isFailure
|
||||||
|
|
||||||
test "payment fails when payer has insufficient funds":
|
test "payment fails when payer has insufficient funds":
|
||||||
wallet = Wallet.init(key)
|
wallet = Wallet.init(key)
|
||||||
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 1.u256).get
|
channel = wallet.openLedgerChannel(hub, chainId, nonce, asset, 1.u256).get
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isOk
|
check wallet.pay(channel, asset, hub, 1.u256).isSuccess
|
||||||
check wallet.pay(channel, asset, hub, 1.u256).isErr
|
check wallet.pay(channel, asset, hub, 1.u256).isFailure
|
||||||
|
|
||||||
suite "wallet: accepting payments":
|
suite "wallet: accepting payments":
|
||||||
|
|
||||||
@ -168,15 +168,15 @@ suite "wallet: accepting payments":
|
|||||||
|
|
||||||
test "updates channel state":
|
test "updates channel state":
|
||||||
let payment = payer.pay(channel, asset, receiver.address, 42.u256).get
|
let payment = payer.pay(channel, asset, receiver.address, 42.u256).get
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isOk
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isSuccess
|
||||||
check receiver.balance(channel, asset) == 42.u256
|
check receiver.balance(channel, asset) == 42.u256
|
||||||
|
|
||||||
test "fails when receiver balance is decreased":
|
test "fails when receiver balance is decreased":
|
||||||
let payment1 = payer.pay(channel, asset, receiver.address, 10.u256).get
|
let payment1 = payer.pay(channel, asset, receiver.address, 10.u256).get
|
||||||
let payment2 = payer.pay(channel, asset, receiver.address, 10.u256).get
|
let payment2 = payer.pay(channel, asset, receiver.address, 10.u256).get
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment1).isOk
|
check receiver.acceptPayment(channel, asset, payer.address, payment1).isSuccess
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment2).isOk
|
check receiver.acceptPayment(channel, asset, payer.address, payment2).isSuccess
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment1).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment1).isFailure
|
||||||
check receiver.balance(channel, asset) == 20
|
check receiver.balance(channel, asset) == 20
|
||||||
|
|
||||||
test "fails when the total supply of the asset changes":
|
test "fails when the total supply of the asset changes":
|
||||||
@ -184,32 +184,32 @@ suite "wallet: accepting payments":
|
|||||||
var balances = payment.state.outcome.balances(asset).get
|
var balances = payment.state.outcome.balances(asset).get
|
||||||
balances[payer.destination] += 10.u256
|
balances[payer.destination] += 10.u256
|
||||||
payment.state.outcome.update(asset, balances)
|
payment.state.outcome.update(asset, balances)
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isFailure
|
||||||
|
|
||||||
test "fails without a signature":
|
test "fails without a signature":
|
||||||
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
||||||
payment.signatures = @[]
|
payment.signatures = @[]
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isFailure
|
||||||
|
|
||||||
test "fails with an incorrect signature":
|
test "fails with an incorrect signature":
|
||||||
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
||||||
payment.signatures = @[Signature.example]
|
payment.signatures = @[Signature.example]
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isFailure
|
||||||
|
|
||||||
test "fails when channel is unknown":
|
test "fails when channel is unknown":
|
||||||
let newChannel = payer.openLedgerChannel(
|
let newChannel = payer.openLedgerChannel(
|
||||||
receiver.address, chainId, nonce + 1, asset, 100.u256).get
|
receiver.address, chainId, nonce + 1, asset, 100.u256).get
|
||||||
let payment = payer.pay(newChannel, asset, receiver.address, 10.u256).get
|
let payment = payer.pay(newChannel, asset, receiver.address, 10.u256).get
|
||||||
check receiver.acceptPayment(newChannel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(newChannel, asset, payer.address, payment).isFailure
|
||||||
|
|
||||||
test "fails when payment does not match channel":
|
test "fails when payment does not match channel":
|
||||||
let newChannel = payer.openLedgerChannel(
|
let newChannel = payer.openLedgerChannel(
|
||||||
receiver.address, chainId, nonce + 1, asset, 100.u256).get
|
receiver.address, chainId, nonce + 1, asset, 100.u256).get
|
||||||
let payment = payer.pay(newChannel, asset, receiver.address, 10.u256).get
|
let payment = payer.pay(newChannel, asset, receiver.address, 10.u256).get
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isFailure
|
||||||
|
|
||||||
test "fails when state is updated in unrelated areas":
|
test "fails when state is updated in unrelated areas":
|
||||||
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
var payment = payer.pay(channel, asset, receiver.address, 10.u256).get
|
||||||
payment.state.appDefinition = EthAddress.example
|
payment.state.appDefinition = EthAddress.example
|
||||||
payment.signatures = @[payerKey.sign(payment.state)]
|
payment.signatures = @[payerKey.sign(payment.state)]
|
||||||
check receiver.acceptPayment(channel, asset, payer.address, payment).isErr
|
check receiver.acceptPayment(channel, asset, payer.address, payment).isFailure
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user