Skip to content

Commit

Permalink
Merge pull request #11 from CirclesUBI/dev
Browse files Browse the repository at this point in the history
add a section about the dencun incompatibility for spaceneth
  • Loading branch information
jaensen authored May 16, 2024
2 parents 87f8cc8 + 04c4684 commit 013e612
Show file tree
Hide file tree
Showing 4 changed files with 295 additions and 8 deletions.
1 change: 1 addition & 0 deletions Circles.sln
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{B30CB7
package.json = package.json
deploy.sh = deploy.sh
.gitignore = .gitignore
add-deploy-script-tp-v2-repo.sh = add-deploy-script-tp-v2-repo.sh
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Circles.Index.Postgres", "Circles.Index.Postgres\Circles.Index.Postgres.csproj", "{8ED5FCD0-0995-44E7-9A11-E0EB03BB0832}"
Expand Down
108 changes: 106 additions & 2 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,115 @@ Since a new spaceneth node is empty except for the genesis block, you need to de
git submodule update --init --recursive
```

To deploy the contracts, we add a script to the Circles contracts repository that deploys the contracts to the spaceneth
node.

```bash
# Add the deploy script to the Circles contracts repository
./add-deploy-script-tp-v2-repo.sh
```

As a last step, we need to replace the `tload` and `tstore` based reentrancy guards with a more classic approach.
Spaceneth does not support these instructions.

1. Open `circles-contracts-v2/src/hub/Hub.sol`
2. Replace this modifier:
```solidity
modifier nonReentrant(uint8 _code) {
assembly {
if tload(0) { revert(0, 0) }
tstore(0, 1)
}
_;
assembly {
tstore(0, 0)
}
}
```

with this modifier:

```solidity
bool private _reentrancyGuard;
modifier nonReentrant(uint8 _code) {
if (_reentrancyGuard) {
revert CirclesReentrancyGuard(_code);
}
_reentrancyGuard = true;
_;
_reentrancyGuard = false;
}
```
3. Open `circles-contracts-v2/foundry.toml`
4. Remove this line:
```toml
evm_version = 'cancun'
```


Now you can deploy the contracts to the spaceneth node.

```bash
# Deploy the contracts
npm install && ./deploy.sh
```

#### Blockscout

You can access the blockscout instance at `http://localhost:4000`.

#### Get a funded account

You can get a funded account private key by running:

```bash
npm install
node createFundedAccount.js
```

#### Manipulate time

You can fast-forward the time by running:

```bash
curl -X POST -H "Content-Type: application/json" -d '{"fake_time": "+1d x1"}' http://localhost:5000/set_time
```

**Explanation:**

```json
{
"fake_time": "+1d x1"
}
```

`+1d` means to offset the current time by 1 day. `x1` means that the time will pass as real time. If you want to
fast-forward the time, you can increase the number of `x` (e.g. `x10`).

_NOTE: This will restart the nethermind node._

#### Reset the spaceneth node

If you want to start over, you can reset the spaceneth node by running:

```bash
# Stop the stack
docker compose -f docker-compose.spaceneth.yml down
```

```bash
# Delete all persisted data
sudo rm -rf .state/nethermind-spaceneth
sudo rm -rf .state/postgres-spaceneth
sudo rm -rf .state/postgres2-spaceneth
sudo rm -rf .state/redis-spaceneth
```

```bash
# Start the stack again
docker compose -f docker-compose.spaceneth.yml up
```

## Circles RPC methods

### circles_getTotalBalance
Expand Down Expand Up @@ -215,7 +319,7 @@ following properties:
* `distinct` - If set to `true`, only distinct rows are returned.
* `limit` - The maximum number of rows to return (defaults to max. 1000).

*There is no default order, so make sure to always add sensible order columns.*
_NOTE: There is no default order, so make sure to always add sensible order columns._

#### Available namespaces, tables and columns

Expand Down Expand Up @@ -270,7 +374,7 @@ Namespaces and tables:

#### Pagination

You can use the combination of `blockNumber`, `transactionIndex` and `logIndex`
You can use the combination of `blockNumber`, `transactionIndex` and `logIndex`
(+ `batchIndex` in the case of batch events) together with a `limit` to paginate through the results.

#### Example
Expand Down
182 changes: 182 additions & 0 deletions add-deploy-script-tp-v2-repo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Write an additional deployment script to the circles-contracts-v2 repository.
cat << 'EOF' > ./circles-contracts-v2/script/deployments/genericDeploy.sh
#!/bin/bash
# Function to deploy contract and store deployment details
deploy_and_store_details() {
local contract_name=$1
local precalculated_address=$2
local deployment_output
local deployed_address
echo "" >&2
echo "Deploying ${contract_name}..." >&2
deployment_output=$(forge create \
--rpc-url ${RPC_URL} \
--private-key ${PRIVATE_KEY} \
--optimizer-runs 200 \
--chain-id ${CHAIN_ID} \
--delay 10 \
"${@:3}") # Passes all arguments beyond the second to forge create
deployed_address=$(echo "$deployment_output" | grep "Deployed to:" | awk '{print $3}')
echo "${contract_name} deployed at ${deployed_address}" >&2
# Verify that the deployed address matches the precalculated address
if [ "$deployed_address" = "$precalculated_address" ]; then
echo "Verification Successful: Deployed address matches the precalculated address for ${contract_name}." >&2
else
echo "Verification Failed: Deployed address does not match the precalculated address for ${contract_name}." >&2
echo "Precalculated Address: $precalculated_address" >&2
echo "Deployed Address: $deployed_address" >&2
# exit the script if the addresses don't match
exit 1
fi
# Define the filename for constructor arguments based on the contract name
arguments_file="constructorArgs_${contract_name}.txt"
arguments_path="${OUT_DIR}/${arguments_file}"
# Save constructor arguments to the file, skip "--constructor-args"
echo "${@:5}" > "${arguments_path}"
# Store deployment details in a file
echo "{\"contractName\":\"${contract_name}\",\"deployedAddress\":\"${deployed_address}\",\"sourcePath\":\"$3\",\"constructor-args\":\"${@:5}\",\"argumentsFile\":\"${arguments_file}\"}" >> "${deployment_details_file}"
# return the deployed address
echo "$deployed_address"
}
# Function to generate a compact and short identifier
generate_identifier() {
# Fetch the current Git commit hash and take the first 7 characters
local git_commit_short=$(git rev-parse HEAD | cut -c1-7)
# Get the current date and time in a compact format (YYMMDD-HMS)
local deployment_date=$1
# Fetch version from package.json
local version=$(node -p "require('./package.json').version")
# Define the summary file name with version, short git commit, and compact date
echo "${version}-${git_commit_short}-${deployment_date}"
}
# Set the environment variables, also for use in node script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
source "$DIR/../../.env"
# fallback URI
URI='https://fallback.aboutcircles.com/v1/circles/{id}.json'
export PRIVATE_KEY=$PRIVATE_KEY
export RPC_URL=$RPC_URL
# Get the current date and time in a compact format (YYMMDD-HMS) outside the functions
deployment_date=$(date "+%y%m%d-%H%M%S")
deployment_date_long=$(date "+%Y-%m-%d %H:%M:%S")
identifier=$(generate_identifier $deployment_date)
# Run the Node.js script to predict contract addresses
# Assuming predictAddresses.js is in the current directory
read DEPLOYER_ADDRESS NONCE_USED HUB_ADDRESS_01 MIGRATION_ADDRESS_02 NAMEREGISTRY_ADDRESS_03 \
ERC20LIFT_ADDRESS_04 STANDARD_TREASURY_ADDRESS_05 BASE_GROUPMINTPOLICY_ADDRESS_06 \
MASTERCOPY_DEMURRAGE_ERC20_ADDRESS_07 MASTERCOPY_INFLATIONARY_ERC20_ADDRESS_08 \
MASTERCOPY_STANDARD_VAULT_09 \
<<< $(node $DIR/predictDeploymentAddresses.js)
# Create a directory for the deployment and go there after calling node script
mkdir -p "$DIR/generic-$identifier"
OUT_DIR="$DIR/generic-$identifier"
# Use DEPLOYER_ADDRESS and NONCE_USED as needed
echo "Deployer Address: $DEPLOYER_ADDRESS, Nonce Used: $NONCE_USED"
# Log the predicted deployment addresses
echo "Predicted deployment addresses:"
echo "==============================="
echo "Hub: \"${HUB_ADDRESS_01}\","
echo "Migration: \"${MIGRATION_ADDRESS_02}\","
echo "NameRegistry: \"${NAMEREGISTRY_ADDRESS_03}\","
echo "ERC20Lift: \"${ERC20LIFT_ADDRESS_04}\","
echo "StandardTreasury: \"${STANDARD_TREASURY_ADDRESS_05}\","
echo "BaseGroupMintPolicy: \"${BASE_GROUPMINTPOLICY_ADDRESS_06}\","
echo "MastercopyDemurrageERC20: \"${MASTERCOPY_DEMURRAGE_ERC20_ADDRESS_07}\","
echo "MastercopyInflationaryERC20: \"${MASTERCOPY_INFLATIONARY_ERC20_ADDRESS_08}\","
echo "MastercopyStandardVault: \"${MASTERCOPY_STANDARD_VAULT_09}\""
# Deploy the contracts
export deployment_details_file="${OUT_DIR}/generic-artefacts-${identifier}.txt"
echo "Deployment details will be stored in $deployment_details_file"
echo ""
echo "Starting deployment..."
echo "======================"
HUB=$(deploy_and_store_details "Hub" $HUB_ADDRESS_01 \
src/hub/Hub.sol:Hub \
--constructor-args $V1_HUB_ADDRESS \
$NAMEREGISTRY_ADDRESS_03 $MIGRATION_ADDRESS_02 $ERC20LIFT_ADDRESS_04 \
$STANDARD_TREASURY_ADDRESS_05 $INFLATION_DAY_ZERO \
$BOOTSTRAP_ONE_YEAR $URI)
MIGRATION=$(deploy_and_store_details "Migration" $MIGRATION_ADDRESS_02 \
src/migration/Migration.sol:Migration \
--constructor-args $V1_HUB_ADDRESS $HUB_ADDRESS_01)
NAME_REGISTRY=$(deploy_and_store_details "NameRegistry" $NAMEREGISTRY_ADDRESS_03 \
src/names/NameRegistry.sol:NameRegistry \
--constructor-args $HUB_ADDRESS_01)
ERC20LIFT=$(deploy_and_store_details "ERC20Lift" $ERC20LIFT_ADDRESS_04 \
src/lift/ERC20Lift.sol:ERC20Lift \
--constructor-args $HUB_ADDRESS_01 \
$NAMEREGISTRY_ADDRESS_03 $MASTERCOPY_DEMURRAGE_ERC20_ADDRESS_07 \
$MASTERCOPY_INFLATIONARY_ERC20_ADDRESS_08)
STANDARD_TREASURY=$(deploy_and_store_details "StandardTreasury" $STANDARD_TREASURY_ADDRESS_05 \
src/treasury/StandardTreasury.sol:StandardTreasury \
--constructor-args $HUB_ADDRESS_01 $MASTERCOPY_STANDARD_VAULT_09)
BASE_MINTPOLICY=$(deploy_and_store_details "BaseGroupMintPolicy" $BASE_GROUPMINTPOLICY_ADDRESS_06 \
src/groups/BaseMintPolicy.sol:MintPolicy)
MC_ERC20_DEMURRAGE=$(deploy_and_store_details "MastercopyDemurrageERC20" $MASTERCOPY_DEMURRAGE_ERC20_ADDRESS_07 \
src/lift/DemurrageCircles.sol:DemurrageCircles)
MC_ERC20_INFLATION=$(deploy_and_store_details "MastercopyInflationaryERC20" $MASTERCOPY_INFLATIONARY_ERC20_ADDRESS_08 \
src/lift/InflationaryCircles.sol:InflationaryCircles)
MC_STANDARD_VAULT=$(deploy_and_store_details "MastercopyStandardVault" $MASTERCOPY_STANDARD_VAULT_09 \
src/treasury/StandardVault.sol:StandardVault)
# log to file
# Use the function to generate the file name
summary_file="${OUT_DIR}/generic-${identifier}.log"
# Now you can use $summary_file for logging
{
echo "generic deployment"
echo "================="
echo "Deployment Date: $deployment_date_long"
echo "Version: $(node -p "require('./package.json').version")"
echo "Git Commit: $(git rev-parse HEAD)"
echo "Deployer Address: $DEPLOYER_ADDRESS, Intitial nonce: $NONCE_USED"
echo "Compiler Version: v0.8.23+commit.f704f362" # todo: figure out where to extract this from
echo ""
echo "Deployed Contracts:"
echo "Hub: ${HUB}"
echo "Migration: ${MIGRATION}"
echo "NameRegistry: ${NAME_REGISTRY}"
echo "ERC20Lift: ${ERC20LIFT}"
echo "StandardTreasury: ${STANDARD_TREASURY}"
echo "BaseGroupMintPolicy: ${BASE_MINTPOLICY}"
echo "MastercopyDemurrageERC20: ${MC_ERC20_DEMURRAGE}"
echo "MastercopyInflationaryERC20: ${MC_ERC20_INFLATION}"
echo "MastercopyStandardVault: ${MC_STANDARD_VAULT}"
} >> "$summary_file"
EOF

# Ensure the script is executable
chmod +x ./circles-contracts-v2/script/deployments/genericDeploy.sh
12 changes: 6 additions & 6 deletions docker-compose.spaceneth.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ services:
- START_BLOCK=0
- POSTGRES_CONNECTION_STRING=Server=localhost;Port=5432;User Id=postgres;Password=postgres;Database=postgres;Include Error Detail=true;
volumes:
- ./.spaceneth-state/circles-spaceneth/spaceneth_db:/nethermind/spaceneth_db
- ./.spaceneth-state/circles-spaceneth/logs:/nethermind/logs
- ./.spaceneth-state/circles-spaceneth/keystore:/nethermind/keystore
- .state/nethermind-spaceneth/spaceneth_db:/nethermind/spaceneth_db
- .state/nethermind-spaceneth/logs:/nethermind/logs
- .state/nethermind-spaceneth/keystore:/nethermind/keystore

redis_db:
image: 'redis:alpine'
Expand All @@ -25,7 +25,7 @@ services:
command: redis-server
restart: unless-stopped
volumes:
- ./.spaceneth-state/redis-data:/data
- .state/redis-spaceneth:/data

db:
image: postgres:14
Expand All @@ -37,7 +37,7 @@ services:
POSTGRES_USER: 'postgres'
POSTGRES_HOST_AUTH_METHOD: 'trust'
volumes:
- ./.spaceneth-state/postgres-data:/var/lib/postgresql/data
- .state/postgres-spaceneth:/var/lib/postgresql/data
ports:
- 7432:5432

Expand All @@ -51,7 +51,7 @@ services:
POSTGRES_PASSWORD: 'postgres'
POSTGRES_USER: 'postgres'
volumes:
- ./.spaceneth-state/postgres2-data:/var/lib/postgresql/data
- .state/postgres2-spaceneth:/var/lib/postgresql/data
ports:
- 5432:5432

Expand Down

0 comments on commit 013e612

Please sign in to comment.