Skip to content

Commit

Permalink
perf: contract storage optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
AuHau committed Jan 31, 2025
1 parent 58a962a commit e251b03
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 85 deletions.
3 changes: 3 additions & 0 deletions codex/clock.nim
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,8 @@ proc toSecondsSince1970*(bytes: seq[byte]): SecondsSince1970 =
let asUint = uint64.fromBytes(bytes)
cast[int64](asUint)

proc toSecondsSince1970*(num: uint64): SecondsSince1970 =
cast[int64](num)

proc toSecondsSince1970*(bigint: UInt256): SecondsSince1970 =
bigint.truncate(int64)
4 changes: 2 additions & 2 deletions codex/contracts/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ type
slashPercentage*: uint8 # percentage of the collateral that is slashed

ProofConfig* = object
period*: UInt256 # proofs requirements are calculated per period (in seconds)
timeout*: UInt256 # mark proofs as missing before the timeout (in seconds)
period*: uint64 # proofs requirements are calculated per period (in seconds)
timeout*: uint64 # mark proofs as missing before the timeout (in seconds)
downtime*: uint8 # ignore this much recent blocks for proof requirements
zkeyHash*: string # hash of the zkey file which is linked to the verifier
# Ensures the pointer does not remain in downtime for many consecutive
Expand Down
14 changes: 7 additions & 7 deletions codex/contracts/market.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ method periodicity*(market: OnChainMarket): Future[Periodicity] {.async.} =
let period = config.proofs.period
return Periodicity(seconds: period)

method proofTimeout*(market: OnChainMarket): Future[UInt256] {.async.} =
method proofTimeout*(market: OnChainMarket): Future[uint64] {.async.} =
convertEthersError:
let config = await market.config()
return config.proofs.timeout
Expand Down Expand Up @@ -146,7 +146,7 @@ method requestExpiresAt*(
return await market.contract.requestExpiry(id)

method getHost(
market: OnChainMarket, requestId: RequestId, slotIndex: UInt256
market: OnChainMarket, requestId: RequestId, slotIndex: uint64
): Future[?Address] {.async.} =
convertEthersError:
let slotId = slotId(requestId, slotIndex)
Expand All @@ -172,7 +172,7 @@ method getActiveSlot*(market: OnChainMarket, slotId: SlotId): Future[?Slot] {.as
method fillSlot(
market: OnChainMarket,
requestId: RequestId,
slotIndex: UInt256,
slotIndex: uint64,
proof: Groth16Proof,
collateral: UInt256,
) {.async.} =
Expand Down Expand Up @@ -256,7 +256,7 @@ method canProofBeMarkedAsMissing*(
return false

method reserveSlot*(
market: OnChainMarket, requestId: RequestId, slotIndex: UInt256
market: OnChainMarket, requestId: RequestId, slotIndex: uint64
) {.async.} =
convertEthersError:
discard await market.contract
Expand All @@ -269,7 +269,7 @@ method reserveSlot*(
.confirm(1)

method canReserveSlot*(
market: OnChainMarket, requestId: RequestId, slotIndex: UInt256
market: OnChainMarket, requestId: RequestId, slotIndex: uint64
): Future[bool] {.async.} =
convertEthersError:
return await market.contract.canReserveSlot(requestId, slotIndex)
Expand Down Expand Up @@ -305,10 +305,10 @@ method subscribeSlotFilled*(
method subscribeSlotFilled*(
market: OnChainMarket,
requestId: RequestId,
slotIndex: UInt256,
slotIndex: uint64,
callback: OnSlotFilled,
): Future[MarketSubscription] {.async.} =
proc onSlotFilled(eventRequestId: RequestId, eventSlotIndex: UInt256) =
proc onSlotFilled(eventRequestId: RequestId, eventSlotIndex: uint64) =
if eventRequestId == requestId and eventSlotIndex == slotIndex:
callback(requestId, slotIndex)

Expand Down
18 changes: 4 additions & 14 deletions codex/contracts/marketplace.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ proc currentCollateral*(
marketplace: Marketplace, id: SlotId
): UInt256 {.contract, view.}

proc slashMisses*(marketplace: Marketplace): UInt256 {.contract, view.}
proc slashPercentage*(marketplace: Marketplace): UInt256 {.contract, view.}
proc minCollateralThreshold*(marketplace: Marketplace): UInt256 {.contract, view.}

proc requestStorage*(
marketplace: Marketplace, request: StorageRequest
): Confirmable {.
Expand All @@ -75,10 +71,7 @@ proc requestStorage*(
.}

proc fillSlot*(
marketplace: Marketplace,
requestId: RequestId,
slotIndex: UInt256,
proof: Groth16Proof,
marketplace: Marketplace, requestId: RequestId, slotIndex: uint64, proof: Groth16Proof
): Confirmable {.
contract,
errors: [
Expand Down Expand Up @@ -154,9 +147,6 @@ proc requestExpiry*(
marketplace: Marketplace, requestId: RequestId
): SecondsSince1970 {.contract, view.}

proc proofTimeout*(marketplace: Marketplace): UInt256 {.contract, view.}

proc proofEnd*(marketplace: Marketplace, id: SlotId): UInt256 {.contract, view.}
proc missingProofs*(marketplace: Marketplace, id: SlotId): UInt256 {.contract, view.}
proc isProofRequired*(marketplace: Marketplace, id: SlotId): bool {.contract, view.}
proc willProofBeRequired*(marketplace: Marketplace, id: SlotId): bool {.contract, view.}
Expand All @@ -175,7 +165,7 @@ proc submitProof*(
.}

proc markProofAsMissing*(
marketplace: Marketplace, id: SlotId, period: UInt256
marketplace: Marketplace, id: SlotId, period: uint64
): Confirmable {.
contract,
errors: [
Expand All @@ -186,9 +176,9 @@ proc markProofAsMissing*(
.}

proc reserveSlot*(
marketplace: Marketplace, requestId: RequestId, slotIndex: UInt256
marketplace: Marketplace, requestId: RequestId, slotIndex: uint64
): Confirmable {.contract.}

proc canReserveSlot*(
marketplace: Marketplace, requestId: RequestId, slotIndex: UInt256
marketplace: Marketplace, requestId: RequestId, slotIndex: uint64
): bool {.contract, view.}
37 changes: 19 additions & 18 deletions codex/contracts/requests.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import pkg/questionable/results
import pkg/stew/byteutils
import ../logutils
import ../utils/json
import ../clock

export contractabi

Expand All @@ -16,16 +17,16 @@ type
client* {.serialize.}: Address
ask* {.serialize.}: StorageAsk
content* {.serialize.}: StorageContent
expiry* {.serialize.}: UInt256
expiry* {.serialize.}: SecondsSince1970
nonce*: Nonce

StorageAsk* = object
slots* {.serialize.}: uint64
slotSize* {.serialize.}: UInt256
duration* {.serialize.}: UInt256
proofProbability* {.serialize.}: UInt256
pricePerBytePerSecond* {.serialize.}: UInt256
collateralPerByte* {.serialize.}: UInt256
slots* {.serialize.}: uint64
slotSize* {.serialize.}: uint64
duration* {.serialize.}: SecondsSince1970
maxSlotLoss* {.serialize.}: uint64

StorageContent* = object
Expand All @@ -34,7 +35,7 @@ type

Slot* = object
request* {.serialize.}: StorageRequest
slotIndex* {.serialize.}: UInt256
slotIndex* {.serialize.}: uint64

SlotId* = distinct array[32, byte]
RequestId* = distinct array[32, byte]
Expand Down Expand Up @@ -108,12 +109,12 @@ func fromTuple(_: type Slot, tupl: tuple): Slot =

func fromTuple(_: type StorageAsk, tupl: tuple): StorageAsk =
StorageAsk(
slots: tupl[0],
slotSize: tupl[1],
duration: tupl[2],
proofProbability: tupl[3],
pricePerBytePerSecond: tupl[4],
collateralPerByte: tupl[5],
proofProbability: tupl[0],
pricePerBytePerSecond: tupl[1],
collateralPerByte: tupl[2],
slots: tupl[3],
slotSize: tupl[4],
duration: tupl[5],
maxSlotLoss: tupl[6],
)

Expand Down Expand Up @@ -164,21 +165,21 @@ func id*(request: StorageRequest): RequestId =
let encoding = AbiEncoder.encode((request,))
RequestId(keccak256.digest(encoding).data)

func slotId*(requestId: RequestId, slotIndex: UInt256): SlotId =
func slotId*(requestId: RequestId, slotIndex: uint64): SlotId =
let encoding = AbiEncoder.encode((requestId, slotIndex))
SlotId(keccak256.digest(encoding).data)

func slotId*(request: StorageRequest, slotIndex: UInt256): SlotId =
func slotId*(request: StorageRequest, slotIndex: uint64): SlotId =
slotId(request.id, slotIndex)

func id*(slot: Slot): SlotId =
slotId(slot.request, slot.slotIndex)

func pricePerSlotPerSecond*(ask: StorageAsk): UInt256 =
ask.pricePerBytePerSecond * ask.slotSize
ask.pricePerBytePerSecond * ask.slotSize.u256

func pricePerSlot*(ask: StorageAsk): UInt256 =
ask.duration * ask.pricePerSlotPerSecond
ask.duration.u256 * ask.pricePerSlotPerSecond

func totalPrice*(ask: StorageAsk): UInt256 =
ask.slots.u256 * ask.pricePerSlot
Expand All @@ -187,7 +188,7 @@ func totalPrice*(request: StorageRequest): UInt256 =
request.ask.totalPrice

func collateralPerSlot*(ask: StorageAsk): UInt256 =
ask.collateralPerByte * ask.slotSize
ask.collateralPerByte * ask.slotSize.u256

func size*(ask: StorageAsk): UInt256 =
ask.slots.u256 * ask.slotSize
func size*(ask: StorageAsk): uint64 =
ask.slots * ask.slotSize
29 changes: 14 additions & 15 deletions codex/market.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ type
MarketError* = object of CodexError
Subscription* = ref object of RootObj
OnRequest* =
proc(id: RequestId, ask: StorageAsk, expiry: UInt256) {.gcsafe, upraises: [].}
proc(id: RequestId, ask: StorageAsk, expiry: uint64) {.gcsafe, upraises: [].}
OnFulfillment* = proc(requestId: RequestId) {.gcsafe, upraises: [].}
OnSlotFilled* =
proc(requestId: RequestId, slotIndex: UInt256) {.gcsafe, upraises: [].}
OnSlotFreed* = proc(requestId: RequestId, slotIndex: UInt256) {.gcsafe, upraises: [].}
OnSlotFilled* = proc(requestId: RequestId, slotIndex: uint64) {.gcsafe, upraises: [].}
OnSlotFreed* = proc(requestId: RequestId, slotIndex: uint64) {.gcsafe, upraises: [].}
OnSlotReservationsFull* =
proc(requestId: RequestId, slotIndex: UInt256) {.gcsafe, upraises: [].}
proc(requestId: RequestId, slotIndex: uint64) {.gcsafe, upraises: [].}
OnRequestCancelled* = proc(requestId: RequestId) {.gcsafe, upraises: [].}
OnRequestFailed* = proc(requestId: RequestId) {.gcsafe, upraises: [].}
OnProofSubmitted* = proc(id: SlotId) {.gcsafe, upraises: [].}
Expand All @@ -37,19 +36,19 @@ type
StorageRequested* = object of MarketplaceEvent
requestId*: RequestId
ask*: StorageAsk
expiry*: UInt256
expiry*: uint64

SlotFilled* = object of MarketplaceEvent
requestId* {.indexed.}: RequestId
slotIndex*: UInt256
slotIndex*: uint64

SlotFreed* = object of MarketplaceEvent
requestId* {.indexed.}: RequestId
slotIndex*: UInt256
slotIndex*: uint64

SlotReservationsFull* = object of MarketplaceEvent
requestId* {.indexed.}: RequestId
slotIndex*: UInt256
slotIndex*: uint64

RequestFulfilled* = object of MarketplaceEvent
requestId* {.indexed.}: RequestId
Expand All @@ -72,7 +71,7 @@ method getSigner*(market: Market): Future[Address] {.base, async.} =
method periodicity*(market: Market): Future[Periodicity] {.base, async.} =
raiseAssert("not implemented")

method proofTimeout*(market: Market): Future[UInt256] {.base, async.} =
method proofTimeout*(market: Market): Future[uint64] {.base, async.} =
raiseAssert("not implemented")

method repairRewardPercentage*(market: Market): Future[uint8] {.base, async.} =
Expand Down Expand Up @@ -122,7 +121,7 @@ method requestExpiresAt*(
raiseAssert("not implemented")

method getHost*(
market: Market, requestId: RequestId, slotIndex: UInt256
market: Market, requestId: RequestId, slotIndex: uint64
): Future[?Address] {.base, async.} =
raiseAssert("not implemented")

Expand All @@ -137,7 +136,7 @@ method getActiveSlot*(market: Market, slotId: SlotId): Future[?Slot] {.base, asy
method fillSlot*(
market: Market,
requestId: RequestId,
slotIndex: UInt256,
slotIndex: uint64,
proof: Groth16Proof,
collateral: UInt256,
) {.base, async.} =
Expand Down Expand Up @@ -177,12 +176,12 @@ method canProofBeMarkedAsMissing*(
raiseAssert("not implemented")

method reserveSlot*(
market: Market, requestId: RequestId, slotIndex: UInt256
market: Market, requestId: RequestId, slotIndex: uint64
) {.base, async.} =
raiseAssert("not implemented")

method canReserveSlot*(
market: Market, requestId: RequestId, slotIndex: UInt256
market: Market, requestId: RequestId, slotIndex: uint64
): Future[bool] {.base, async.} =
raiseAssert("not implemented")

Expand All @@ -202,7 +201,7 @@ method subscribeSlotFilled*(
raiseAssert("not implemented")

method subscribeSlotFilled*(
market: Market, requestId: RequestId, slotIndex: UInt256, callback: OnSlotFilled
market: Market, requestId: RequestId, slotIndex: uint64, callback: OnSlotFilled
): Future[Subscription] {.base, async.} =
raiseAssert("not implemented")

Expand Down
13 changes: 7 additions & 6 deletions codex/node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -369,13 +369,13 @@ proc iterateManifests*(self: CodexNodeRef, onManifest: OnManifest) {.async.} =
proc setupRequest(
self: CodexNodeRef,
cid: Cid,
duration: UInt256,
duration: uint64,
proofProbability: UInt256,
nodes: uint,
tolerance: uint,
pricePerBytePerSecond: UInt256,
collateralPerByte: UInt256,
expiry: UInt256,
expiry: uint64,
): Future[?!StorageRequest] {.async.} =
## Setup slots for a given dataset
##
Expand Down Expand Up @@ -432,7 +432,7 @@ proc setupRequest(
request = StorageRequest(
ask: StorageAsk(
slots: verifiable.numSlots.uint64,
slotSize: builder.slotBytes.uint.u256,
slotSize: builder.slotBytes.uint64,
duration: duration,
proofProbability: proofProbability,
pricePerBytePerSecond: pricePerBytePerSecond,
Expand All @@ -452,13 +452,13 @@ proc setupRequest(
proc requestStorage*(
self: CodexNodeRef,
cid: Cid,
duration: UInt256,
duration: uint64,
proofProbability: UInt256,
nodes: uint,
tolerance: uint,
pricePerBytePerSecond: UInt256,
collateralPerByte: UInt256,
expiry: UInt256,
expiry: uint64,
): Future[?!PurchaseId] {.async.} =
## Initiate a request for storage sequence, this might
## be a multistep procedure.
Expand Down Expand Up @@ -494,7 +494,7 @@ proc requestStorage*(
success purchase.id

proc onStore(
self: CodexNodeRef, request: StorageRequest, slotIdx: UInt256, blocksCb: BlocksCb
self: CodexNodeRef, request: StorageRequest, slotIdx: uint64, blocksCb: BlocksCb
): Future[?!void] {.async.} =
## store data in local storage
##
Expand All @@ -518,6 +518,7 @@ proc onStore(
trace "Unable to create slots builder", err = err.msg
return failure(err)

# TODO: Follow the rabbit hole of changing slotIndex to uint64
let
slotIdx = slotIdx.truncate(int)
expiry = request.expiry.toSecondsSince1970
Expand Down
6 changes: 3 additions & 3 deletions codex/periods.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import pkg/stint

type
Periodicity* = object
seconds*: UInt256
seconds*: uint64

Period* = UInt256
Timestamp* = UInt256
Period* = uint64
Timestamp* = uint64

func periodOf*(periodicity: Periodicity, timestamp: Timestamp): Period =
timestamp div periodicity.seconds
Expand Down
Loading

0 comments on commit e251b03

Please sign in to comment.