Use func where possible

This commit is contained in:
Mark Spanbroek 2021-03-17 12:22:00 +01:00
parent 2737732e6d
commit 9efcf21722
11 changed files with 72 additions and 72 deletions

View File

@ -8,10 +8,10 @@ type
state*: State
signatures*: seq[(EthAddress, Signature)]
proc participants*(update: ChannelUpdate): seq[EthAddress] =
func participants*(update: ChannelUpdate): seq[EthAddress] =
update.state.channel.participants
proc verifySignatures*(update: ChannelUpdate): bool =
func verifySignatures*(update: ChannelUpdate): bool =
for (participant, signature) in update.signatures:
if not update.participants.contains(participant):
return false

View File

@ -7,18 +7,18 @@ include questionable/errorban
type Destination* = distinct array[32, byte]
proc toArray*(destination: Destination): array[32, byte] =
func toArray*(destination: Destination): array[32, byte] =
array[32, byte](destination)
proc `$`*(destination: Destination): string =
func `$`*(destination: Destination): string =
destination.toArray().toHex()
proc parse*(_: type Destination, s: string): ?Destination =
func parse*(_: type Destination, s: string): ?Destination =
Destination(array[32, byte].fromHex(s)).catch.option
proc `==`*(a, b: Destination): bool {.borrow.}
func `==`*(a, b: Destination): bool {.borrow.}
proc toDestination*(address: EthAddress): Destination =
func toDestination*(address: EthAddress): Destination =
var bytes: array[32, byte]
for i in 0..<20:
bytes[12 + i] = array[20, byte](address)[i]

View File

@ -6,16 +6,16 @@ export questionable
type EthAddress* = distinct array[20, byte]
proc zero*(_: type EthAddress): EthAddress =
func zero*(_: type EthAddress): EthAddress =
EthAddress.default
proc toArray*(address: EthAddress): array[20, byte] =
func toArray*(address: EthAddress): array[20, byte] =
array[20, byte](address)
proc `$`*(a: EthAddress): string =
func `$`*(a: EthAddress): string =
a.toArray().toHex()
proc parse*(_: type EthAddress, hex: string): ?EthAddress =
func parse*(_: type EthAddress, hex: string): ?EthAddress =
EthAddress(array[20, byte].fromHex(hex)).catch.option
proc `==`*(a, b: EthAddress): bool {.borrow.}
func `==`*(a, b: EthAddress): bool {.borrow.}

View File

@ -17,13 +17,13 @@ proc rng(data: var openArray[byte]): bool =
proc random*(_: type PrivateKey): PrivateKey =
PrivateKey.random(rng).get()
proc `$`*(key: PrivateKey): string =
func `$`*(key: PrivateKey): string =
key.toHex()
proc parse*(_: type PrivateKey, s: string): ?PrivateKey =
func parse*(_: type PrivateKey, s: string): ?PrivateKey =
SkSecretKey.fromHex(s).option
proc toAddress*(key: PublicKey): EthAddress =
func toAddress*(key: PublicKey): EthAddress =
let hash = keccak256.digest(key.toRaw())
var bytes: array[20, byte]
for i in 0..<20:

View File

@ -2,7 +2,7 @@ import ./basics
import ./channelupdate
import ./protocol
proc startLedger*(me: EthAddress,
func startLedger*(me: EthAddress,
hub: EthAddress,
chainId: UInt256,
nonce: UInt48,

View File

@ -16,16 +16,16 @@ type
head: Slice[int]
tail: seq[byte]
proc write*[T](encoder: var AbiEncoder, value: T)
proc encode*[T](_: type AbiEncoder, value: T): seq[byte]
func write*[T](encoder: var AbiEncoder, value: T)
func encode*[T](_: type AbiEncoder, value: T): seq[byte]
proc init*(_: type AbiEncoder): AbiEncoder =
func init*(_: type AbiEncoder): AbiEncoder =
AbiEncoder(stack: @[Tuple()])
proc append(tupl: var Tuple, bytes: openArray[byte]) =
func append(tupl: var Tuple, bytes: openArray[byte]) =
tupl.bytes.add(bytes)
proc postpone(tupl: var Tuple, bytes: seq[byte]) =
func postpone(tupl: var Tuple, bytes: seq[byte]) =
var split: Split
split.head.a = tupl.bytes.len
tupl.append(AbiEncoder.encode(0'u64))
@ -33,7 +33,7 @@ proc postpone(tupl: var Tuple, bytes: seq[byte]) =
split.tail = bytes
tupl.postponed.add(split)
proc finish(tupl: Tuple): seq[byte] =
func finish(tupl: Tuple): seq[byte] =
var bytes = tupl.bytes
for split in tupl.postponed:
let offset = bytes.len
@ -41,74 +41,74 @@ proc finish(tupl: Tuple): seq[byte] =
bytes.add(split.tail)
bytes
proc append(encoder: var AbiEncoder, bytes: openArray[byte]) =
func append(encoder: var AbiEncoder, bytes: openArray[byte]) =
encoder.stack[^1].append(bytes)
proc postpone(encoder: var AbiEncoder, bytes: seq[byte]) =
func postpone(encoder: var AbiEncoder, bytes: seq[byte]) =
if encoder.stack.len > 1:
encoder.stack[^1].postpone(bytes)
else:
encoder.stack[0].append(bytes)
proc setDynamic(encoder: var AbiEncoder) =
func setDynamic(encoder: var AbiEncoder) =
encoder.stack[^1].dynamic = true
proc startTuple*(encoder: var AbiEncoder) =
func startTuple*(encoder: var AbiEncoder) =
encoder.stack.add(Tuple())
proc encode(encoder: var AbiEncoder, tupl: Tuple) =
func encode(encoder: var AbiEncoder, tupl: Tuple) =
if tupl.dynamic:
encoder.postpone(tupl.finish())
encoder.setDynamic()
else:
encoder.append(tupl.finish())
proc finishTuple*(encoder: var AbiEncoder) =
func finishTuple*(encoder: var AbiEncoder) =
encoder.encode(encoder.stack.pop())
proc pad(encoder: var AbiEncoder, len: int) =
func pad(encoder: var AbiEncoder, len: int) =
let padlen = (32 - len mod 32) mod 32
for _ in 0..<padlen:
encoder.append([0'u8])
proc padleft(encoder: var AbiEncoder, bytes: openArray[byte]) =
func padleft(encoder: var AbiEncoder, bytes: openArray[byte]) =
encoder.pad(bytes.len)
encoder.append(bytes)
proc padright(encoder: var AbiEncoder, bytes: openArray[byte]) =
func padright(encoder: var AbiEncoder, bytes: openArray[byte]) =
encoder.append(bytes)
encoder.pad(bytes.len)
proc encode(encoder: var AbiEncoder, value: SomeUnsignedInt | StUint) =
func encode(encoder: var AbiEncoder, value: SomeUnsignedInt | StUint) =
encoder.padleft(value.toBytesBE)
proc encode(encoder: var AbiEncoder, value: bool) =
func encode(encoder: var AbiEncoder, value: bool) =
encoder.encode(cast[uint8](value))
proc encode(encoder: var AbiEncoder, value: enum) =
func encode(encoder: var AbiEncoder, value: enum) =
encoder.encode(uint64(ord(value)))
proc encode[I](encoder: var AbiEncoder, bytes: array[I, byte]) =
func encode[I](encoder: var AbiEncoder, bytes: array[I, byte]) =
encoder.padright(bytes)
proc encode(encoder: var AbiEncoder, bytes: seq[byte]) =
func encode(encoder: var AbiEncoder, bytes: seq[byte]) =
encoder.encode(bytes.len.uint64)
encoder.padright(bytes)
encoder.setDynamic()
proc encode(encoder: var AbiEncoder, address: EthAddress) =
func encode(encoder: var AbiEncoder, address: EthAddress) =
encoder.padleft(address.toArray)
proc encode(encoder: var AbiEncoder, destination: Destination) =
func encode(encoder: var AbiEncoder, destination: Destination) =
encoder.encode(destination.toArray)
proc encode[I, T](encoder: var AbiEncoder, value: array[I, T]) =
func encode[I, T](encoder: var AbiEncoder, value: array[I, T]) =
encoder.startTuple()
for element in value:
encoder.write(element)
encoder.finishTuple()
proc encode[T](encoder: var AbiEncoder, value: seq[T]) =
func encode[T](encoder: var AbiEncoder, value: seq[T]) =
encoder.encode(value.len.uint64)
encoder.startTuple()
for element in value:
@ -116,17 +116,17 @@ proc encode[T](encoder: var AbiEncoder, value: seq[T]) =
encoder.finishTuple()
encoder.setDynamic()
proc write*[T](encoder: var AbiEncoder, value: T) =
func write*[T](encoder: var AbiEncoder, value: T) =
var writer = AbiEncoder.init()
writer.encode(value)
encoder.encode(writer.stack[0])
proc finish*(encoder: var AbiEncoder): seq[byte] =
func finish*(encoder: var AbiEncoder): seq[byte] =
doAssert encoder.stack.len == 1, "not all tuples were finished"
doAssert encoder.stack[0].bytes.len mod 32 == 0, "encoding invariant broken"
encoder.stack[0].bytes
proc encode*[T](_: type AbiEncoder, value: T): seq[byte] =
func encode*[T](_: type AbiEncoder, value: T): seq[byte] =
var encoder = AbiEncoder.init()
encoder.write(value)
encoder.finish()

View File

@ -12,7 +12,7 @@ type
participants*: seq[EthAddress]
chainId*: UInt256
proc getChannelId*(channel: ChannelDefinition): Destination =
func getChannelId*(channel: ChannelDefinition): Destination =
var encoder= AbiEncoder.init()
encoder.startTuple()
encoder.write(channel.chainId)

View File

@ -26,7 +26,7 @@ type
targetChannelId*: Destination
destinations*: seq[Destination]
proc init*(_: type Outcome,
func init*(_: type Outcome,
asset: EthAddress,
allocation: openArray[AllocationItem]): Outcome =
let assetOutcome = AssetOutcome(
@ -36,9 +36,9 @@ proc init*(_: type Outcome,
)
Outcome(@[assetOutcome])
proc `==`*(a, b: Allocation): bool {.borrow.}
func `==`*(a, b: Allocation): bool {.borrow.}
proc `==`*(a, b: AssetOutcome): bool =
func `==`*(a, b: AssetOutcome): bool =
if a.kind != b.kind:
return false
if a.assetHolder != b.assetHolder:
@ -49,9 +49,9 @@ proc `==`*(a, b: AssetOutcome): bool =
of guaranteeType:
a.guarantee == b.guarantee
proc `==`*(a, b: Outcome): bool {.borrow.}
func `==`*(a, b: Outcome): bool {.borrow.}
proc encode*(encoder: var AbiEncoder, guarantee: Guarantee) =
func encode*(encoder: var AbiEncoder, guarantee: Guarantee) =
encoder.startTuple()
encoder.startTuple()
encoder.write(guarantee.targetChannelId)
@ -59,18 +59,18 @@ proc encode*(encoder: var AbiEncoder, guarantee: Guarantee) =
encoder.finishTuple()
encoder.finishTuple()
proc encode*(encoder: var AbiEncoder, item: AllocationItem) =
func encode*(encoder: var AbiEncoder, item: AllocationItem) =
encoder.startTuple()
encoder.write(item.destination)
encoder.write(item.amount)
encoder.finishTuple()
proc encode*(encoder: var AbiEncoder, allocation: Allocation) =
func encode*(encoder: var AbiEncoder, allocation: Allocation) =
encoder.startTuple()
encoder.write(seq[AllocationItem](allocation))
encoder.finishTuple()
proc encode*(encoder: var AbiEncoder, assetOutcome: AssetOutcome) =
func encode*(encoder: var AbiEncoder, assetOutcome: AssetOutcome) =
var content= AbiEncoder.init()
content.startTuple()
content.startTuple()
@ -88,10 +88,10 @@ proc encode*(encoder: var AbiEncoder, assetOutcome: AssetOutcome) =
encoder.write(content.finish())
encoder.finishTuple()
proc encode*(encoder: var AbiEncoder, outcome: Outcome) =
func encode*(encoder: var AbiEncoder, outcome: Outcome) =
encoder.startTuple()
encoder.write(seq[AssetOutcome](outcome))
encoder.finishTuple()
proc hashOutcome*(outcome: Outcome): array[32, byte] =
func hashOutcome*(outcome: Outcome): array[32, byte] =
keccak256.digest(AbiEncoder.encode(outcome)).data

View File

@ -12,7 +12,7 @@ export keys
type Signature* = SkRecoverableSignature
proc hashMessage(message: openArray[byte]): array[32, byte] =
func hashMessage(message: openArray[byte]): array[32, byte] =
# https://eips.ethereum.org/EIPS/eip-191
var data: seq[byte]
data.add("\x19Ethereum Signed Message:\n".toBytes)
@ -20,29 +20,29 @@ proc hashMessage(message: openArray[byte]): array[32, byte] =
data.add(message)
keccak256.digest(data).data
proc sign(key: PrivateKey, hash: array[32, byte]): Signature =
func sign(key: PrivateKey, hash: array[32, byte]): Signature =
key.signRecoverable(SkMessage(hash))
proc sign*(key: PrivateKey, state: State): Signature =
func sign*(key: PrivateKey, state: State): Signature =
let hash = hashMessage(hashState(state))
key.sign(hash)
proc recover(signature: Signature, hash: array[32, byte]): ?PublicKey =
func recover(signature: Signature, hash: array[32, byte]): ?PublicKey =
recover(signature, SkMessage(hash)).option
proc recover*(signature: Signature, state: State): ?EthAddress =
func recover*(signature: Signature, state: State): ?EthAddress =
let hash = hashMessage(hashState(state))
recover(signature, hash)?.toAddress
proc verify*(signature: Signature, state: State, signer: EthAddress): bool =
func verify*(signature: Signature, state: State, signer: EthAddress): bool =
recover(signature, state) == signer.some
proc `$`*(signature: Signature): string =
func `$`*(signature: Signature): string =
var bytes = signature.toRaw()
bytes[64] += 27
bytes.toHex()
proc parse*(_: type Signature, s: string): ?Signature =
func parse*(_: type Signature, s: string): ?Signature =
let signature = catch:
var bytes = array[65, byte].fromHex(s)
bytes[64] = bytes[64] - 27

View File

@ -29,7 +29,7 @@ type
outcome*: seq[byte]
appdata*: seq[byte]
proc fixedPart*(state: State): FixedPart =
func fixedPart*(state: State): FixedPart =
FixedPart(
chainId: state.channel.chainId,
participants: state.channel.participants,
@ -38,13 +38,13 @@ proc fixedPart*(state: State): FixedPart =
challengeDuration: state.challengeDuration
)
proc variablePart*(state: State): VariablePart =
func variablePart*(state: State): VariablePart =
VariablePart(
outcome: AbiEncoder.encode(state.outcome),
appData: state.appData
)
proc hashAppPart*(state: State): array[32, byte] =
func hashAppPart*(state: State): array[32, byte] =
var encoder= AbiEncoder.init()
encoder.startTuple()
encoder.write(state.challengeDuration)
@ -53,7 +53,7 @@ proc hashAppPart*(state: State): array[32, byte] =
encoder.finishTuple()
keccak256.digest(encoder.finish).data
proc hashState*(state: State): array[32, byte] =
func hashState*(state: State): array[32, byte] =
var encoder= AbiEncoder.init()
encoder.startTuple()
encoder.write(state.turnNum)

View File

@ -17,24 +17,24 @@ type
Channel* = object
latest*: ChannelUpdate
proc init*(_: type Wallet, key: PrivateKey): Wallet =
func init*(_: type Wallet, key: PrivateKey): Wallet =
result.key = key
proc address*(wallet: Wallet): EthAddress =
func address*(wallet: Wallet): EthAddress =
wallet.key.toPublicKey.toAddress
proc sign(wallet: Wallet, update: ChannelUpdate): ChannelUpdate =
func sign(wallet: Wallet, update: ChannelUpdate): ChannelUpdate =
var signed = update
signed.signatures &= @{wallet.address: wallet.key.sign(update.state)}
signed
proc createChannel(wallet: var Wallet, update: ChannelUpdate): Channel =
func createChannel(wallet: var Wallet, update: ChannelUpdate): Channel =
let signed = wallet.sign(update)
let channel = Channel(latest: signed)
wallet.channels.add(channel)
channel
proc openLedgerChannel*(wallet: var Wallet,
func openLedgerChannel*(wallet: var Wallet,
hub: EthAddress,
chainId: UInt256,
nonce: UInt48,
@ -43,7 +43,7 @@ proc openLedgerChannel*(wallet: var Wallet,
let update = startLedger(wallet.address, hub, chainId, nonce, asset, amount)
wallet.createChannel(update)
proc acceptChannel*(wallet: var Wallet, update: ChannelUpdate): ?!Channel =
func acceptChannel*(wallet: var Wallet, update: ChannelUpdate): ?!Channel =
if not update.participants.contains(wallet.address):
return Channel.failure "wallet owner is not a participant"