[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/contractabi
import pkg/nimcrypto import pkg/nimcrypto
import pkg/ethers/fields import pkg/ethers/fields
@ -28,9 +29,17 @@ type
u*: seq[byte] u*: seq[byte]
publicKey*: seq[byte] publicKey*: seq[byte]
name*: seq[byte] name*: seq[byte]
SlotId* = array[32, byte] SlotId* = distinct array[32, byte]
RequestId* = array[32, byte] RequestId* = distinct array[32, byte]
Nonce* = 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 = func fromTuple(_: type StorageRequest, tupl: tuple): StorageRequest =
StorageRequest( StorageRequest(
@ -84,6 +93,9 @@ func solidityType*(_: type StorageAsk): string =
func solidityType*(_: type StorageRequest): string = func solidityType*(_: type StorageRequest): string =
solidityType(StorageRequest.fieldTypes) solidityType(StorageRequest.fieldTypes)
func solidityType*[T: RequestId | SlotId | Nonce](_: type T): string =
solidityType(array[32, byte])
func encode*(encoder: var AbiEncoder, por: StoragePoR) = func encode*(encoder: var AbiEncoder, por: StoragePoR) =
encoder.write(por.fieldValues) encoder.write(por.fieldValues)
@ -96,9 +108,17 @@ func encode*(encoder: var AbiEncoder, content: StorageContent) =
func encode*(encoder: var AbiEncoder, ask: StorageAsk) = func encode*(encoder: var AbiEncoder, ask: StorageAsk) =
encoder.write(ask.fieldValues) encoder.write(ask.fieldValues)
func encode*(encoder: var AbiEncoder, id: RequestId | SlotId | Nonce) =
encoder.write(id.toArray)
func encode*(encoder: var AbiEncoder, request: StorageRequest) = func encode*(encoder: var AbiEncoder, request: StorageRequest) =
encoder.write(request.fieldValues) 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 = func decode*(decoder: var AbiDecoder, T: type StoragePoR): ?!T =
let tupl = ?decoder.read(StoragePoR.fieldTypes) let tupl = ?decoder.read(StoragePoR.fieldTypes)
success StoragePoR.fromTuple(tupl) success StoragePoR.fromTuple(tupl)
@ -121,11 +141,11 @@ func decode*(decoder: var AbiDecoder, T: type StorageRequest): ?!T =
func id*(request: StorageRequest): RequestId = func id*(request: StorageRequest): RequestId =
let encoding = AbiEncoder.encode((request, )) let encoding = AbiEncoder.encode((request, ))
keccak256.digest(encoding).data RequestId(keccak256.digest(encoding).data)
func slotId*(requestId: RequestId, slot: UInt256): SlotId = func slotId*(requestId: RequestId, slot: UInt256): SlotId =
let encoding = AbiEncoder.encode((requestId, slot)) let encoding = AbiEncoder.encode((requestId, slot))
keccak256.digest(encoding).data SlotId(keccak256.digest(encoding).data)
func slotId*(request: StorageRequest, slot: UInt256): SlotId = func slotId*(request: StorageRequest, slot: UInt256): SlotId =
slotId(request.id, slot) slotId(request.id, slot)

View File

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

View File

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

View File

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

View File

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

View File

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