Merge remote-tracking branch 'origin/master' into node-wire-prover
This commit is contained in:
commit
293ec2d788
61
BUILDING.md
61
BUILDING.md
|
@ -24,7 +24,7 @@ Other approaches may be viable. On macOS, some users may prefer [MacPorts](https
|
||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
|
|
||||||
The current implementation of Codex's zero-knowledge proving circuit requires the installation of rust v1.76.0 or greater. Be sure to install it for your OS and add it to your terminal's path such that the command `cargo --version` gives a compatible version.
|
The current implementation of Codex's zero-knowledge proving circuit requires the installation of rust v1.74.0 or greater. Be sure to install it for your OS and add it to your terminal's path such that the command `cargo --version` gives a compatible version.
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
|
@ -32,35 +32,36 @@ The current implementation of Codex's zero-knowledge proving circuit requires th
|
||||||
|
|
||||||
On a bare bones installation of Debian (or a distribution derived from Debian, such as Ubuntu), run
|
On a bare bones installation of Debian (or a distribution derived from Debian, such as Ubuntu), run
|
||||||
|
|
||||||
```text
|
```shell
|
||||||
$ apt-get update && apt-get install build-essential cmake curl git
|
apt-get update && apt-get install build-essential cmake curl git rustc cargo
|
||||||
```
|
```
|
||||||
|
|
||||||
Non-Debian distributions have different package managers: `apk`, `dnf`, `pacman`, `rpm`, `yum`, etc.
|
Non-Debian distributions have different package managers: `apk`, `dnf`, `pacman`, `rpm`, `yum`, etc.
|
||||||
|
|
||||||
For example, on a bare bones installation of Fedora, run
|
For example, on a bare bones installation of Fedora, run
|
||||||
|
|
||||||
```text
|
```shell
|
||||||
$ dnf install @development-tools cmake gcc-c++ which
|
dnf install @development-tools cmake gcc-c++ rust cargo
|
||||||
```
|
```
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
Install the [Xcode Command Line Tools](https://mac.install.guide/commandlinetools/index.html) by opening a terminal and running
|
Install the [Xcode Command Line Tools](https://mac.install.guide/commandlinetools/index.html) by opening a terminal and running
|
||||||
```text
|
```shell
|
||||||
$ xcode-select --install
|
xcode-select --install
|
||||||
```
|
```
|
||||||
|
|
||||||
Install [Homebrew (`brew`)](https://brew.sh/) and in a new terminal run
|
Install [Homebrew (`brew`)](https://brew.sh/) and in a new terminal run
|
||||||
```text
|
```shell
|
||||||
$ brew install bash cmake
|
brew install bash cmake rust
|
||||||
```
|
```
|
||||||
|
|
||||||
Check that `PATH` is setup correctly
|
Check that `PATH` is setup correctly
|
||||||
```text
|
```shell
|
||||||
$ which bash cmake
|
which bash cmake
|
||||||
/usr/local/bin/bash
|
|
||||||
/usr/local/bin/cmake
|
# /usr/local/bin/bash
|
||||||
|
# /usr/local/bin/cmake
|
||||||
```
|
```
|
||||||
|
|
||||||
### Windows + MSYS2
|
### Windows + MSYS2
|
||||||
|
@ -72,9 +73,9 @@ Download and run the installer from [msys2.org](https://www.msys2.org/).
|
||||||
Launch an MSYS2 [environment](https://www.msys2.org/docs/environments/). UCRT64 is generally recommended: from the Windows *Start menu* select `MSYS2 MinGW UCRT x64`.
|
Launch an MSYS2 [environment](https://www.msys2.org/docs/environments/). UCRT64 is generally recommended: from the Windows *Start menu* select `MSYS2 MinGW UCRT x64`.
|
||||||
|
|
||||||
Assuming a UCRT64 environment, in Bash run
|
Assuming a UCRT64 environment, in Bash run
|
||||||
```text
|
```shell
|
||||||
$ pacman -Suy
|
pacman -Suy
|
||||||
$ pacman -S base-devel git unzip mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-rust
|
pacman -S base-devel git unzip mingw-w64-ucrt-x86_64-toolchain mingw-w64-ucrt-x86_64-cmake mingw-w64-ucrt-x86_64-rust
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- #### Headless Windows container -->
|
<!-- #### Headless Windows container -->
|
||||||
|
@ -113,27 +114,27 @@ It is possible that nim-codex can be built and run on other platforms supported
|
||||||
## Repository
|
## Repository
|
||||||
|
|
||||||
In Bash run
|
In Bash run
|
||||||
```text
|
```shell
|
||||||
$ git clone https://github.com/codex-storage/nim-codex.git repos/nim-codex && cd repos/nim-codex
|
git clone https://github.com/codex-storage/nim-codex.git repos/nim-codex && cd repos/nim-codex
|
||||||
```
|
```
|
||||||
|
|
||||||
nim-codex uses the [nimbus-build-system](https://github.com/status-im/nimbus-build-system#readme), so next run
|
nim-codex uses the [nimbus-build-system](https://github.com/status-im/nimbus-build-system), so next run
|
||||||
```text
|
```shell
|
||||||
$ make update
|
make update
|
||||||
```
|
```
|
||||||
|
|
||||||
This step can take a while to complete because by default it builds the [Nim compiler](https://nim-lang.org/docs/nimc.html).
|
This step can take a while to complete because by default it builds the [Nim compiler](https://nim-lang.org/docs/nimc.html).
|
||||||
|
|
||||||
To see more output from `make` pass `V=1`. This works for all `make` targets in projects using the nimbus-build-system
|
To see more output from `make` pass `V=1`. This works for all `make` targets in projects using the nimbus-build-system
|
||||||
```text
|
```shell
|
||||||
$ make V=1 update
|
make V=1 update
|
||||||
```
|
```
|
||||||
|
|
||||||
## Executable
|
## Executable
|
||||||
|
|
||||||
In Bash run
|
In Bash run
|
||||||
```text
|
```shell
|
||||||
$ make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
The default `make` target creates the `build/codex` executable.
|
The default `make` target creates the `build/codex` executable.
|
||||||
|
@ -145,8 +146,8 @@ See the [instructions](README.md#cli-options) in the main readme.
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
In Bash run
|
In Bash run
|
||||||
```text
|
```shell
|
||||||
$ make test
|
make test
|
||||||
```
|
```
|
||||||
|
|
||||||
### testAll
|
### testAll
|
||||||
|
@ -156,9 +157,11 @@ $ make test
|
||||||
To run the integration tests, an Ethereum test node is required. Follow these instructions to set it up.
|
To run the integration tests, an Ethereum test node is required. Follow these instructions to set it up.
|
||||||
|
|
||||||
##### Windows (do this before 'All platforms')
|
##### Windows (do this before 'All platforms')
|
||||||
|
|
||||||
1. Download and install Visual Studio 2017 or newer. (Not VSCode!) In the Workloads overview, enable `Desktop development with C++`. ( https://visualstudio.microsoft.com )
|
1. Download and install Visual Studio 2017 or newer. (Not VSCode!) In the Workloads overview, enable `Desktop development with C++`. ( https://visualstudio.microsoft.com )
|
||||||
|
|
||||||
##### All platforms
|
##### All platforms
|
||||||
|
|
||||||
1. Install NodeJS (tested with v18.14.0), consider using NVM as a version manager. [Node Version Manager (`nvm`)](https://github.com/nvm-sh/nvm#readme)
|
1. Install NodeJS (tested with v18.14.0), consider using NVM as a version manager. [Node Version Manager (`nvm`)](https://github.com/nvm-sh/nvm#readme)
|
||||||
1. Open a terminal
|
1. Open a terminal
|
||||||
1. Go to the vendor/codex-contracts-eth folder: `cd /<git-root>/vendor/codex-contracts-eth/`
|
1. Go to the vendor/codex-contracts-eth folder: `cd /<git-root>/vendor/codex-contracts-eth/`
|
||||||
|
@ -177,6 +180,6 @@ The `testAll` target runs the same tests as `make test` and also runs tests for
|
||||||
To run `make testAll`.
|
To run `make testAll`.
|
||||||
|
|
||||||
Use a new terminal to run:
|
Use a new terminal to run:
|
||||||
```text
|
```shell
|
||||||
$ make testAll
|
make testAll
|
||||||
```
|
```
|
||||||
|
|
|
@ -12,7 +12,7 @@ requires "bearssl >= 0.1.4"
|
||||||
requires "chronicles >= 0.7.2"
|
requires "chronicles >= 0.7.2"
|
||||||
requires "chronos >= 2.5.2"
|
requires "chronos >= 2.5.2"
|
||||||
requires "confutils"
|
requires "confutils"
|
||||||
requires "ethers >= 0.7.1 & < 0.8.0"
|
requires "ethers >= 0.7.3 & < 0.8.0"
|
||||||
requires "libbacktrace"
|
requires "libbacktrace"
|
||||||
requires "libp2p"
|
requires "libp2p"
|
||||||
requires "metrics"
|
requires "metrics"
|
||||||
|
|
|
@ -540,13 +540,19 @@ proc taskHandler*(b: BlockExcEngine, task: BlockExcPeerCtx) {.gcsafe, async.} =
|
||||||
|
|
||||||
var
|
var
|
||||||
wantsBlocks = task.peerWants.filterIt(
|
wantsBlocks = task.peerWants.filterIt(
|
||||||
it.wantType == WantType.WantBlock
|
it.wantType == WantType.WantBlock and not it.inFlight
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc updateInFlight(addresses: seq[BlockAddress], inFlight: bool) =
|
||||||
|
for peerWant in task.peerWants.mitems:
|
||||||
|
if peerWant.address in addresses:
|
||||||
|
peerWant.inFlight = inFlight
|
||||||
|
|
||||||
trace "wantsBlocks", peer = task.id, n = wantsBlocks.len
|
trace "wantsBlocks", peer = task.id, n = wantsBlocks.len
|
||||||
if wantsBlocks.len > 0:
|
if wantsBlocks.len > 0:
|
||||||
trace "Got peer want blocks list", items = wantsBlocks.len
|
# Mark wants as in-flight.
|
||||||
|
let wantAddresses = wantsBlocks.mapIt(it.address)
|
||||||
|
updateInFlight(wantAddresses, true)
|
||||||
wantsBlocks.sort(SortOrder.Descending)
|
wantsBlocks.sort(SortOrder.Descending)
|
||||||
|
|
||||||
proc localLookup(e: WantListEntry): Future[?!BlockDelivery] {.async.} =
|
proc localLookup(e: WantListEntry): Future[?!BlockDelivery] {.async.} =
|
||||||
|
@ -563,13 +569,16 @@ proc taskHandler*(b: BlockExcEngine, task: BlockExcPeerCtx) {.gcsafe, async.} =
|
||||||
|
|
||||||
let
|
let
|
||||||
blocksDeliveryFut = await allFinished(wantsBlocks.map(localLookup))
|
blocksDeliveryFut = await allFinished(wantsBlocks.map(localLookup))
|
||||||
|
|
||||||
# Extract successfully received blocks
|
|
||||||
let
|
|
||||||
blocksDelivery = blocksDeliveryFut
|
blocksDelivery = blocksDeliveryFut
|
||||||
.filterIt(it.completed and it.read.isOk)
|
.filterIt(it.completed and it.read.isOk)
|
||||||
.mapIt(it.read.get)
|
.mapIt(it.read.get)
|
||||||
|
|
||||||
|
# All the wants that failed local lookup must be set to not-in-flight again.
|
||||||
|
let
|
||||||
|
successAddresses = blocksDelivery.mapIt(it.address)
|
||||||
|
failedAddresses = wantAddresses.filterIt(it notin successAddresses)
|
||||||
|
updateInFlight(failedAddresses, false)
|
||||||
|
|
||||||
if blocksDelivery.len > 0:
|
if blocksDelivery.len > 0:
|
||||||
trace "Sending blocks to peer", peer = task.id, blocks = blocksDelivery.len
|
trace "Sending blocks to peer", peer = task.id, blocks = blocksDelivery.len
|
||||||
await b.network.request.sendBlocksDelivery(
|
await b.network.request.sendBlocksDelivery(
|
||||||
|
@ -579,13 +588,8 @@ proc taskHandler*(b: BlockExcEngine, task: BlockExcPeerCtx) {.gcsafe, async.} =
|
||||||
|
|
||||||
codex_block_exchange_blocks_sent.inc(blocksDelivery.len.int64)
|
codex_block_exchange_blocks_sent.inc(blocksDelivery.len.int64)
|
||||||
|
|
||||||
trace "About to remove entries from peerWants", blocks = blocksDelivery.len, items = task.peerWants.len
|
task.peerWants.keepItIf(it.address notin successAddresses)
|
||||||
# Remove successfully sent blocks
|
trace "Removed entries from peerWants", peerWants = task.peerWants.len
|
||||||
task.peerWants.keepIf(
|
|
||||||
proc(e: WantListEntry): bool =
|
|
||||||
not blocksDelivery.anyIt( it.address == e.address )
|
|
||||||
)
|
|
||||||
trace "Removed entries from peerWants", items = task.peerWants.len
|
|
||||||
|
|
||||||
proc blockexcTaskRunner(b: BlockExcEngine) {.async.} =
|
proc blockexcTaskRunner(b: BlockExcEngine) {.async.} =
|
||||||
## process tasks
|
## process tasks
|
||||||
|
|
|
@ -29,6 +29,7 @@ type
|
||||||
cancel*: bool # Whether this revokes an entry
|
cancel*: bool # Whether this revokes an entry
|
||||||
wantType*: WantType # Note: defaults to enum 0, ie Block
|
wantType*: WantType # Note: defaults to enum 0, ie Block
|
||||||
sendDontHave*: bool # Note: defaults to false
|
sendDontHave*: bool # Note: defaults to false
|
||||||
|
inFlight*: bool # Whether block sending is in progress. Not serialized.
|
||||||
|
|
||||||
WantList* = object
|
WantList* = object
|
||||||
entries*: seq[WantListEntry] # A list of wantList entries
|
entries*: seq[WantListEntry] # A list of wantList entries
|
||||||
|
|
|
@ -58,6 +58,14 @@ type
|
||||||
CodexPrivateKey* = libp2p.PrivateKey # alias
|
CodexPrivateKey* = libp2p.PrivateKey # alias
|
||||||
EthWallet = ethers.Wallet
|
EthWallet = ethers.Wallet
|
||||||
|
|
||||||
|
proc waitForSync(provider: Provider): Future[void] {.async.} =
|
||||||
|
var sleepTime = 1
|
||||||
|
while await provider.isSyncing:
|
||||||
|
notice "Waiting for Ethereum provider to sync..."
|
||||||
|
await sleepAsync(sleepTime.seconds)
|
||||||
|
if sleepTime < 10:
|
||||||
|
inc sleepTime
|
||||||
|
|
||||||
proc bootstrapInteractions(
|
proc bootstrapInteractions(
|
||||||
s: CodexServer): Future[void] {.async.} =
|
s: CodexServer): Future[void] {.async.} =
|
||||||
## bootstrap interactions and return contracts
|
## bootstrap interactions and return contracts
|
||||||
|
@ -73,6 +81,7 @@ proc bootstrapInteractions(
|
||||||
quit QuitFailure
|
quit QuitFailure
|
||||||
|
|
||||||
let provider = JsonRpcProvider.new(config.ethProvider)
|
let provider = JsonRpcProvider.new(config.ethProvider)
|
||||||
|
await waitForSync(provider)
|
||||||
var signer: Signer
|
var signer: Signer
|
||||||
if account =? config.ethAccount:
|
if account =? config.ethAccount:
|
||||||
signer = provider.getSigner(account)
|
signer = provider.getSigner(account)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Variables
|
# Variables
|
||||||
ARG BUILDER=ubuntu:lunar-20230415
|
ARG BUILDER=ubuntu:22.04
|
||||||
ARG IMAGE=${BUILDER}
|
ARG IMAGE=${BUILDER}
|
||||||
ARG BUILD_HOME=/src
|
ARG BUILD_HOME=/src
|
||||||
ARG MAKE_PARALLEL=${MAKE_PARALLEL:-4}
|
ARG MAKE_PARALLEL=${MAKE_PARALLEL:-4}
|
||||||
|
@ -13,9 +13,7 @@ ARG BUILD_HOME
|
||||||
ARG MAKE_PARALLEL
|
ARG MAKE_PARALLEL
|
||||||
ARG NIMFLAGS
|
ARG NIMFLAGS
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y git cmake curl make bash lcov build-essential nim
|
RUN apt-get update && apt-get install -y git cmake curl make bash lcov build-essential rustc cargo
|
||||||
RUN curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
|
||||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
|
||||||
|
|
||||||
WORKDIR ${BUILD_HOME}
|
WORKDIR ${BUILD_HOME}
|
||||||
COPY . .
|
COPY . .
|
||||||
|
@ -32,7 +30,7 @@ ARG NAT_IP_AUTO
|
||||||
WORKDIR ${APP_HOME}
|
WORKDIR ${APP_HOME}
|
||||||
COPY --from=builder ${BUILD_HOME}/build/codex /usr/local/bin
|
COPY --from=builder ${BUILD_HOME}/build/codex /usr/local/bin
|
||||||
COPY --chmod=0755 docker/docker-entrypoint.sh /
|
COPY --chmod=0755 docker/docker-entrypoint.sh /
|
||||||
RUN apt-get update && apt-get install -y libgomp1 bash curl && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y libgomp1 bash curl jq && rm -rf /var/lib/apt/lists/*
|
||||||
ENV NAT_IP_AUTO=${NAT_IP_AUTO}
|
ENV NAT_IP_AUTO=${NAT_IP_AUTO}
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
CMD ["codex"]
|
CMD ["codex"]
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
# Environment variables from files
|
# Environment variables from files
|
||||||
if [[ -n "${ENV_PATH}" ]]; then
|
if [[ -n "${ENV_PATH}" ]]; then
|
||||||
[[ -f ${ENV_PATH} ]] && source ${ENV_PATH} || for f in ${ENV_PATH}/*; do source $f; done
|
set -a
|
||||||
|
[[ -f "${ENV_PATH}" ]] && source "${ENV_PATH}" || for f in "${ENV_PATH}"/*; do source "$f"; done
|
||||||
|
set +a
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Parameters
|
# Parameters
|
||||||
|
|
|
@ -490,6 +490,39 @@ asyncchecksuite "Task Handler":
|
||||||
|
|
||||||
await engine.taskHandler(peersCtx[0])
|
await engine.taskHandler(peersCtx[0])
|
||||||
|
|
||||||
|
test "Should set in-flight for outgoing blocks":
|
||||||
|
proc sendBlocksDelivery(
|
||||||
|
id: PeerId,
|
||||||
|
blocksDelivery: seq[BlockDelivery]) {.gcsafe, async.} =
|
||||||
|
check peersCtx[0].peerWants[0].inFlight
|
||||||
|
|
||||||
|
for blk in blocks:
|
||||||
|
(await engine.localStore.putBlock(blk)).tryGet()
|
||||||
|
engine.network.request.sendBlocksDelivery = sendBlocksDelivery
|
||||||
|
|
||||||
|
peersCtx[0].peerWants.add(WantListEntry(
|
||||||
|
address: blocks[0].address,
|
||||||
|
priority: 50,
|
||||||
|
cancel: false,
|
||||||
|
wantType: WantType.WantBlock,
|
||||||
|
sendDontHave: false,
|
||||||
|
inFlight: false)
|
||||||
|
)
|
||||||
|
await engine.taskHandler(peersCtx[0])
|
||||||
|
|
||||||
|
test "Should clear in-flight when local lookup fails":
|
||||||
|
peersCtx[0].peerWants.add(WantListEntry(
|
||||||
|
address: blocks[0].address,
|
||||||
|
priority: 50,
|
||||||
|
cancel: false,
|
||||||
|
wantType: WantType.WantBlock,
|
||||||
|
sendDontHave: false,
|
||||||
|
inFlight: false)
|
||||||
|
)
|
||||||
|
await engine.taskHandler(peersCtx[0])
|
||||||
|
|
||||||
|
check not peersCtx[0].peerWants[0].inFlight
|
||||||
|
|
||||||
test "Should send presence":
|
test "Should send presence":
|
||||||
let present = blocks
|
let present = blocks
|
||||||
let missing = @[Block.new("missing".toBytes).tryGet()]
|
let missing = @[Block.new("missing".toBytes).tryGet()]
|
||||||
|
|
Loading…
Reference in New Issue