[chore] make RequestId, SlotId, Nonce, PurcahseId distinct

Make RequestId, SlotId, Nonce, PurcahseId distinct types.

Add/modify conversions to support the distinct type (ABI encoding/decoding, JSON encoding, REST decoding).

Update tests
This commit is contained in:
Eric Mastro 2022-08-18 15:55:53 +10:00 committed by Eric Mastro
parent 6df5a7cf54
commit 8f116cd01e
6 changed files with 48 additions and 10 deletions

View File

@ -1,3 +1,4 @@
import std/hashes
import pkg/contractabi
import pkg/nimcrypto
import pkg/ethers/fields
@ -28,9 +29,17 @@ type
u*: seq[byte]
publicKey*: seq[byte]
name*: seq[byte]
SlotId* = array[32, byte]
RequestId* = array[32, byte]
Nonce* = array[32, byte]
SlotId* = distinct array[32, byte]
RequestId* = distinct array[32, byte]
Nonce* = distinct array[32, byte]
proc `==`*(x, y: Nonce): bool {.borrow.}
proc `==`*(x, y: RequestId): bool {.borrow.}
proc `==`*(x, y: SlotId): bool {.borrow.}
proc hash*(x: SlotId): Hash {.borrow.}
func toArray*(id: RequestId | SlotId | Nonce): array[32, byte] =
array[32, byte](id)
func fromTuple(_: type StorageRequest, tupl: tuple): StorageRequest =
StorageRequest(
@ -84,6 +93,9 @@ func solidityType*(_: type StorageAsk): string =
func solidityType*(_: type StorageRequest): string =
solidityType(StorageRequest.fieldTypes)
func solidityType*[T: RequestId | SlotId | Nonce](_: type T): string =
solidityType(array[32, byte])
func encode*(encoder: var AbiEncoder, por: StoragePoR) =
encoder.write(por.fieldValues)
@ -96,9 +108,17 @@ func encode*(encoder: var AbiEncoder, content: StorageContent) =
func encode*(encoder: var AbiEncoder, ask: StorageAsk) =
encoder.write(ask.fieldValues)
func encode*(encoder: var AbiEncoder, id: RequestId | SlotId | Nonce) =
encoder.write(id.toArray)
func encode*(encoder: var AbiEncoder, request: StorageRequest) =
encoder.write(request.fieldValues)
func decode*[T: RequestId | SlotId | Nonce](decoder: var AbiDecoder,
_: type T): ?!T =
let nonce = ?decoder.read(type array[32, byte])
success T(nonce)
func decode*(decoder: var AbiDecoder, T: type StoragePoR): ?!T =
let tupl = ?decoder.read(StoragePoR.fieldTypes)
success StoragePoR.fromTuple(tupl)
@ -121,11 +141,11 @@ func decode*(decoder: var AbiDecoder, T: type StorageRequest): ?!T =
func id*(request: StorageRequest): RequestId =
let encoding = AbiEncoder.encode((request, ))
keccak256.digest(encoding).data
RequestId(keccak256.digest(encoding).data)
func slotId*(requestId: RequestId, slot: UInt256): SlotId =
let encoding = AbiEncoder.encode((requestId, slot))
keccak256.digest(encoding).data
SlotId(keccak256.digest(encoding).data)
func slotId*(request: StorageRequest, slot: UInt256): SlotId =
slotId(request.id, slot)

View File

@ -1,3 +1,4 @@
import std/hashes
import std/tables
import pkg/stint
import pkg/chronos
@ -22,13 +23,16 @@ type
clock: Clock
request*: StorageRequest
PurchaseTimeout* = Timeout
PurchaseId* = array[32, byte]
PurchaseId* = distinct array[32, byte]
const DefaultProofProbability = 100.u256
const DefaultRequestExpiryInterval = (10 * 60).u256
proc start(purchase: Purchase) {.gcsafe.}
func id*(purchase: Purchase): PurchaseId
proc `==`*(x, y: PurchaseId): bool {.borrow.}
proc hash*(x: PurchaseId): Hash {.borrow.}
proc toHex*(x: PurchaseId): string {.borrow.}
proc new*(_: type Purchasing, market: Market, clock: Clock): Purchasing =
Purchasing(
@ -45,7 +49,9 @@ proc populate*(purchasing: Purchasing, request: StorageRequest): StorageRequest
if result.expiry == 0.u256:
result.expiry = (purchasing.clock.now().u256 + purchasing.requestExpiryInterval)
if result.nonce == Nonce.default:
doAssert randomBytes(result.nonce) == 32
var id = result.nonce.toArray
doAssert randomBytes(id) == 32
result.nonce = Nonce(id)
proc purchase*(purchasing: Purchasing, request: StorageRequest): Purchase =
let request = purchasing.populate(request)
@ -94,7 +100,7 @@ proc wait*(purchase: Purchase) {.async.} =
await purchase.future
func id*(purchase: Purchase): PurchaseId =
purchase.request.id
PurchaseId(purchase.request.id)
func finished*(purchase: Purchase): bool =
purchase.future.finished

View File

@ -13,6 +13,7 @@ push: {.upraises: [].}
import std/sequtils
import std/sugar
import pkg/questionable
import pkg/questionable/results
@ -104,6 +105,10 @@ proc decodeString(_: type array[32, byte],
except ValueError as e:
err e.msg.cstring
proc decodeString[T: PurchaseId | RequestId | Nonce](_: type T,
value: string): Result[T, cstring] =
array[32, byte].decodeString(value).map(id => T(id))
proc initRestApi*(node: CodexNodeRef, conf: CodexConf): RestRouter =
var router = RestRouter.init(validate)
router.api(

View File

@ -45,6 +45,9 @@ func `%`*(stint: StInt|StUInt): JsonNode =
func `%`*(arr: openArray[byte]): JsonNode =
%("0x" & arr.toHex)
func `%`*(id: RequestId | SlotId | Nonce): JsonNode =
% id.toArray
func `%`*(purchase: Purchase): JsonNode =
%*{
"finished": purchase.finished,

View File

@ -2,12 +2,12 @@ import pkg/chronos
import pkg/stint
import pkg/upraises
import ./periods
from ../../contracts/requests import SlotId, RequestId
import ../../contracts/requests
export chronos
export stint
export periods
export SlotId, RequestId
export requests
type
Proofs* = ref object of RootObj

View File

@ -1,5 +1,6 @@
import std/random
import std/sequtils
import pkg/codex/proving
import pkg/stint
proc example*[T: SomeInteger](_: type T): T =
@ -15,3 +16,6 @@ proc example*[T](_: type seq[T]): seq[T] =
proc example*(_: type UInt256): UInt256 =
UInt256.fromBytes(array[32, byte].example)
proc example*[T: RequestId | SlotId | Nonce](_: type T): T =
T(array[32, byte].example)