Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playground check #3079

Merged
merged 39 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2865046
Added new workflow file
mstrug Oct 21, 2024
3ea4444
Added querying order test script
mstrug Oct 21, 2024
1a989f2
Added submitting an order
mstrug Oct 21, 2024
7e14681
Added workflow run on pull request
mstrug Oct 22, 2024
6645221
Added signing order proposal using foundry cast
mstrug Oct 23, 2024
c8d80b4
Updated test script
mstrug Oct 24, 2024
5b71460
Fixed script to pass recovered signer validation
mstrug Oct 24, 2024
ed1544f
Test script cleanup
mstrug Oct 24, 2024
1950774
Propper handling of sellAmount
mstrug Oct 24, 2024
1a8e630
Added wrapping of ETH
mstrug Oct 25, 2024
d5e062f
Added allowances, cleanup
mstrug Oct 25, 2024
b910a21
Updated workflow file
mstrug Oct 25, 2024
7082d38
Added CI job step to free some space in runner image
mstrug Oct 25, 2024
2acd01b
Limited parallel docker compose build
mstrug Oct 25, 2024
3e14f82
Updated workflow file
mstrug Oct 25, 2024
98c05c3
Using container chain-1 cast for sending transactions
mstrug Oct 28, 2024
da918f7
Increased script timeout to 300sec
mstrug Oct 28, 2024
ff42a07
Added 2% slippage
mstrug Oct 28, 2024
3cd6c7c
Another workaround for yarn error
mstrug Oct 28, 2024
7fef055
Seepdup freeing image space
mstrug Oct 28, 2024
3a774e2
Added slippage calculation
mstrug Oct 28, 2024
0872605
Fixed cast call
mstrug Oct 28, 2024
291f4c6
Added storing of docker logs
mstrug Oct 28, 2024
e984344
Updated buyAmmount with slippage
mstrug Oct 28, 2024
9b5c6b6
Merge branch 'main' into ci/playground-check
mstrug Oct 28, 2024
7c970ce
Added run schedule and fixed typoo
mstrug Oct 28, 2024
f0b7298
Updated test script according to comments
mstrug Oct 29, 2024
34046e8
Merge branch 'main' into ci/playground-check
mstrug Oct 29, 2024
44cd21d
Added curl retries
mstrug Oct 29, 2024
8834535
Added waiting for services to be ready
mstrug Oct 29, 2024
c2a0842
Added Slack notificatino on job fail
mstrug Oct 30, 2024
a41c6a1
Added temporary step to test fail scenario
mstrug Oct 30, 2024
15edf3b
Fixed env vars
mstrug Oct 30, 2024
1ac9857
Fixed env vars #2
mstrug Oct 30, 2024
4b10329
Added more conext information to slack notification
mstrug Oct 30, 2024
6806d3d
Added option to specify Slack channel ID
mstrug Oct 30, 2024
b468e2e
Added link for artifacts download
mstrug Oct 30, 2024
5a7737e
Switched to #alerts-barn channel
mstrug Oct 30, 2024
015cb13
Removed testing of failed scenario step
mstrug Oct 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions .github/workflows/playground-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Playground operation check

on:
pull_request:
schedule:
# Run this job once per day
- cron: "0 0 * * *"

jobs:
playground-check:
runs-on: ubuntu-latest
env:
FORK_URL_MAINNET: ${{ secrets.FORK_URL_MAINNET }}
steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false
squadgazzz marked this conversation as resolved.
Show resolved Hide resolved

- name: Checkout code
uses: actions/checkout@v4

- name: Install dependency
run: sudo apt-get -qq update && sudo apt-get -y -q install curl jq

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Test fail scenario
run: exit 1

- name: Setup environment
run: |
cp playground/.env.example playground/.env
sed -i -e 's/ETH_RPC_URL=.*/ETH_RPC_URL=$FORK_URL_MAINNET/g' playground/.env
cat playground/.env

- name: Start docker containers
id: containers
run: |
cd playground
# firstly start explorer container to workaround yarn cache problem
mstrug marked this conversation as resolved.
Show resolved Hide resolved
docker compose -f docker-compose.fork.yml up -d explorer
docker compose -f docker-compose.fork.yml up -d

- name: Execute validation script
id: test_script
run: |
cd playground
./test_playground.sh

- name: Collect docker logs on failure
if: failure()
uses: jwalton/gh-docker-logs@v2
with:
dest: './logs'

- name: Tar logs
if: failure()
run: tar cvzf ./logs.tgz ./logs

- name: Upload logs to GitHub
if: failure()
uses: actions/upload-artifact@master
with:
name: logs.tgz
path: ./logs.tgz
mstrug marked this conversation as resolved.
Show resolved Hide resolved

- name: Slack notification on failure
if: failure()
id: slack
uses: slackapi/[email protected]
with:
payload: |
{
"job_link":"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"actor":"${{ github.actor }}",
"action":"${{ github.action_status }}",
"base_ref":"${{ github.base_ref }}",
"event_name":"${{ github.event_name }}",
"head_ref":"${{ github.head_ref }}",
"step_containers":"${{ steps.containers.conclusion }}",
"step_test_script":"${{ steps.test_script.conclusion }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_PLAYGROUND_CI_WEBHOOK_URL }}
155 changes: 155 additions & 0 deletions playground/test_playground.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/bin/bash

# Fail on all errors
set -e
# Fail on expand of unset variables
set -u

# Setup parameters
HOST=localhost:8080
WETH_ADDRESS="0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" # WETH token
SELL_TOKEN=$WETH_ADDRESS
BUY_TOKEN="0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" # USDC token
SELL_AMOUNT="1000000000000000000" # 1 ETH
SLIPPAGE=2 # 2%
COW_SETTLMENT_CONTRACT="0x9008D19f58AAbD9eD0D60971565AA8510560ab41"
COW_VAULT_RELAYER_CONTRACT="0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"
APPDATA='{"version":"1.3.0","metadata":{}}'
MAXUINT256="115792089237316195423570985008687907853269984665640564039457584007913129639935"

# Following private key is only used for testing purposes in a local environment.
# For security reasons please do not use it on a production network, most likely
# all funds sent to this account will be stolen immediately.
PRIVATE_KEY="0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6"

# Wait for 2 minutes for all services are read
echo "Waiting until all services are ready"
curl --retry 24 --retry-delay 5 --retry-all-errors --fail-with-body -s --show-error \
-H 'accept:application/json' \
http://$HOST/api/v1/token/$BUY_TOKEN/native_price > /dev/null

# Run test flow
echo "Using private key:" $PRIVATE_KEY
receiver=$(cast wallet address $PRIVATE_KEY)

# Calculate AppData hash
app_data_hash=$(cast keccak $APPDATA)

# Deposit WETH
echo "Wrapping some ETH"
docker exec playground-chain-1 cast send --private-key $PRIVATE_KEY --value 3ether $WETH_ADDRESS > /dev/null

echo "Setting WETH allowance"
docker exec playground-chain-1 cast send --private-key $PRIVATE_KEY $WETH_ADDRESS "approve(address, uint)" $COW_VAULT_RELAYER_CONTRACT $MAXUINT256 > /dev/null

echo "Request price qoute for buying USDC for WETH"
quote_response=$( curl --retry 5 --fail-with-body -s --show-error -X 'POST' \
"http://$HOST/api/v1/quote" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"sellToken": "'$SELL_TOKEN'",
"buyToken": "'$BUY_TOKEN'",
"from": "'$receiver'",
"receiver": "'$receiver'",
"sellTokenBalance": "erc20",
"buyTokenBalance": "erc20",
"signingScheme": "eip712",
"onchainOrder": false,
"partiallyFillable": false,
"kind": "sell",
"sellAmountBeforeFee": "'$SELL_AMOUNT'"
}')

buyAmount=$(jq -r --args '.quote.buyAmount' <<< "${quote_response}")
feeAmount=$(jq -r --args '.quote.feeAmount' <<< "${quote_response}")
validTo=$(($(date +%s) + 120)) # validity time: now + 2 minutes
sellAmount=$((SELL_AMOUNT - feeAmount))

# Apply slippage
buyAmount=$((buyAmount * ( 100 - $SLIPPAGE ) / 100 )) # apply slippage

# Prepare EIP712 message
eip712_message=$(jq -r --args '
.quote|=(.appData="'$app_data_hash'") |
.quote|=(.sellAmount="'$sellAmount'") |
.quote|=(.feeAmount="0") |
.quote|=(.buyAmount="'$buyAmount'") |
.quote|=(.validTo='$validTo') |
.quote' <<< "${quote_response}")

# Prepare EIP-712 typed struct
eip712_typed_struct='{
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"Order": [
{ "name": "sellToken", "type": "address" },
{ "name": "buyToken", "type": "address" },
{ "name": "receiver", "type": "address" },
{ "name": "sellAmount", "type": "uint256" },
{ "name": "buyAmount", "type": "uint256" },
{ "name": "validTo", "type": "uint32" },
{ "name": "appData", "type": "bytes32" },
{ "name": "feeAmount", "type": "uint256" },
{ "name": "kind", "type": "string" },
{ "name": "partiallyFillable", "type": "bool" },
{ "name": "sellTokenBalance", "type": "string" },
{ "name": "buyTokenBalance", "type": "string" }
]
},
"primaryType": "Order",
"domain": {
"name": "Gnosis Protocol",
"version": "v2",
"chainId": 1,
"verifyingContract": "'$COW_SETTLMENT_CONTRACT'"
},
"message": '$eip712_message'
}'

# Compact json and escape quotes
eip712_typed_struct=$(jq -r -c <<< "${eip712_typed_struct}")
eip712_typed_struct=${eip712_typed_struct//\"/\\\"}

# Sign quote_response with private key
signature=$(cast wallet sign --private-key $PRIVATE_KEY --data \""$eip712_typed_struct"\")
echo "Intent signature:" $signature

app_data=${APPDATA//\"/\\\"} # escape quotes for json field

# Update EIP712 message with additional fields required for order submit
order_proposal=$(jq -r -c --args '
.from="'$receiver'" |
.appData|="'$app_data'" |
.appDataHash="'$app_data_hash'" |
.signature="'$signature'"' <<< "${eip712_message}")

echo "Submit an order"
orderUid=$( curl --retry 5 --fail-with-body -s --show-error -X 'POST' \
"http://$HOST/api/v1/orders" \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d "${order_proposal}")
orderUid=${orderUid:1:-1} # remove quotes
echo "Order UID: $orderUid"

for i in $(seq 1 24);
do
orderStatus=$( curl --retry 5 --fail-with-body -s --show-error -X 'GET' \
"http://$HOST/api/v1/orders/$orderUid/status" \
-H 'accept: application/json' | jq -r '.type')
echo -e -n "Order status: $orderStatus \r"
if [ "$orderStatus" = "traded" ]; then
echo -e "\nSuccess"
exit 0
fi
sleep 5
done

echo -e "\nTimeout"
exit 1
Loading