Skip to content

Commit b3e57a3

Browse files
markspanbroekdryajovemizzle
authored
Wire up prover (#736)
* wire prover into node * stricter case object checks * return correct proof * misc renames * adding usefull traces * fix nodes and tolerance to match expected params * format challenges in logs * add circom compat to solidity groth16 convertion * update * bump time to give nodes time to load with all circom artifacts * misc * misc * use correct dataset geometry in erasure * make errors more searchable * use parens around `=? (await...)` calls * styling * styling * use push raises * fix to match constructor arguments * merge master * merge master * integration: fix proof parameters for a test Increased times due to ZK proof generation. Increased storage requirement because we're now hosting 5 slots instead of 1. * sales: calculate initial proof at start of period reason: this ensures that the period (and therefore the challenge) doesn't change while we're calculating the proof * integration: fix proof parameters for tests Increased times due to waiting on next period. Fixed data to be of right size. Updated expected payout due to hosting 5 slots. * sales: wait for stable proof challenge When the block pointer is nearing the wrap-around point, we wait another period before calculating a proof. * fix merge conflict --------- Co-authored-by: Dmitriy Ryajov <[email protected]> Co-authored-by: Eric <[email protected]>
1 parent 293c676 commit b3e57a3

23 files changed

+271
-154
lines changed

codex/blockexchange/engine/engine.nim

+36-28
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ proc sendWantHave(
129129
for p in peers:
130130
if p notin excluded:
131131
if address notin p.peerHave:
132-
trace " wantHave > ", peer = p.id
133132
await b.network.request.sendWantList(
134133
p.id,
135134
@[address],
@@ -145,11 +144,18 @@ proc sendWantBlock(
145144
@[address],
146145
wantType = WantType.WantBlock) # we want this remote to send us a block
147146

148-
proc monitorBlockHandle(b: BlockExcEngine, handle: Future[Block], address: BlockAddress, peerId: PeerId) {.async.} =
147+
proc monitorBlockHandle(
148+
b: BlockExcEngine,
149+
handle: Future[Block],
150+
address: BlockAddress,
151+
peerId: PeerId) {.async.} =
152+
149153
try:
150154
trace "Monitoring block handle", address, peerId
151155
discard await handle
152156
trace "Block handle success", address, peerId
157+
except CancelledError as exc:
158+
trace "Block handle cancelled", address, peerId
153159
except CatchableError as exc:
154160
trace "Error block handle, disconnecting peer", address, exc = exc.msg, peerId
155161

@@ -167,38 +173,38 @@ proc monitorBlockHandle(b: BlockExcEngine, handle: Future[Block], address: Block
167173
proc requestBlock*(
168174
b: BlockExcEngine,
169175
address: BlockAddress,
170-
timeout = DefaultBlockTimeout): Future[Block] {.async.} =
176+
timeout = DefaultBlockTimeout): Future[?!Block] {.async.} =
171177
let blockFuture = b.pendingBlocks.getWantHandle(address, timeout)
172178

173179
if b.pendingBlocks.isInFlight(address):
174-
return await blockFuture
175-
176-
let peers = b.peers.selectCheapest(address)
177-
if peers.len == 0:
178-
b.discovery.queueFindBlocksReq(@[address.cidOrTreeCid])
179-
180-
let maybePeer =
181-
if peers.len > 0:
182-
peers[hash(address) mod peers.len].some
183-
elif b.peers.len > 0:
184-
toSeq(b.peers)[hash(address) mod b.peers.len].some
185-
else:
186-
BlockExcPeerCtx.none
180+
success await blockFuture
181+
else:
182+
let peers = b.peers.selectCheapest(address)
183+
if peers.len == 0:
184+
b.discovery.queueFindBlocksReq(@[address.cidOrTreeCid])
185+
186+
let maybePeer =
187+
if peers.len > 0:
188+
peers[hash(address) mod peers.len].some
189+
elif b.peers.len > 0:
190+
toSeq(b.peers)[hash(address) mod b.peers.len].some
191+
else:
192+
BlockExcPeerCtx.none
187193

188-
if peer =? maybePeer:
189-
asyncSpawn b.monitorBlockHandle(blockFuture, address, peer.id)
190-
b.pendingBlocks.setInFlight(address)
191-
await b.sendWantBlock(address, peer)
192-
codex_block_exchange_want_block_lists_sent.inc()
193-
await b.sendWantHave(address, @[peer], toSeq(b.peers))
194-
codex_block_exchange_want_have_lists_sent.inc()
194+
if peer =? maybePeer:
195+
asyncSpawn b.monitorBlockHandle(blockFuture, address, peer.id)
196+
b.pendingBlocks.setInFlight(address)
197+
await b.sendWantBlock(address, peer)
198+
codex_block_exchange_want_block_lists_sent.inc()
199+
await b.sendWantHave(address, @[peer], toSeq(b.peers))
200+
codex_block_exchange_want_have_lists_sent.inc()
195201

196-
return await blockFuture
202+
success await blockFuture
197203

198204
proc requestBlock*(
199205
b: BlockExcEngine,
200206
cid: Cid,
201-
timeout = DefaultBlockTimeout): Future[Block] =
207+
timeout = DefaultBlockTimeout): Future[?!Block] =
202208
b.requestBlock(BlockAddress.init(cid))
203209

204210
proc blockPresenceHandler*(
@@ -298,7 +304,10 @@ proc resolveBlocks*(b: BlockExcEngine, blocksDelivery: seq[BlockDelivery]) {.asy
298304
b.discovery.queueProvideBlocksReq(cids.toSeq)
299305

300306
proc resolveBlocks*(b: BlockExcEngine, blocks: seq[Block]) {.async.} =
301-
await b.resolveBlocks(blocks.mapIt(BlockDelivery(blk: it, address: BlockAddress(leaf: false, cid: it.cid))))
307+
await b.resolveBlocks(
308+
blocks.mapIt(
309+
BlockDelivery(blk: it, address: BlockAddress(leaf: false, cid: it.cid)
310+
)))
302311

303312
proc payForBlocks(engine: BlockExcEngine,
304313
peer: BlockExcPeerCtx,
@@ -315,8 +324,7 @@ proc payForBlocks(engine: BlockExcEngine,
315324

316325
proc validateBlockDelivery(
317326
b: BlockExcEngine,
318-
bd: BlockDelivery
319-
): ?!void =
327+
bd: BlockDelivery): ?!void =
320328
if bd.address notin b.pendingBlocks:
321329
return failure("Received block is not currently a pending block")
322330

codex/blockexchange/engine/pendingblocks.nim

+22-19
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,10 @@ proc updatePendingBlockGauge(p: PendingBlocksManager) =
4444
codex_block_exchange_pending_block_requests.set(p.blocks.len.int64)
4545

4646
proc getWantHandle*(
47-
p: PendingBlocksManager,
48-
address: BlockAddress,
49-
timeout = DefaultBlockTimeout,
50-
inFlight = false
51-
): Future[Block] {.async.} =
47+
p: PendingBlocksManager,
48+
address: BlockAddress,
49+
timeout = DefaultBlockTimeout,
50+
inFlight = false): Future[Block] {.async.} =
5251
## Add an event for a block
5352
##
5453

@@ -75,17 +74,15 @@ proc getWantHandle*(
7574
p.updatePendingBlockGauge()
7675

7776
proc getWantHandle*(
78-
p: PendingBlocksManager,
79-
cid: Cid,
80-
timeout = DefaultBlockTimeout,
81-
inFlight = false
82-
): Future[Block] =
77+
p: PendingBlocksManager,
78+
cid: Cid,
79+
timeout = DefaultBlockTimeout,
80+
inFlight = false): Future[Block] =
8381
p.getWantHandle(BlockAddress.init(cid), timeout, inFlight)
8482

8583
proc resolve*(
8684
p: PendingBlocksManager,
87-
blocksDelivery: seq[BlockDelivery]
88-
) {.gcsafe, raises: [].} =
85+
blocksDelivery: seq[BlockDelivery]) {.gcsafe, raises: [].} =
8986
## Resolve pending blocks
9087
##
9188

@@ -108,16 +105,23 @@ proc resolve*(
108105
do:
109106
warn "Attempting to resolve block that's not currently a pending block", address = bd.address
110107

111-
proc setInFlight*(p: PendingBlocksManager,
112-
address: BlockAddress,
113-
inFlight = true) =
108+
proc setInFlight*(
109+
p: PendingBlocksManager,
110+
address: BlockAddress,
111+
inFlight = true) =
112+
## Set inflight status for a block
113+
##
114+
114115
p.blocks.withValue(address, pending):
115116
pending[].inFlight = inFlight
116117
trace "Setting inflight", address, inFlight = pending[].inFlight
117118

118-
proc isInFlight*(p: PendingBlocksManager,
119-
address: BlockAddress,
120-
): bool =
119+
proc isInFlight*(
120+
p: PendingBlocksManager,
121+
address: BlockAddress): bool =
122+
## Check if a block is in flight
123+
##
124+
121125
p.blocks.withValue(address, pending):
122126
result = pending[].inFlight
123127
trace "Getting inflight", address, inFlight = result
@@ -145,7 +149,6 @@ iterator wantListCids*(p: PendingBlocksManager): Cid =
145149
yieldedCids.incl(cid)
146150
yield cid
147151

148-
149152
iterator wantHandles*(p: PendingBlocksManager): Future[Block] =
150153
for v in p.blocks.values:
151154
yield v.handle

codex/erasure/backends/leopard.nim

+17-21
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ type
2222
decoder*: Option[LeoDecoder]
2323

2424
method encode*(
25-
self: LeoEncoderBackend,
26-
data,
27-
parity: var openArray[seq[byte]]
28-
): Result[void, cstring] =
25+
self: LeoEncoderBackend,
26+
data,
27+
parity: var openArray[seq[byte]]): Result[void, cstring] =
2928
## Encode data using Leopard backend
3029

3130
if parity.len == 0:
@@ -43,11 +42,10 @@ method encode*(
4342
encoder.encode(data, parity)
4443

4544
method decode*(
46-
self: LeoDecoderBackend,
47-
data,
48-
parity,
49-
recovered: var openArray[seq[byte]]
50-
): Result[void, cstring] =
45+
self: LeoDecoderBackend,
46+
data,
47+
parity,
48+
recovered: var openArray[seq[byte]]): Result[void, cstring] =
5149
## Decode data using given Leopard backend
5250

5351
var decoder =
@@ -71,26 +69,24 @@ method release*(self: LeoDecoderBackend) =
7169
self.decoder.get().free()
7270

7371
proc new*(
74-
T: type LeoEncoderBackend,
75-
blockSize,
76-
buffers,
77-
parity: int
78-
): LeoEncoderBackend =
72+
T: type LeoEncoderBackend,
73+
blockSize,
74+
buffers,
75+
parity: int): LeoEncoderBackend =
7976
## Create an instance of an Leopard Encoder backend
80-
##
77+
##
8178
LeoEncoderBackend(
8279
blockSize: blockSize,
8380
buffers: buffers,
8481
parity: parity)
8582

8683
proc new*(
87-
T: type LeoDecoderBackend,
88-
blockSize,
89-
buffers,
90-
parity: int
91-
): LeoDecoderBackend =
84+
T: type LeoDecoderBackend,
85+
blockSize,
86+
buffers,
87+
parity: int): LeoDecoderBackend =
9288
## Create an instance of an Leopard Decoder backend
93-
##
89+
##
9490
LeoDecoderBackend(
9591
blockSize: blockSize,
9692
buffers: buffers,

codex/erasure/erasure.nim

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ proc init*(
241241

242242
let
243243
rounded = roundUp(manifest.blocksCount, ecK)
244-
steps = divUp(manifest.blocksCount, ecK)
244+
steps = divUp(rounded, ecK)
245245
blocksCount = rounded + (steps * ecM)
246246

247247
success EncodingParams(

codex/logutils.nim

+2
Original file line numberDiff line numberDiff line change
@@ -239,3 +239,5 @@ formatIt(LogFormat.textLines, Cid): shortLog($it)
239239
formatIt(LogFormat.json, Cid): $it
240240
formatIt(UInt256): $it
241241
formatIt(MultiAddress): $it
242+
formatIt(LogFormat.textLines, array[32, byte]): it.short0xHexLog
243+
formatIt(LogFormat.json, array[32, byte]): it.to0xHex

codex/node.nim

+24-15
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ proc onStore(
556556
trace "Unable to build slot", err = err.msg
557557
return failure(err)
558558

559+
trace "Slot successfully retrieved and reconstructed"
560+
559561
if cid =? slotRoot.toSlotCid() and cid != manifest.slotRoots[slotIdx.int]:
560562
trace "Slot root mismatch", manifest = manifest.slotRoots[slotIdx.int], recovered = slotRoot.toSlotCid()
561563
return failure(newException(CodexError, "Slot root mismatch"))
@@ -593,25 +595,32 @@ proc onProve(
593595
error "Unable to fetch manifest for cid", err = err.msg
594596
return failure(err)
595597

596-
without builder =? Poseidon2Builder.new(self.networkStore.localStore, manifest), err:
597-
error "Unable to create slots builder", err = err.msg
598-
return failure(err)
598+
when defined(verify_circuit):
599+
without (inputs, proof) =? await prover.prove(slotIdx, manifest, challenge), err:
600+
error "Unable to generate proof", err = err.msg
601+
return failure(err)
599602

600-
without sampler =? DataSampler.new(slotIdx, self.networkStore.localStore, builder), err:
601-
error "Unable to create data sampler", err = err.msg
602-
return failure(err)
603+
without checked =? await prover.verify(proof, inputs), err:
604+
error "Unable to verify proof", err = err.msg
605+
return failure(err)
603606

604-
without proofInput =? await sampler.getProofInput(challenge, nSamples = 3), err:
605-
error "Unable to get proof input for slot", err = err.msg
606-
return failure(err)
607+
if not checked:
608+
error "Proof verification failed"
609+
return failure("Proof verification failed")
607610

608-
# Todo: send proofInput to circuit. Get proof. (Profit, repeat.)
611+
trace "Proof verified successfully"
612+
else:
613+
without (_, proof) =? await prover.prove(slotIdx, manifest, challenge), err:
614+
error "Unable to generate proof", err = err.msg
615+
return failure(err)
609616

610-
# For now: dummy proof that is not all zero's, so that it is accepted by the
611-
# dummy verifier:
612-
var proof = Groth16Proof.default
613-
proof.a.x = 42.u256
614-
success(proof)
617+
let groth16Proof = proof.toGroth16Proof()
618+
trace "Proof generated successfully", groth16Proof
619+
620+
success groth16Proof
621+
else:
622+
warn "Prover not enabled"
623+
failure "Prover not enabled"
615624

616625
proc onExpiryUpdate(
617626
self: CodexNodeRef,

codex/sales/reservations.nim

+7-6
Original file line numberDiff line numberDiff line change
@@ -325,8 +325,9 @@ proc createReservation*(
325325
return failure(error)
326326

327327
if availability.size < slotSize:
328-
let error = newException(BytesOutOfBoundsError, "trying to reserve an " &
329-
"amount of bytes that is greater than the total size of the Availability")
328+
let error = newException(
329+
BytesOutOfBoundsError,
330+
"trying to reserve an amount of bytes that is greater than the total size of the Availability")
330331
return failure(error)
331332

332333
if createResErr =? (await self.update(reservation)).errorOption:
@@ -427,9 +428,9 @@ proc release*(
427428
return failure(error)
428429

429430
if reservation.size < bytes.u256:
430-
let error = newException(BytesOutOfBoundsError,
431-
"trying to release an amount of bytes that is greater than the total " &
432-
"size of the Reservation")
431+
let error = newException(
432+
BytesOutOfBoundsError,
433+
"trying to release an amount of bytes that is greater than the total size of the Reservation")
433434
return failure(error)
434435

435436
if releaseErr =? (await self.repo.release(bytes)).errorOption:
@@ -540,7 +541,7 @@ proc findAvailability*(
540541

541542
return some availability
542543

543-
trace "availiability did not match",
544+
trace "availability did not match",
544545
size, availsize = availability.size,
545546
duration, availDuration = availability.duration,
546547
minPrice, availMinPrice = availability.minPrice,

0 commit comments

Comments
 (0)