forked from cerc-io/ipld-eth-server
Compare commits
69
Commits
v3.0.0
...
v4.0.4-alpha
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aaf571b04c | ||
|
|
4121863a4c | ||
|
|
fa4428b167 | ||
|
|
221114cf56 | ||
|
|
8e652a634f | ||
|
|
1fc53ccab1 | ||
|
|
31e9a7dc5e | ||
|
|
c19cc5c44d | ||
|
|
6bd563e3d5 | ||
|
|
b3d9e01d67 | ||
|
|
0c44882cb2 | ||
|
|
80413211c2 | ||
|
|
7f15befdee | ||
|
|
217cfc63ec | ||
|
|
9550d60467 | ||
|
|
da1c8b2332 | ||
|
|
fe7329c284 | ||
|
|
f144d932cd | ||
|
|
491939b35f | ||
|
|
248d9eb7a2 | ||
|
|
a3d2e71ca6 | ||
|
|
be1d4281e8 | ||
|
|
e2b83a5737 | ||
|
|
613dd6acf4 | ||
|
|
8966d1b6c2 | ||
|
|
c556845d1a | ||
|
|
cf8c08f01e | ||
|
|
5c6fb45d36 | ||
|
|
222fa6d6ed | ||
|
|
6c82eafef1 | ||
|
|
89b9a05234 | ||
|
|
27d9413544 | ||
|
|
4817674c5c | ||
|
|
8556332ff8 | ||
|
|
81884d4826 | ||
|
|
389ba2e360 | ||
|
|
c25d220f71 | ||
|
|
8ea4d1e40d | ||
|
|
ace12fbc35 | ||
|
|
8b8f644b2a | ||
|
|
8bfcce95ca | ||
|
|
0b12c3c329 | ||
|
|
037131528c | ||
|
|
be34f0e8fd | ||
|
|
04096fab0c | ||
|
|
dc14656bbc | ||
|
|
9676690a2d | ||
|
|
025b1c7c9e | ||
|
|
36e590c092 | ||
|
|
384d939dc2 | ||
|
|
24a45a3f00 | ||
|
|
867323a1ab | ||
|
|
da30a957a7 | ||
|
|
705835512e | ||
|
|
2a0e9f8dfd | ||
|
|
c8bdaefe97 | ||
|
|
a141d154b7 | ||
|
|
76986d9497 | ||
|
|
233fa29740 | ||
|
|
4883590d85 | ||
|
|
181e3745f1 | ||
|
|
4b697b2a98 | ||
|
|
77812f2673 | ||
|
|
849b17f4bd | ||
|
|
56c85709c1 | ||
|
|
2be2a06575 | ||
|
|
39fb9207b2 | ||
|
|
3914889d53 | ||
|
|
1a6ff273ba |
@@ -1,25 +0,0 @@
|
|||||||
name: Docker Compose Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Run docker build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Get the version
|
|
||||||
id: vars
|
|
||||||
run: echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7})
|
|
||||||
- name: Run docker build
|
|
||||||
run: make docker-build
|
|
||||||
- name: Tag docker image
|
|
||||||
run: docker tag vulcanize/ipld-eth-server docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
|
||||||
- name: Docker Login
|
|
||||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
|
||||||
- name: Docker Push
|
|
||||||
run: docker push docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
|
||||||
|
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
name: Test, Build, and/or Publish
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pre_job:
|
||||||
|
# continue-on-error: true # Uncomment once integration is finished
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Map a step output to a job output
|
||||||
|
outputs:
|
||||||
|
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||||
|
steps:
|
||||||
|
- id: skip_check
|
||||||
|
uses: fkirc/skip-duplicate-actions@v4
|
||||||
|
with:
|
||||||
|
# All of these options are optional, so you can remove them if you are happy with the defaults
|
||||||
|
concurrent_skipping: "never"
|
||||||
|
skip_after_successful_duplicate: "true"
|
||||||
|
do_not_skip: '["workflow_dispatch", "schedule"]'
|
||||||
|
run-tests:
|
||||||
|
uses: ./.github/workflows/tests.yaml
|
||||||
|
if: ${{ needs.pre_job.outputs.should_skip != 'true' }}
|
||||||
|
needs: pre_job
|
||||||
|
secrets:
|
||||||
|
BUILD_HOSTNAME: ${{ secrets.BUILD_HOSTNAME }}
|
||||||
|
BUILD_USERNAME: ${{ secrets.BUILD_USERNAME }}
|
||||||
|
BUILD_KEY: ${{ secrets.BUILD_KEY }}
|
||||||
|
build:
|
||||||
|
name: Run docker build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: run-tests
|
||||||
|
if: |
|
||||||
|
always() &&
|
||||||
|
(needs.run-tests.result == 'success' || needs.run-tests.result == 'skipped') &&
|
||||||
|
github.event_name == 'release'
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Get the version
|
||||||
|
id: vars
|
||||||
|
run: echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7})
|
||||||
|
- name: Run docker build
|
||||||
|
run: make docker-build
|
||||||
|
- name: Tag docker image
|
||||||
|
run: docker tag vulcanize/ipld-eth-server docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
||||||
|
- name: Docker Login
|
||||||
|
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
||||||
|
- name: Docker Push
|
||||||
|
run: docker push docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
||||||
|
|
||||||
|
push_to_registries:
|
||||||
|
name: Push Docker image to Docker Hub
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
always() &&
|
||||||
|
(needs.build.result == 'success') &&
|
||||||
|
github.event_name == 'release'
|
||||||
|
needs: build
|
||||||
|
steps:
|
||||||
|
- name: Get the version
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7})
|
||||||
|
echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})
|
||||||
|
- name: Docker Login to Github Registry
|
||||||
|
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
||||||
|
- name: Docker Pull
|
||||||
|
run: docker pull docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
||||||
|
- name: Docker Login to Docker Registry
|
||||||
|
run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin
|
||||||
|
- name: Tag docker image
|
||||||
|
run: docker tag docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}} vulcanize/ipld-eth-server:${{steps.vars.outputs.tag}}
|
||||||
|
- name: Docker Push to Docker Hub
|
||||||
|
run: docker push vulcanize/ipld-eth-server:${{steps.vars.outputs.tag}}
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
name: Docker Build
|
|
||||||
|
|
||||||
on: [pull_request]
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Run docker build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Run docker build
|
|
||||||
run: make docker-build
|
|
||||||
test:
|
|
||||||
name: Run unit tests
|
|
||||||
env:
|
|
||||||
GOPATH: /tmp/go
|
|
||||||
# To run the unit tests you need to add secrets to your repository.
|
|
||||||
BUILD_HOSTNAME: ${{ secrets.BUILD_HOSTNAME }}
|
|
||||||
BUILD_USERNAME: ${{ secrets.BUILD_USERNAME }}
|
|
||||||
BUILD_KEY: ${{ secrets.BUILD_KEY }}
|
|
||||||
#strategy:
|
|
||||||
# matrix:
|
|
||||||
# go-version: [1.16.x, 1.17.x]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Passed experience with GHA has taught me to store variables in files instead of passing them as variables.
|
|
||||||
- name: Output variables to files
|
|
||||||
run: |
|
|
||||||
echo $GITHUB_REPOSITORY > /tmp/git_repository
|
|
||||||
echo $GITHUB_HEAD_REF > /tmp/git_head_ref
|
|
||||||
echo "-----BEGIN OPENSSH PRIVATE KEY-----" >> /tmp/key
|
|
||||||
echo ${{ env.BUILD_KEY }} >> /tmp/key
|
|
||||||
echo "-----END OPENSSH PRIVATE KEY-----" >> /tmp/key
|
|
||||||
chmod 400 /tmp/key
|
|
||||||
cat /tmp/git_repository
|
|
||||||
cat /tmp/git_head_ref
|
|
||||||
|
|
||||||
- name: Raw SCP
|
|
||||||
run: |
|
|
||||||
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key /tmp/git_repository ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/git_repository
|
|
||||||
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key /tmp/git_head_ref ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/git_head_ref
|
|
||||||
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key .github/workflows/run_unit_test.sh ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/run_unit_test.sh
|
|
||||||
|
|
||||||
- name: Trigger Unit Test
|
|
||||||
run: |
|
|
||||||
ssh -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }} chmod +x /tmp/run_unit_test.sh /tmp/run_unit_test.sh
|
|
||||||
ssh -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }} /tmp/run_unit_test.sh
|
|
||||||
|
|
||||||
- name: Get the logs and cat them
|
|
||||||
run: |
|
|
||||||
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/test.log .
|
|
||||||
cat ./test.log
|
|
||||||
|
|
||||||
- name: Check Error Code
|
|
||||||
run: |
|
|
||||||
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/return_test.txt .
|
|
||||||
[ $(cat ./return_test.txt) -eq 0 ]
|
|
||||||
|
|
||||||
integrationtest:
|
|
||||||
name: Run integration tests
|
|
||||||
env:
|
|
||||||
GOPATH: /tmp/go
|
|
||||||
DB_WRITE: true
|
|
||||||
ETH_FORWARD_ETH_CALLS: false
|
|
||||||
ETH_PROXY_ON_ERROR: false
|
|
||||||
ETH_HTTP_PATH: ""
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.16.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Create GOPATH
|
|
||||||
run: mkdir -p /tmp/go
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Run database
|
|
||||||
run: docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d ipld-eth-db dapptools contract eth-server
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8081)" != "200" ]; do echo "waiting for ipld-eth-server..." && sleep 5; done && \
|
|
||||||
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8545)" != "200" ]; do echo "waiting for geth-statediff..." && sleep 5; done && \
|
|
||||||
make integrationtest
|
|
||||||
|
|
||||||
integrationtest_forwardethcalls:
|
|
||||||
name: Run integration tests for direct proxy fall-through of eth_calls
|
|
||||||
env:
|
|
||||||
GOPATH: /tmp/go
|
|
||||||
DB_WRITE: false
|
|
||||||
ETH_FORWARD_ETH_CALLS: true
|
|
||||||
ETH_PROXY_ON_ERROR: false
|
|
||||||
ETH_HTTP_PATH: "dapptools:8545"
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.16.x]
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Create GOPATH
|
|
||||||
run: mkdir -p /tmp/go
|
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: ${{ matrix.go-version }}
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Run database
|
|
||||||
run: docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d ipld-eth-db dapptools contract eth-server
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8081)" != "200" ]; do echo "waiting for ipld-eth-server..." && sleep 5; done && \
|
|
||||||
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8545)" != "200" ]; do echo "waiting for geth-statediff..." && sleep 5; done && \
|
|
||||||
make integrationtest
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
name: Publish Docker image
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
jobs:
|
|
||||||
push_to_registries:
|
|
||||||
name: Push Docker image to Docker Hub
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Get the version
|
|
||||||
id: vars
|
|
||||||
run: |
|
|
||||||
echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7})
|
|
||||||
echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/})
|
|
||||||
- name: Docker Login to Github Registry
|
|
||||||
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin
|
|
||||||
- name: Docker Pull
|
|
||||||
run: docker pull docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}}
|
|
||||||
- name: Docker Login to Docker Registry
|
|
||||||
run: echo ${{ secrets.VULCANIZEJENKINS_PAT }} | docker login -u vulcanizejenkins --password-stdin
|
|
||||||
- name: Tag docker image
|
|
||||||
run: docker tag docker.pkg.github.com/vulcanize/ipld-eth-server/ipld-eth-server:${{steps.vars.outputs.sha}} vulcanize/ipld-eth-server:${{steps.vars.outputs.tag}}
|
|
||||||
- name: Docker Push to Docker Hub
|
|
||||||
run: docker push vulcanize/ipld-eth-server:${{steps.vars.outputs.tag}}
|
|
||||||
|
|
||||||
@@ -8,22 +8,30 @@ temp_dir=$(mktemp -d)
|
|||||||
cd $temp_dir
|
cd $temp_dir
|
||||||
git clone -b $(cat /tmp/git_head_ref) "https://github.com/$(cat /tmp/git_repository).git"
|
git clone -b $(cat /tmp/git_head_ref) "https://github.com/$(cat /tmp/git_repository).git"
|
||||||
cd ipld-eth-server
|
cd ipld-eth-server
|
||||||
|
mkdir -p out
|
||||||
|
|
||||||
## Remove the branch and github related info. This way future runs wont be confused.
|
## Remove the branch and github related info. This way future runs wont be confused.
|
||||||
rm -f /tmp/git_head_ref /tmp/git_repository
|
rm -f /tmp/git_head_ref /tmp/git_repository
|
||||||
|
|
||||||
# Spin up DB
|
# Remove existing docker-tsdb directory
|
||||||
docker-compose up -d ipld-eth-db
|
rm -rf out/docker-tsdb/
|
||||||
trap "docker-compose down --remove-orphans; cd $start_dir ; rm -r $temp_dir" SIGINT SIGTERM ERR
|
|
||||||
sleep 10
|
# Copy over files to setup TimescaleDB
|
||||||
|
ID=$(docker create vulcanize/ipld-eth-db:v4.1.1-alpha)
|
||||||
|
docker cp $ID:/app/docker-tsdb out/docker-tsdb/
|
||||||
|
docker rm -v $ID
|
||||||
|
|
||||||
|
# Spin up TimescaleDB
|
||||||
|
docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml up ipld-eth-db
|
||||||
|
trap "docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml down --remove-orphans --volumes; cd $start_dir ; rm -r $temp_dir" SIGINT SIGTERM ERR
|
||||||
|
sleep 45
|
||||||
|
|
||||||
# Remove old logs so there's no confusion, then run test
|
# Remove old logs so there's no confusion, then run test
|
||||||
rm -f /tmp/test.log /tmp/return_test.txt
|
rm -f /tmp/test.log /tmp/return_test.txt
|
||||||
PGPASSWORD=password DATABASE_USER=vdbm DATABASE_PORT=8077 DATABASE_PASSWORD=password DATABASE_HOSTNAME=127.0.0.1 DATABASE_NAME=vulcanize_testing make test > /tmp/test.log
|
PGPASSWORD=password DATABASE_USER=vdbm DATABASE_PORT=8066 DATABASE_PASSWORD=password DATABASE_HOSTNAME=127.0.0.1 DATABASE_NAME=vulcanize_testing_v4 make test > /tmp/test.log
|
||||||
echo $? > /tmp/return_test.txt
|
echo $? > /tmp/return_test.txt
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
docker-compose down -v --remove-orphans
|
docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml down --remove-orphans --volumes
|
||||||
cd $start_dir
|
cd $start_dir
|
||||||
rm -fr $temp_dir
|
rm -fr $temp_dir
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
name: Test the stack.
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
secrets:
|
||||||
|
BUILD_HOSTNAME:
|
||||||
|
required: true
|
||||||
|
BUILD_USERNAME:
|
||||||
|
required: true
|
||||||
|
BUILD_KEY:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Run docker build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Run docker build
|
||||||
|
run: make docker-build
|
||||||
|
test:
|
||||||
|
name: Run unit tests
|
||||||
|
env:
|
||||||
|
GOPATH: /tmp/go
|
||||||
|
# To run the unit tests you need to add secrets to your repository.
|
||||||
|
BUILD_HOSTNAME: ${{ secrets.BUILD_HOSTNAME }}
|
||||||
|
BUILD_USERNAME: ${{ secrets.BUILD_USERNAME }}
|
||||||
|
BUILD_KEY: ${{ secrets.BUILD_KEY }}
|
||||||
|
#strategy:
|
||||||
|
# matrix:
|
||||||
|
# go-version: [1.16.x, 1.17.x]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Passed experience with GHA has taught me to store variables in files instead of passing them as variables.
|
||||||
|
- name: Output variables to files
|
||||||
|
run: |
|
||||||
|
echo $GITHUB_REPOSITORY > /tmp/git_repository
|
||||||
|
[ -z "$GITHUB_HEAD_REF" ] && echo $GITHUB_REF_NAME > /tmp/git_head_ref || echo $GITHUB_HEAD_REF > /tmp/git_head_ref
|
||||||
|
echo "-----BEGIN OPENSSH PRIVATE KEY-----" >> /tmp/key
|
||||||
|
echo ${{ env.BUILD_KEY }} >> /tmp/key
|
||||||
|
echo "-----END OPENSSH PRIVATE KEY-----" >> /tmp/key
|
||||||
|
chmod 400 /tmp/key
|
||||||
|
cat /tmp/git_repository
|
||||||
|
cat /tmp/git_head_ref
|
||||||
|
|
||||||
|
- name: Raw SCP
|
||||||
|
run: |
|
||||||
|
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key /tmp/git_repository ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/git_repository
|
||||||
|
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key /tmp/git_head_ref ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/git_head_ref
|
||||||
|
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key .github/workflows/run_unit_test.sh ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/run_unit_test.sh
|
||||||
|
|
||||||
|
- name: Trigger Unit Test
|
||||||
|
run: |
|
||||||
|
ssh -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }} go install github.com/onsi/ginkgo/ginkgo@latest
|
||||||
|
ssh -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }} /tmp/run_unit_test.sh
|
||||||
|
|
||||||
|
- name: Get the logs and cat them
|
||||||
|
run: |
|
||||||
|
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/test.log .
|
||||||
|
cat ./test.log
|
||||||
|
|
||||||
|
- name: Check Error Code
|
||||||
|
run: |
|
||||||
|
scp -o 'StrictHostKeyChecking no' -o UserKnownHostsFile=/dev/null -q -i /tmp/key ${{ env.BUILD_USERNAME }}@${{ env.BUILD_HOSTNAME }}:/tmp/return_test.txt .
|
||||||
|
[ $(cat ./return_test.txt) -eq 0 ]
|
||||||
|
|
||||||
|
integrationtest:
|
||||||
|
name: Run integration tests
|
||||||
|
env:
|
||||||
|
STACK_ORCHESTRATOR_REF: 418957a1f745c921b21286c13bb033f922a91ae9
|
||||||
|
GO_ETHEREUM_REF: "v1.10.18-statediff-4.0.2-alpha"
|
||||||
|
IPLD_ETH_DB_REF: 91d30b9ea1acecd0a7f4307390a98bf3e289b8d7
|
||||||
|
GOPATH: /tmp/go
|
||||||
|
DB_WRITE: true
|
||||||
|
ETH_FORWARD_ETH_CALLS: false
|
||||||
|
ETH_PROXY_ON_ERROR: false
|
||||||
|
ETH_HTTP_PATH: "go-ethereum:8545"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Create GOPATH
|
||||||
|
run: mkdir -p /tmp/go
|
||||||
|
- uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: ">=1.18.0"
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: "./ipld-eth-server"
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.STACK_ORCHESTRATOR_REF }}
|
||||||
|
path: "./stack-orchestrator/"
|
||||||
|
repository: vulcanize/stack-orchestrator
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.GO_ETHEREUM_REF }}
|
||||||
|
repository: vulcanize/go-ethereum
|
||||||
|
path: "./go-ethereum/"
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.IPLD_ETH_DB_REF }}
|
||||||
|
repository: vulcanize/ipld-eth-db
|
||||||
|
path: "./ipld-eth-db/"
|
||||||
|
- name: Create config file
|
||||||
|
run: |
|
||||||
|
echo vulcanize_go_ethereum=$GITHUB_WORKSPACE/go-ethereum/ > ./config.sh
|
||||||
|
echo vulcanize_ipld_eth_db=$GITHUB_WORKSPACE/ipld-eth-db/ >> ./config.sh
|
||||||
|
echo vulcanize_ipld_eth_server=$GITHUB_WORKSPACE/ipld-eth-server/ >> ./config.sh
|
||||||
|
echo vulcanize_test_contract=$GITHUB_WORKSPACE/ipld-eth-server/test/contract >> ./config.sh
|
||||||
|
echo db_write=$DB_WRITE >> ./config.sh
|
||||||
|
echo eth_forward_eth_calls=$ETH_FORWARD_ETH_CALLS >> ./config.sh
|
||||||
|
echo eth_proxy_on_error=$ETH_PROXY_ON_ERROR >> ./config.sh
|
||||||
|
echo eth_http_path=$ETH_HTTP_PATH >> ./config.sh
|
||||||
|
echo ipld_eth_server_db_dependency=access-node >> ./config.sh
|
||||||
|
echo go_ethereum_db_dependency=access-node >> ./config.sh
|
||||||
|
echo connecting_db_name=vulcanize_testing_v4 >> ./config.sh
|
||||||
|
echo watched_address_gap_filler_enabled=false >> ./config.sh
|
||||||
|
echo watched_address_gap_filler_interval=5 >> ./config.sh
|
||||||
|
cat ./config.sh
|
||||||
|
- name: Build geth
|
||||||
|
run: |
|
||||||
|
cd $GITHUB_WORKSPACE/stack-orchestrator/helper-scripts
|
||||||
|
./compile-geth.sh \
|
||||||
|
-p "$GITHUB_WORKSPACE/config.sh" \
|
||||||
|
-e docker
|
||||||
|
- name: Run docker compose
|
||||||
|
run: |
|
||||||
|
docker-compose \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-migration.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-ipld-eth-server.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-contract.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/latest/docker-compose-timescale-db.yml" \
|
||||||
|
--env-file "$GITHUB_WORKSPACE/config.sh" \
|
||||||
|
up -d --build
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd $GITHUB_WORKSPACE/ipld-eth-server
|
||||||
|
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8081)" != "200" ]; do echo "waiting for ipld-eth-server..." && sleep 5; done && \
|
||||||
|
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8545)" != "200" ]; do echo "waiting for geth-statediff..." && sleep 5; done && \
|
||||||
|
make integrationtest
|
||||||
|
|
||||||
|
integrationtest_forwardethcalls:
|
||||||
|
name: Run integration tests for direct proxy fall-through of eth_calls
|
||||||
|
env:
|
||||||
|
STACK_ORCHESTRATOR_REF: 418957a1f745c921b21286c13bb033f922a91ae9
|
||||||
|
GO_ETHEREUM_REF: "v1.10.18-statediff-4.0.2-alpha"
|
||||||
|
IPLD_ETH_DB_REF: 91d30b9ea1acecd0a7f4307390a98bf3e289b8d7
|
||||||
|
GOPATH: /tmp/go
|
||||||
|
DB_WRITE: false
|
||||||
|
ETH_FORWARD_ETH_CALLS: true
|
||||||
|
ETH_PROXY_ON_ERROR: false
|
||||||
|
ETH_HTTP_PATH: "go-ethereum:8545"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Create GOPATH
|
||||||
|
run: mkdir -p /tmp/go
|
||||||
|
- uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: ">=1.18.0"
|
||||||
|
check-latest: true
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: "./ipld-eth-server"
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.STACK_ORCHESTRATOR_REF }}
|
||||||
|
path: "./stack-orchestrator/"
|
||||||
|
repository: vulcanize/stack-orchestrator
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.GO_ETHEREUM_REF }}
|
||||||
|
repository: vulcanize/go-ethereum
|
||||||
|
path: "./go-ethereum/"
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{ env.IPLD_ETH_DB_REF }}
|
||||||
|
repository: vulcanize/ipld-eth-db
|
||||||
|
path: "./ipld-eth-db/"
|
||||||
|
- name: Create config file
|
||||||
|
run: |
|
||||||
|
echo vulcanize_go_ethereum=$GITHUB_WORKSPACE/go-ethereum/ > ./config.sh
|
||||||
|
echo vulcanize_ipld_eth_db=$GITHUB_WORKSPACE/ipld-eth-db/ >> ./config.sh
|
||||||
|
echo vulcanize_ipld_eth_server=$GITHUB_WORKSPACE/ipld-eth-server/ >> ./config.sh
|
||||||
|
echo vulcanize_test_contract=$GITHUB_WORKSPACE/ipld-eth-server/test/contract >>./config.sh
|
||||||
|
echo db_write=$DB_WRITE >> ./config.sh
|
||||||
|
echo eth_forward_eth_calls=$ETH_FORWARD_ETH_CALLS >> ./config.sh
|
||||||
|
echo eth_proxy_on_error=$ETH_PROXY_ON_ERROR >> ./config.sh
|
||||||
|
echo eth_http_path=$ETH_HTTP_PATH >> ./config.sh
|
||||||
|
echo ipld_eth_server_db_dependency=access-node >> ./config.sh
|
||||||
|
echo go_ethereum_db_dependency=access-node >> ./config.sh
|
||||||
|
echo connecting_db_name=vulcanize_testing_v4 >> ./config.sh
|
||||||
|
echo watched_address_gap_filler_enabled=false >> ./config.sh
|
||||||
|
echo watched_address_gap_filler_interval=5 >> ./config.sh
|
||||||
|
cat ./config.sh
|
||||||
|
- name: Build geth
|
||||||
|
run: |
|
||||||
|
cd $GITHUB_WORKSPACE/stack-orchestrator/helper-scripts
|
||||||
|
./compile-geth.sh \
|
||||||
|
-p "$GITHUB_WORKSPACE/config.sh" \
|
||||||
|
-e docker
|
||||||
|
- name: Run docker compose
|
||||||
|
run: |
|
||||||
|
docker-compose \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-migration.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-ipld-eth-server.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-contract.yml" \
|
||||||
|
-f "$GITHUB_WORKSPACE/stack-orchestrator/docker/latest/docker-compose-timescale-db.yml" \
|
||||||
|
--env-file "$GITHUB_WORKSPACE/config.sh" \
|
||||||
|
up -d --build
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd $GITHUB_WORKSPACE/ipld-eth-server
|
||||||
|
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8081)" != "200" ]; do echo "waiting for ipld-eth-server..." && sleep 5; done && \
|
||||||
|
while [ "$(curl -s -o /dev/null -w ''%{http_code}'' localhost:8545)" != "200" ]; do echo "waiting for geth-statediff..." && sleep 5; done && \
|
||||||
|
make integrationtest
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.16-alpine as builder
|
FROM golang:1.18-alpine as builder
|
||||||
|
|
||||||
RUN apk --update --no-cache add make git g++ linux-headers
|
RUN apk --update --no-cache add make git g++ linux-headers
|
||||||
# DEBUG
|
# DEBUG
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ BASE = $(GOPATH)/src/$(PACKAGE)
|
|||||||
PKGS = go list ./... | grep -v "^vendor/"
|
PKGS = go list ./... | grep -v "^vendor/"
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
## Testing library
|
|
||||||
GINKGO = $(BIN)/ginkgo
|
|
||||||
$(BIN)/ginkgo:
|
|
||||||
go get -u github.com/onsi/ginkgo/ginkgo
|
|
||||||
|
|
||||||
## Migration tool
|
## Migration tool
|
||||||
GOOSE = $(BIN)/goose
|
GOOSE = $(BIN)/goose
|
||||||
@@ -26,8 +22,9 @@ $(BIN)/gometalinter.v2:
|
|||||||
|
|
||||||
|
|
||||||
.PHONY: installtools
|
.PHONY: installtools
|
||||||
installtools: | $(LINT) $(GOOSE) $(GINKGO)
|
installtools: | $(LINT) $(GOOSE)
|
||||||
echo "Installing tools"
|
echo "Installing tools"
|
||||||
|
go mod download
|
||||||
|
|
||||||
.PHONY: metalint
|
.PHONY: metalint
|
||||||
metalint: | $(METALINT)
|
metalint: | $(METALINT)
|
||||||
@@ -54,30 +51,23 @@ TEST_CONNECT_STRING = postgresql://$(DATABASE_USER):$(DATABASE_PASSWORD)@$(DATAB
|
|||||||
TEST_CONNECT_STRING_LOCAL = postgresql://$(USER)@$(HOST_NAME):$(PORT)/$(TEST_DB)?sslmode=disable
|
TEST_CONNECT_STRING_LOCAL = postgresql://$(USER)@$(HOST_NAME):$(PORT)/$(TEST_DB)?sslmode=disable
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: | $(GINKGO) $(GOOSE)
|
test: | $(GOOSE)
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
$(GINKGO) -r --skipPackage=test
|
go run github.com/onsi/ginkgo/ginkgo -r --skipPackage=test
|
||||||
|
|
||||||
.PHONY: integrationtest
|
.PHONY: integrationtest
|
||||||
integrationtest: | $(GINKGO) $(GOOSE)
|
integrationtest: | $(GOOSE)
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
$(GINKGO) -r test/ -v
|
go run github.com/onsi/ginkgo/ginkgo -r test/ -v
|
||||||
|
|
||||||
.PHONY: test_local
|
.PHONY: test_local
|
||||||
test_local: | $(GINKGO) $(GOOSE)
|
test_local: | $(GOOSE)
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
./scripts/run_unit_test.sh
|
./scripts/run_unit_test.sh
|
||||||
|
|
||||||
.PHONY: integrationtest_local
|
|
||||||
integrationtest_local: | $(GINKGO) $(GOOSE)
|
|
||||||
go vet ./...
|
|
||||||
go fmt ./...
|
|
||||||
./scripts/run_integration_test.sh
|
|
||||||
./scripts/run_integration_test_forward_eth_calls.sh
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go fmt ./...
|
go fmt ./...
|
||||||
GO111MODULE=on go build
|
GO111MODULE=on go build
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ External dependency
|
|||||||
## Install
|
## Install
|
||||||
Start by downloading ipld-eth-server and moving into the repo:
|
Start by downloading ipld-eth-server and moving into the repo:
|
||||||
|
|
||||||
`GO111MODULE=off go get -d github.com/vulcanize/ipld-eth-server`
|
`GO111MODULE=off go get -d github.com/vulcanize/ipld-eth-server/v4`
|
||||||
|
|
||||||
`cd $GOPATH/src/github.com/vulcanize/ipld-eth-server`
|
`cd $GOPATH/src/github.com/vulcanize/ipld-eth-server/v4@v4.x.x`
|
||||||
|
|
||||||
Then, build the binary:
|
Then, build the binary:
|
||||||
|
|
||||||
@@ -148,8 +148,8 @@ TODO: Add the rest of the standard endpoints and unique endpoints (e.g. getSlice
|
|||||||
|
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
`make test` will run the unit tests
|
|
||||||
`make test` setups a clean `vulcanize_testing` db
|
Follow steps in [test/README.md](./test/README.md)
|
||||||
|
|
||||||
## Monitoring
|
## Monitoring
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/prom"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/prom"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
+6
-6
@@ -32,11 +32,11 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"github.com/vulcanize/gap-filler/pkg/mux"
|
"github.com/vulcanize/gap-filler/pkg/mux"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/graphql"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/graphql"
|
||||||
srpc "github.com/vulcanize/ipld-eth-server/pkg/rpc"
|
srpc "github.com/vulcanize/ipld-eth-server/v4/pkg/rpc"
|
||||||
s "github.com/vulcanize/ipld-eth-server/pkg/serve"
|
s "github.com/vulcanize/ipld-eth-server/v4/pkg/serve"
|
||||||
v "github.com/vulcanize/ipld-eth-server/version"
|
v "github.com/vulcanize/ipld-eth-server/v4/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available")
|
var ErrNoRpcEndpoints = errors.New("no rpc endpoints is available")
|
||||||
@@ -133,7 +133,7 @@ func startServers(server s.Server, settings *s.Config) error {
|
|||||||
|
|
||||||
if settings.HTTPEnabled {
|
if settings.HTTPEnabled {
|
||||||
logWithCommand.Info("starting up HTTP server")
|
logWithCommand.Info("starting up HTTP server")
|
||||||
_, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"eth", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{})
|
_, err := srpc.StartHTTPEndpoint(settings.HTTPEndpoint, server.APIs(), []string{"vdb", "eth", "net"}, nil, []string{"*"}, rpc.HTTPTimeouts{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -27,9 +27,9 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/client"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/client"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
w "github.com/vulcanize/ipld-eth-server/pkg/serve"
|
w "github.com/vulcanize/ipld-eth-server/v4/pkg/serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
// subscribeCmd represents the subscribe command
|
// subscribeCmd represents the subscribe command
|
||||||
|
|||||||
+3
-3
@@ -22,10 +22,10 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
validator "github.com/vulcanize/eth-ipfs-state-validator/pkg"
|
validator "github.com/vulcanize/eth-ipfs-state-validator/v4/pkg"
|
||||||
ipfsethdb "github.com/vulcanize/ipfs-ethdb/postgres"
|
ipfsethdb "github.com/vulcanize/ipfs-ethdb/v4/postgres"
|
||||||
|
|
||||||
s "github.com/vulcanize/ipld-eth-server/pkg/serve"
|
s "github.com/vulcanize/ipld-eth-server/v4/pkg/serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
const GroupName = "statedb-validate"
|
const GroupName = "statedb-validate"
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
v "github.com/vulcanize/ipld-eth-server/version"
|
v "github.com/vulcanize/ipld-eth-server/v4/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// versionCmd represents the version command
|
// versionCmd represents the version command
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ version: '3.2'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
contract:
|
contract:
|
||||||
depends_on:
|
|
||||||
- dapptools
|
|
||||||
build:
|
build:
|
||||||
context: ./test/contract
|
context: ./test/contract
|
||||||
args:
|
args:
|
||||||
ETH_ADDR: "http://dapptools:8545"
|
ETH_ADDR: "http://go-ethereum:8545"
|
||||||
environment:
|
environment:
|
||||||
ETH_ADDR: "http://dapptools:8545"
|
ETH_ADDR: "http://go-ethereum:8545"
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3000:3000"
|
- "127.0.0.1:3000:3000"
|
||||||
|
|||||||
+9
-28
@@ -1,36 +1,17 @@
|
|||||||
version: '3.2'
|
version: '3.2'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
dapptools:
|
|
||||||
restart: unless-stopped
|
|
||||||
depends_on:
|
|
||||||
- ipld-eth-db
|
|
||||||
image: vulcanize/dapptools:v0.30.0-v1.10.16-statediff-3.0.2a
|
|
||||||
environment:
|
|
||||||
DB_USER: vdbm
|
|
||||||
DB_NAME: vulcanize_testing
|
|
||||||
DB_HOST: ipld-eth-db
|
|
||||||
DB_PORT: 5432
|
|
||||||
DB_PASSWORD: password
|
|
||||||
DB_WRITE: $DB_WRITE
|
|
||||||
DB_TYPE: postgres
|
|
||||||
DB_DRIVER: sqlx
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:8545:8545"
|
|
||||||
- "127.0.0.1:8546:8546"
|
|
||||||
|
|
||||||
ipld-eth-db:
|
ipld-eth-db:
|
||||||
restart: always
|
restart: on-failure
|
||||||
image: vulcanize/ipld-eth-db:v3.0.7
|
depends_on:
|
||||||
|
- access-node
|
||||||
|
image: vulcanize/ipld-eth-db:v4.1.1-alpha
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: "vdbm"
|
DATABASE_USER: "vdbm"
|
||||||
POSTGRES_DB: "vulcanize_testing"
|
DATABASE_NAME: "vulcanize_testing_v4"
|
||||||
POSTGRES_PASSWORD: "password"
|
DATABASE_PASSWORD: "password"
|
||||||
volumes:
|
DATABASE_HOSTNAME: "access-node"
|
||||||
- vdb_db_eth_server:/var/lib/postgresql/data
|
DATABASE_PORT: 5432
|
||||||
ports:
|
|
||||||
- "127.0.0.1:8077:5432"
|
|
||||||
command: ["postgres", "-c", "log_statement=all"]
|
|
||||||
|
|
||||||
eth-server:
|
eth-server:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
+11
-11
@@ -12,7 +12,7 @@ We can expose a number of different APIs for remote access to ipld-eth-server da
|
|||||||
ipld-eth-server stores all processed data in Postgres using PG-IPFS, this includes all of the IPLD objects.
|
ipld-eth-server stores all processed data in Postgres using PG-IPFS, this includes all of the IPLD objects.
|
||||||
[Postgraphile](https://www.graphile.org/postgraphile/) can be used to expose GraphQL endpoints for the Postgres tables.
|
[Postgraphile](https://www.graphile.org/postgraphile/) can be used to expose GraphQL endpoints for the Postgres tables.
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
|
|
||||||
`postgraphile --plugins @graphile/pg-pubsub --subscriptions --simple-subscriptions -c postgres://localhost:5432/vulcanize_public?sslmode=disable -s public,btc,eth -a -j`
|
`postgraphile --plugins @graphile/pg-pubsub --subscriptions --simple-subscriptions -c postgres://localhost:5432/vulcanize_public?sslmode=disable -s public,btc,eth -a -j`
|
||||||
|
|
||||||
@@ -33,16 +33,16 @@ by ipld-eth-server to filter and return a requested subset of chain data to the
|
|||||||
An example of how to subscribe to a real-time Ethereum data feed from ipld-eth-server using the `Stream` RPC method is provided below
|
An example of how to subscribe to a real-time Ethereum data feed from ipld-eth-server using the `Stream` RPC method is provided below
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/client"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/client"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/watch"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
config, _ := eth.NewEthSubscriptionConfig()
|
config, _ := eth.NewEthSubscriptionConfig()
|
||||||
@@ -153,16 +153,16 @@ the addresses in the `addresses` fields are pre-hashed ETH addresses.
|
|||||||
An example of how to subscribe to a real-time Bitcoin data feed from ipld-eth-server using the `Stream` RPC method is provided below
|
An example of how to subscribe to a real-time Bitcoin data feed from ipld-eth-server using the `Stream` RPC method is provided below
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/btc"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/btc"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/client"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/client"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/watch"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
config, _ := btc.NewBtcSubscriptionConfig()
|
config, _ := btc.NewBtcSubscriptionConfig()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
graphqlEndpoint = "127.0.0.1:8083" # $SERVER_GRAPHQL_ENDPOINT
|
graphqlEndpoint = "127.0.0.1:8083" # $SERVER_GRAPHQL_ENDPOINT
|
||||||
|
|
||||||
[ethereum]
|
[ethereum]
|
||||||
|
chainConfig = "./chain.json" # ETH_CHAIN_CONFIG
|
||||||
chainID = "1" # $ETH_CHAIN_ID
|
chainID = "1" # $ETH_CHAIN_ID
|
||||||
defaultSender = "" # $ETH_DEFAULT_SENDER_ADDR
|
defaultSender = "" # $ETH_DEFAULT_SENDER_ADDR
|
||||||
rpcGasCap = "1000000000000" # $ETH_RPC_GAS_CAP
|
rpcGasCap = "1000000000000" # $ETH_RPC_GAS_CAP
|
||||||
|
|||||||
@@ -1,38 +1,292 @@
|
|||||||
module github.com/vulcanize/ipld-eth-server
|
module github.com/vulcanize/ipld-eth-server/v4
|
||||||
|
|
||||||
go 1.15
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/ethereum/go-ethereum v1.10.16
|
github.com/ethereum/go-ethereum v1.10.19
|
||||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
|
||||||
github.com/graph-gophers/graphql-go v1.3.0
|
github.com/graph-gophers/graphql-go v1.3.0
|
||||||
github.com/ipfs/go-block-format v0.0.3
|
github.com/ipfs/go-block-format v0.0.3
|
||||||
github.com/ipfs/go-cid v0.0.7
|
github.com/ipfs/go-cid v0.0.7
|
||||||
github.com/ipfs/go-ipfs-blockstore v1.0.1
|
github.com/ipfs/go-ipfs-blockstore v1.0.1
|
||||||
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
||||||
github.com/ipfs/go-ipld-format v0.2.0
|
github.com/jmoiron/sqlx v1.3.5
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
|
||||||
github.com/joho/godotenv v1.4.0
|
github.com/joho/godotenv v1.4.0
|
||||||
github.com/lib/pq v1.10.4
|
github.com/lib/pq v1.10.6
|
||||||
github.com/machinebox/graphql v0.2.2
|
github.com/machinebox/graphql v0.2.2
|
||||||
github.com/mailgun/groupcache/v2 v2.2.1
|
github.com/mailgun/groupcache/v2 v2.3.0
|
||||||
github.com/matryer/is v1.4.0 // indirect
|
github.com/multiformats/go-multihash v0.1.0
|
||||||
github.com/multiformats/go-multihash v0.0.15
|
|
||||||
github.com/onsi/ginkgo v1.16.5
|
github.com/onsi/ginkgo v1.16.5
|
||||||
github.com/onsi/gomega v1.13.0
|
github.com/onsi/gomega v1.19.0
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/shirou/gopsutil v3.21.5+incompatible // indirect
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/spf13/cobra v1.4.0
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/viper v1.11.0
|
||||||
github.com/spf13/viper v1.7.0
|
github.com/vulcanize/eth-ipfs-state-validator/v4 v4.0.3-alpha
|
||||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
github.com/vulcanize/gap-filler v0.4.0
|
||||||
github.com/vulcanize/eth-ipfs-state-validator v0.1.0
|
github.com/vulcanize/ipfs-ethdb/v4 v4.0.2-alpha
|
||||||
github.com/vulcanize/gap-filler v0.3.1
|
gorm.io/driver/postgres v1.3.7
|
||||||
github.com/vulcanize/ipfs-ethdb v0.0.6
|
gorm.io/gorm v1.23.5
|
||||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e // indirect
|
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
|
||||||
golang.org/x/tools v0.1.8 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/ethereum/go-ethereum v1.10.16 => github.com/vulcanize/go-ethereum v1.10.16-statediff-3.0.2
|
require (
|
||||||
|
bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect
|
||||||
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
||||||
|
github.com/Stebalien/go-bitfield v0.0.1 // indirect
|
||||||
|
github.com/VictoriaMetrics/fastcache v1.6.0 // indirect
|
||||||
|
github.com/benbjohnson/clock v1.1.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||||
|
github.com/btcsuite/btcd v0.22.1 // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
|
||||||
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
|
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||||
|
github.com/cheekybits/genny v1.0.0 // indirect
|
||||||
|
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect
|
||||||
|
github.com/cskr/pubsub v1.0.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
|
||||||
|
github.com/deckarep/golang-set v1.8.0 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||||
|
github.com/deepmap/oapi-codegen v1.8.2 // indirect
|
||||||
|
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||||
|
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect
|
||||||
|
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||||
|
github.com/flynn/noise v1.0.0 // indirect
|
||||||
|
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||||
|
github.com/friendsofgo/graphiql v0.2.2 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||||
|
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
|
||||||
|
github.com/georgysavva/scany v0.2.9 // indirect
|
||||||
|
github.com/go-ole/go-ole v1.2.1 // indirect
|
||||||
|
github.com/go-stack/stack v1.8.0 // indirect
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.3.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
github.com/graphql-go/graphql v0.7.9 // indirect
|
||||||
|
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect
|
||||||
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
|
github.com/hashicorp/go-bexpr v0.1.10 // indirect
|
||||||
|
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||||
|
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
|
||||||
|
github.com/holiman/uint256 v1.2.0 // indirect
|
||||||
|
github.com/huin/goupnp v1.0.3 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/influxdata/influxdb v1.8.3 // indirect
|
||||||
|
github.com/influxdata/influxdb-client-go/v2 v2.4.0 // indirect
|
||||||
|
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
|
||||||
|
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||||
|
github.com/ipfs/go-bitswap v0.4.0 // indirect
|
||||||
|
github.com/ipfs/go-blockservice v0.1.7 // indirect
|
||||||
|
github.com/ipfs/go-cidutil v0.0.2 // indirect
|
||||||
|
github.com/ipfs/go-datastore v0.4.6 // indirect
|
||||||
|
github.com/ipfs/go-ds-measure v0.1.0 // indirect
|
||||||
|
github.com/ipfs/go-fetcher v1.5.0 // indirect
|
||||||
|
github.com/ipfs/go-filestore v1.0.0 // indirect
|
||||||
|
github.com/ipfs/go-fs-lock v0.0.7 // indirect
|
||||||
|
github.com/ipfs/go-graphsync v0.8.0 // indirect
|
||||||
|
github.com/ipfs/go-ipfs v0.10.0 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-config v0.16.0 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-delay v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-exchange-interface v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-exchange-offline v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-files v0.0.8 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-keystore v0.0.2 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-pinner v0.1.2 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-pq v0.0.2 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-provider v0.6.1 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-routing v0.1.0 // indirect
|
||||||
|
github.com/ipfs/go-ipfs-util v0.0.2 // indirect
|
||||||
|
github.com/ipfs/go-ipld-cbor v0.0.5 // indirect
|
||||||
|
github.com/ipfs/go-ipld-format v0.2.0 // indirect
|
||||||
|
github.com/ipfs/go-ipld-legacy v0.1.0 // indirect
|
||||||
|
github.com/ipfs/go-ipns v0.1.2 // indirect
|
||||||
|
github.com/ipfs/go-log v1.0.5 // indirect
|
||||||
|
github.com/ipfs/go-log/v2 v2.3.0 // indirect
|
||||||
|
github.com/ipfs/go-merkledag v0.4.0 // indirect
|
||||||
|
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
|
||||||
|
github.com/ipfs/go-mfs v0.1.2 // indirect
|
||||||
|
github.com/ipfs/go-namesys v0.3.1 // indirect
|
||||||
|
github.com/ipfs/go-path v0.1.2 // indirect
|
||||||
|
github.com/ipfs/go-peertaskqueue v0.4.0 // indirect
|
||||||
|
github.com/ipfs/go-unixfs v0.2.5 // indirect
|
||||||
|
github.com/ipfs/go-unixfsnode v1.1.3 // indirect
|
||||||
|
github.com/ipfs/go-verifcid v0.0.1 // indirect
|
||||||
|
github.com/ipfs/interface-go-ipfs-core v0.5.1 // indirect
|
||||||
|
github.com/ipld/go-codec-dagpb v1.3.0 // indirect
|
||||||
|
github.com/ipld/go-ipld-prime v0.12.2 // indirect
|
||||||
|
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||||
|
github.com/jackc/pgconn v1.12.1 // indirect
|
||||||
|
github.com/jackc/pgio v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||||
|
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
|
||||||
|
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||||
|
github.com/jackc/pgtype v1.11.0 // indirect
|
||||||
|
github.com/jackc/pgx/v4 v4.16.1 // indirect
|
||||||
|
github.com/jackc/puddle v1.2.1 // indirect
|
||||||
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
|
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
|
||||||
|
github.com/jbenet/goprocess v0.1.4 // indirect
|
||||||
|
github.com/jinzhu/copier v0.2.4 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.4 // indirect
|
||||||
|
github.com/klauspost/compress v1.11.7 // indirect
|
||||||
|
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||||
|
github.com/koron/go-ssdp v0.0.2 // indirect
|
||||||
|
github.com/libp2p/go-addr-util v0.1.0 // indirect
|
||||||
|
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
|
||||||
|
github.com/libp2p/go-cidranger v1.1.0 // indirect
|
||||||
|
github.com/libp2p/go-conn-security-multistream v0.2.1 // indirect
|
||||||
|
github.com/libp2p/go-doh-resolver v0.3.1 // indirect
|
||||||
|
github.com/libp2p/go-eventbus v0.2.1 // indirect
|
||||||
|
github.com/libp2p/go-flow-metrics v0.0.3 // indirect
|
||||||
|
github.com/libp2p/go-libp2p v0.15.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-autonat v0.4.2 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-blankhost v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-circuit v0.4.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-connmgr v0.2.4 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-core v0.9.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-discovery v0.5.1 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-kad-dht v0.13.1 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-kbucket v0.4.7 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-loggables v0.1.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-mplex v0.4.1 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-nat v0.0.6 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-noise v0.2.2 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-peerstore v0.2.8 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-pubsub v0.5.4 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-pubsub-router v0.4.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-quic-transport v0.12.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-record v0.1.3 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-routing-helpers v0.2.3 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-swarm v0.5.3 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-tls v0.2.0 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-transport-upgrader v0.4.6 // indirect
|
||||||
|
github.com/libp2p/go-libp2p-xor v0.0.0-20210714161855-5c005aca55db // indirect
|
||||||
|
github.com/libp2p/go-libp2p-yamux v0.5.4 // indirect
|
||||||
|
github.com/libp2p/go-maddr-filter v0.1.0 // indirect
|
||||||
|
github.com/libp2p/go-mplex v0.3.0 // indirect
|
||||||
|
github.com/libp2p/go-msgio v0.0.6 // indirect
|
||||||
|
github.com/libp2p/go-nat v0.0.5 // indirect
|
||||||
|
github.com/libp2p/go-netroute v0.1.6 // indirect
|
||||||
|
github.com/libp2p/go-openssl v0.0.7 // indirect
|
||||||
|
github.com/libp2p/go-reuseport v0.0.2 // indirect
|
||||||
|
github.com/libp2p/go-reuseport-transport v0.0.5 // indirect
|
||||||
|
github.com/libp2p/go-sockaddr v0.1.1 // indirect
|
||||||
|
github.com/libp2p/go-stream-muxer-multistream v0.3.0 // indirect
|
||||||
|
github.com/libp2p/go-tcp-transport v0.2.8 // indirect
|
||||||
|
github.com/libp2p/go-ws-transport v0.5.0 // indirect
|
||||||
|
github.com/libp2p/go-yamux/v2 v2.2.0 // indirect
|
||||||
|
github.com/libp2p/zeroconf/v2 v2.0.0 // indirect
|
||||||
|
github.com/lucas-clemente/quic-go v0.26.0 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.6 // indirect
|
||||||
|
github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect
|
||||||
|
github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect
|
||||||
|
github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect
|
||||||
|
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
|
||||||
|
github.com/matryer/is v1.4.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||||
|
github.com/miekg/dns v1.1.43 // indirect
|
||||||
|
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
|
||||||
|
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
|
||||||
|
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||||
|
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||||
|
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
||||||
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
|
github.com/multiformats/go-base32 v0.0.3 // indirect
|
||||||
|
github.com/multiformats/go-base36 v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr v0.4.0 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
|
||||||
|
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
|
||||||
|
github.com/multiformats/go-multibase v0.0.3 // indirect
|
||||||
|
github.com/multiformats/go-multicodec v0.3.0 // indirect
|
||||||
|
github.com/multiformats/go-multistream v0.2.2 // indirect
|
||||||
|
github.com/multiformats/go-varint v0.0.6 // indirect
|
||||||
|
github.com/nxadm/tail v1.4.8 // indirect
|
||||||
|
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||||
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
|
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.0.0-beta.8 // indirect
|
||||||
|
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 // indirect
|
||||||
|
github.com/pganalyze/pg_query_go/v2 v2.1.0 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect
|
||||||
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
|
github.com/prometheus/common v0.30.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
|
github.com/prometheus/tsdb v0.7.1 // indirect
|
||||||
|
github.com/rjeczalik/notify v0.9.1 // indirect
|
||||||
|
github.com/rs/cors v1.7.0 // indirect
|
||||||
|
github.com/segmentio/fasthash v1.0.3 // indirect
|
||||||
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
||||||
|
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
github.com/spf13/afero v1.8.2 // indirect
|
||||||
|
github.com/spf13/cast v1.4.1 // indirect
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 // indirect
|
||||||
|
github.com/stretchr/objx v0.2.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.7.1 // indirect
|
||||||
|
github.com/subosito/gotenv v1.2.0 // indirect
|
||||||
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
|
||||||
|
github.com/thoas/go-funk v0.9.2 // indirect
|
||||||
|
github.com/tklauser/go-sysconf v0.3.5 // indirect
|
||||||
|
github.com/tklauser/numcpus v0.2.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef // indirect
|
||||||
|
github.com/valyala/fastjson v1.6.3 // indirect
|
||||||
|
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect
|
||||||
|
github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect
|
||||||
|
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
|
||||||
|
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
|
||||||
|
github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 // indirect
|
||||||
|
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect
|
||||||
|
github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect
|
||||||
|
go.opencensus.io v0.23.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v0.20.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v0.20.0 // indirect
|
||||||
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
|
go.uber.org/dig v1.10.0 // indirect
|
||||||
|
go.uber.org/fx v1.13.1 // indirect
|
||||||
|
go.uber.org/multierr v1.7.0 // indirect
|
||||||
|
go.uber.org/zap v1.19.0 // indirect
|
||||||
|
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||||
|
golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023 // indirect
|
||||||
|
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
|
||||||
|
google.golang.org/protobuf v1.28.0 // indirect
|
||||||
|
gopkg.in/ini.v1 v1.66.4 // indirect
|
||||||
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
lukechampine.com/blake3 v1.1.6 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
replace github.com/ethereum/go-ethereum v1.10.19 => github.com/vulcanize/go-ethereum v1.10.19-statediff-4.0.2-alpha
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/cmd"
|
"github.com/vulcanize/ipld-eth-server/v4/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ package client
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/serve"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is used to subscribe to the ipld-eth-server ipld data stream
|
// Client is used to subscribe to the ipld-eth-server ipld data stream
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/statediff"
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIName is the namespace for the watcher's eth api
|
// APIName is the namespace for the watcher's eth api
|
||||||
|
|||||||
+8
-7
@@ -36,9 +36,10 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
ethServerShared "github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
|
ethServerShared "github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -195,8 +196,8 @@ var _ = Describe("API", func() {
|
|||||||
tx interfaces.Batch
|
tx interfaces.Batch
|
||||||
)
|
)
|
||||||
|
|
||||||
db = eth.SetupTestDB()
|
db = shared.SetupDB()
|
||||||
indexAndPublisher := eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
indexAndPublisher := shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
backend, err := eth.NewEthBackend(db, ð.Config{
|
backend, err := eth.NewEthBackend(db, ð.Config{
|
||||||
ChainConfig: chainConfig,
|
ChainConfig: chainConfig,
|
||||||
@@ -241,7 +242,7 @@ var _ = Describe("API", func() {
|
|||||||
|
|
||||||
// setting chain config to for london block
|
// setting chain config to for london block
|
||||||
chainConfig.LondonBlock = big.NewInt(2)
|
chainConfig.LondonBlock = big.NewInt(2)
|
||||||
indexAndPublisher = eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
indexAndPublisher = shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
tx, err = indexAndPublisher.PushBlock(test_helpers.MockLondonBlock, test_helpers.MockLondonReceipts, test_helpers.MockLondonBlock.Difficulty())
|
tx, err = indexAndPublisher.PushBlock(test_helpers.MockLondonBlock, test_helpers.MockLondonReceipts, test_helpers.MockLondonBlock.Difficulty())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -251,7 +252,7 @@ var _ = Describe("API", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Single test db tear down at end of all tests
|
// Single test db tear down at end of all tests
|
||||||
defer It("test teardown", func() { eth.TearDownTestDB(db) })
|
defer It("test teardown", func() { shared.TearDownDB(db) })
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Headers and blocks
|
Headers and blocks
|
||||||
|
|||||||
+26
-11
@@ -43,12 +43,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
validator "github.com/vulcanize/eth-ipfs-state-validator/pkg"
|
validator "github.com/vulcanize/eth-ipfs-state-validator/v4/pkg"
|
||||||
ipfsethdb "github.com/vulcanize/ipfs-ethdb/postgres"
|
ipfsethdb "github.com/vulcanize/ipfs-ethdb/v4/postgres"
|
||||||
|
|
||||||
ethServerShared "github.com/ethereum/go-ethereum/statediff/indexer/shared"
|
ethServerShared "github.com/ethereum/go-ethereum/statediff/indexer/shared"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -59,31 +59,42 @@ var (
|
|||||||
|
|
||||||
// errMissingSignature is returned if a block's extra-data section doesn't seem
|
// errMissingSignature is returned if a block's extra-data section doesn't seem
|
||||||
// to contain a 65 byte secp256k1 signature.
|
// to contain a 65 byte secp256k1 signature.
|
||||||
errMissingSignature = errors.New("extra-data 65 byte signature suffix missing")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RetrieveCanonicalBlockHashByNumber = `SELECT block_hash FROM eth.header_cids
|
RetrieveCanonicalBlockHashByNumber = `SELECT block_hash FROM eth.header_cids
|
||||||
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
header_cids.mh_key = blocks.key
|
||||||
|
AND header_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = (SELECT canonical_header_hash($1))`
|
WHERE block_hash = (SELECT canonical_header_hash($1))`
|
||||||
RetrieveCanonicalHeaderByNumber = `SELECT cid, data FROM eth.header_cids
|
RetrieveCanonicalHeaderByNumber = `SELECT cid, data FROM eth.header_cids
|
||||||
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
header_cids.mh_key = blocks.key
|
||||||
|
AND header_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = (SELECT canonical_header_hash($1))`
|
WHERE block_hash = (SELECT canonical_header_hash($1))`
|
||||||
RetrieveTD = `SELECT CAST(td as Text) FROM eth.header_cids
|
RetrieveTD = `SELECT CAST(td as Text) FROM eth.header_cids
|
||||||
WHERE header_cids.block_hash = $1`
|
WHERE header_cids.block_hash = $1`
|
||||||
RetrieveRPCTransaction = `SELECT blocks.data, block_hash, block_number, index FROM public.blocks, eth.transaction_cids, eth.header_cids
|
RetrieveRPCTransaction = `SELECT blocks.data, block_hash, transaction_cids.block_number, index
|
||||||
|
FROM public.blocks, eth.transaction_cids, eth.header_cids
|
||||||
WHERE blocks.key = transaction_cids.mh_key
|
WHERE blocks.key = transaction_cids.mh_key
|
||||||
|
AND blocks.block_number = transaction_cids.block_number
|
||||||
AND transaction_cids.header_id = header_cids.block_hash
|
AND transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
AND transaction_cids.tx_hash = $1`
|
AND transaction_cids.tx_hash = $1`
|
||||||
RetrieveCodeHashByLeafKeyAndBlockHash = `SELECT code_hash FROM eth.state_accounts, eth.state_cids, eth.header_cids
|
RetrieveCodeHashByLeafKeyAndBlockHash = `SELECT code_hash FROM eth.state_accounts, eth.state_cids, eth.header_cids
|
||||||
WHERE state_accounts.header_id = state_cids.header_id AND state_accounts.state_path = state_cids.state_path
|
WHERE state_accounts.header_id = state_cids.header_id
|
||||||
|
AND state_accounts.state_path = state_cids.state_path
|
||||||
|
AND state_accounts.block_number = state_cids.block_number
|
||||||
AND state_cids.header_id = header_cids.block_hash
|
AND state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
AND state_leaf_key = $1
|
AND state_leaf_key = $1
|
||||||
AND block_number <= (SELECT block_number
|
AND header_cids.block_number <= (SELECT block_number
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
WHERE block_hash = $2)
|
WHERE block_hash = $2)
|
||||||
AND header_cids.block_hash = (SELECT canonical_header_hash(block_number))
|
AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
|
||||||
ORDER BY block_number DESC
|
ORDER BY header_cids.block_number DESC
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
RetrieveCodeByMhKey = `SELECT data FROM public.blocks WHERE key = $1`
|
RetrieveCodeByMhKey = `SELECT data FROM public.blocks WHERE key = $1`
|
||||||
)
|
)
|
||||||
@@ -215,6 +226,10 @@ func (b *Backend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.Bl
|
|||||||
return nil, errors.New("invalid arguments; neither block nor hash specified")
|
return nil, errors.New("invalid arguments; neither block nor hash specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Backend) PendingBlockAndReceipts() (*types.Block, types.Receipts) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetTd gets the total difficulty at the given block hash
|
// GetTd gets the total difficulty at the given block hash
|
||||||
func (b *Backend) GetTd(blockHash common.Hash) (*big.Int, error) {
|
func (b *Backend) GetTd(blockHash common.Hash) (*big.Int, error) {
|
||||||
var tdStr string
|
var tdStr string
|
||||||
|
|||||||
+194
-39
@@ -19,6 +19,7 @@ package eth
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
@@ -26,8 +27,10 @@ import (
|
|||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Retriever interface for substituting mocks in tests
|
// Retriever interface for substituting mocks in tests
|
||||||
@@ -39,13 +42,75 @@ type Retriever interface {
|
|||||||
|
|
||||||
// CIDRetriever satisfies the CIDRetriever interface for ethereum
|
// CIDRetriever satisfies the CIDRetriever interface for ethereum
|
||||||
type CIDRetriever struct {
|
type CIDRetriever struct {
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
|
gormDB *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPLDModelRecord struct {
|
||||||
|
models.IPLDModel
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName overrides the table name used by IPLD
|
||||||
|
func (IPLDModelRecord) TableName() string {
|
||||||
|
return "public.blocks"
|
||||||
|
}
|
||||||
|
|
||||||
|
type HeaderCIDRecord struct {
|
||||||
|
CID string `gorm:"column:cid"`
|
||||||
|
BlockHash string `gorm:"primaryKey"`
|
||||||
|
BlockNumber string `gorm:"primaryKey"`
|
||||||
|
ParentHash string
|
||||||
|
Timestamp uint64
|
||||||
|
StateRoot string
|
||||||
|
TotalDifficulty string `gorm:"column:td"`
|
||||||
|
TxRoot string
|
||||||
|
RctRoot string `gorm:"column:receipt_root"`
|
||||||
|
UncleRoot string
|
||||||
|
Bloom []byte
|
||||||
|
MhKey string
|
||||||
|
|
||||||
|
// gorm doesn't check if foreign key exists in database.
|
||||||
|
// It is required to eager load relations using preload.
|
||||||
|
TransactionCIDs []TransactionCIDRecord `gorm:"foreignKey:HeaderID,BlockNumber;references:BlockHash,BlockNumber"`
|
||||||
|
IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName overrides the table name used by HeaderCIDRecord
|
||||||
|
func (HeaderCIDRecord) TableName() string {
|
||||||
|
return "eth.header_cids"
|
||||||
|
}
|
||||||
|
|
||||||
|
type TransactionCIDRecord struct {
|
||||||
|
CID string `gorm:"column:cid"`
|
||||||
|
TxHash string `gorm:"primaryKey"`
|
||||||
|
BlockNumber string `gorm:"primaryKey"`
|
||||||
|
HeaderID string `gorm:"column:header_id"`
|
||||||
|
Index int64
|
||||||
|
Src string
|
||||||
|
Dst string
|
||||||
|
MhKey string
|
||||||
|
IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TableName overrides the table name used by TransactionCIDRecord
|
||||||
|
func (TransactionCIDRecord) TableName() string {
|
||||||
|
return "eth.transaction_cids"
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCIDRetriever returns a pointer to a new CIDRetriever which supports the CIDRetriever interface
|
// NewCIDRetriever returns a pointer to a new CIDRetriever which supports the CIDRetriever interface
|
||||||
func NewCIDRetriever(db *sqlx.DB) *CIDRetriever {
|
func NewCIDRetriever(db *sqlx.DB) *CIDRetriever {
|
||||||
|
gormDB, err := gorm.Open(postgres.New(postgres.Config{
|
||||||
|
Conn: db,
|
||||||
|
}), &gorm.Config{})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return &CIDRetriever{
|
return &CIDRetriever{
|
||||||
db: db,
|
db: db,
|
||||||
|
gormDB: gormDB,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +124,7 @@ func (ecr *CIDRetriever) RetrieveFirstBlockNumber() (int64, error) {
|
|||||||
// RetrieveLastBlockNumber is used to retrieve the latest block number in the db
|
// RetrieveLastBlockNumber is used to retrieve the latest block number in the db
|
||||||
func (ecr *CIDRetriever) RetrieveLastBlockNumber() (int64, error) {
|
func (ecr *CIDRetriever) RetrieveLastBlockNumber() (int64, error) {
|
||||||
var blockNumber int64
|
var blockNumber int64
|
||||||
err := ecr.db.Get(&blockNumber, "SELECT block_number FROM eth.header_cids ORDER BY block_number DESC LIMIT 1 ")
|
err := ecr.db.Get(&blockNumber, "SELECT block_number FROM eth.header_cids ORDER BY block_number DESC LIMIT 1")
|
||||||
return blockNumber, err
|
return blockNumber, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,9 +232,9 @@ func (ecr *CIDRetriever) Retrieve(filter SubscriptionSettings, blockNumber int64
|
|||||||
func (ecr *CIDRetriever) RetrieveHeaderCIDs(tx *sqlx.Tx, blockNumber int64) ([]models.HeaderModel, error) {
|
func (ecr *CIDRetriever) RetrieveHeaderCIDs(tx *sqlx.Tx, blockNumber int64) ([]models.HeaderModel, error) {
|
||||||
log.Debug("retrieving header cids for block ", blockNumber)
|
log.Debug("retrieving header cids for block ", blockNumber)
|
||||||
headers := make([]models.HeaderModel, 0)
|
headers := make([]models.HeaderModel, 0)
|
||||||
pgStr := `SELECT CAST(block_number as Text), block_hash,parent_hash,cid,mh_key,CAST(td as Text),node_id,
|
pgStr := `SELECT CAST(block_number as Text), block_hash, parent_hash, cid, mh_key, CAST(td as Text), node_id,
|
||||||
CAST(reward as Text), state_root,uncle_root,tx_root,receipt_root,bloom,timestamp,times_validated,
|
CAST(reward as Text), state_root, uncle_root,tx_root, receipt_root, bloom, timestamp, times_validated, coinbase
|
||||||
coinbase FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
WHERE block_number = $1`
|
WHERE block_number = $1`
|
||||||
return headers, tx.Select(&headers, pgStr, blockNumber)
|
return headers, tx.Select(&headers, pgStr, blockNumber)
|
||||||
}
|
}
|
||||||
@@ -178,7 +243,8 @@ func (ecr *CIDRetriever) RetrieveHeaderCIDs(tx *sqlx.Tx, blockNumber int64) ([]m
|
|||||||
func (ecr *CIDRetriever) RetrieveUncleCIDsByHeaderID(tx *sqlx.Tx, headerID string) ([]models.UncleModel, error) {
|
func (ecr *CIDRetriever) RetrieveUncleCIDsByHeaderID(tx *sqlx.Tx, headerID string) ([]models.UncleModel, error) {
|
||||||
log.Debug("retrieving uncle cids for block id ", headerID)
|
log.Debug("retrieving uncle cids for block id ", headerID)
|
||||||
headers := make([]models.UncleModel, 0)
|
headers := make([]models.UncleModel, 0)
|
||||||
pgStr := `SELECT header_id,block_hash,parent_hash,cid,mh_key, CAST(reward as text) FROM eth.uncle_cids
|
pgStr := `SELECT CAST(block_number as Text), header_id, block_hash, parent_hash, cid, mh_key, CAST(reward as text)
|
||||||
|
FROM eth.uncle_cids
|
||||||
WHERE header_id = $1`
|
WHERE header_id = $1`
|
||||||
return headers, tx.Select(&headers, pgStr, headerID)
|
return headers, tx.Select(&headers, pgStr, headerID)
|
||||||
}
|
}
|
||||||
@@ -190,10 +256,15 @@ func (ecr *CIDRetriever) RetrieveTxCIDs(tx *sqlx.Tx, txFilter TxFilter, headerID
|
|||||||
args := make([]interface{}, 0, 3)
|
args := make([]interface{}, 0, 3)
|
||||||
results := make([]models.TxModel, 0)
|
results := make([]models.TxModel, 0)
|
||||||
id := 1
|
id := 1
|
||||||
pgStr := fmt.Sprintf(`SELECT transaction_cids.tx_hash, transaction_cids.header_id,transaction_cids.cid, transaction_cids.mh_key,
|
pgStr := fmt.Sprintf(`SELECT CAST(transaction_cids.block_number as Text), transaction_cids.tx_hash,
|
||||||
transaction_cids.dst, transaction_cids.src, transaction_cids.index, transaction_cids.tx_data
|
transaction_cids.header_id,transaction_cids.cid, transaction_cids.mh_key, transaction_cids.dst,
|
||||||
FROM eth.transaction_cids INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash)
|
transaction_cids.src, transaction_cids.index, transaction_cids.tx_data
|
||||||
WHERE header_cids.block_hash = $%d`, id)
|
FROM eth.transaction_cids
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
WHERE header_cids.block_hash = $%d`, id)
|
||||||
args = append(args, headerID)
|
args = append(args, headerID)
|
||||||
id++
|
id++
|
||||||
if len(txFilter.Dst) > 0 {
|
if len(txFilter.Dst) > 0 {
|
||||||
@@ -292,11 +363,13 @@ func receiptFilterConditions(id *int, pgStr string, args []interface{}, rctFilte
|
|||||||
func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter ReceiptFilter, headerID string, trxHashes []string) ([]models.ReceiptModel, error) {
|
func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter ReceiptFilter, headerID string, trxHashes []string) ([]models.ReceiptModel, error) {
|
||||||
log.Debug("retrieving receipt cids for header id ", headerID)
|
log.Debug("retrieving receipt cids for header id ", headerID)
|
||||||
args := make([]interface{}, 0, 4)
|
args := make([]interface{}, 0, 4)
|
||||||
pgStr := `SELECT receipt_cids.tx_id, receipt_cids.leaf_cid, receipt_cids.leaf_mh_key,
|
pgStr := `SELECT CAST(receipt_cids.block_number as Text), receipt_cids.tx_id, receipt_cids.leaf_cid,
|
||||||
receipt_cids.contract, receipt_cids.contract_hash
|
receipt_cids.leaf_mh_key, receipt_cids.contract, receipt_cids.contract_hash
|
||||||
FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
||||||
WHERE receipt_cids.tx_id = transaction_cids.tx_hash
|
WHERE receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
AND transaction_cids.header_id = header_cids.block_hash
|
AND transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
AND header_cids.block_hash = $1`
|
AND header_cids.block_hash = $1`
|
||||||
id := 2
|
id := 2
|
||||||
args = append(args, headerID)
|
args = append(args, headerID)
|
||||||
@@ -304,24 +377,29 @@ func (ecr *CIDRetriever) RetrieveRctCIDsByHeaderID(tx *sqlx.Tx, rctFilter Receip
|
|||||||
pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, trxHashes)
|
pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, trxHashes)
|
||||||
|
|
||||||
pgStr += ` ORDER BY transaction_cids.index`
|
pgStr += ` ORDER BY transaction_cids.index`
|
||||||
receiptCids := make([]models.ReceiptModel, 0)
|
receiptCIDs := make([]models.ReceiptModel, 0)
|
||||||
return receiptCids, tx.Select(&receiptCids, pgStr, args...)
|
return receiptCIDs, tx.Select(&receiptCIDs, pgStr, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveFilteredGQLLogs retrieves and returns all the log cIDs provided blockHash that conform to the provided
|
// RetrieveFilteredGQLLogs retrieves and returns all the log CIDs provided blockHash that conform to the provided
|
||||||
// filter parameters.
|
// filter parameters.
|
||||||
func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash) ([]LogResult, error) {
|
func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash) ([]LogResult, error) {
|
||||||
log.Debug("retrieving log cids for receipt ids")
|
log.Debug("retrieving log cids for receipt ids")
|
||||||
args := make([]interface{}, 0, 4)
|
args := make([]interface{}, 0, 4)
|
||||||
id := 1
|
id := 1
|
||||||
pgStr := `SELECT eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
|
pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
|
||||||
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
|
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
|
||||||
eth.log_cids.log_data, eth.transaction_cids.tx_hash, data, eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status
|
eth.log_cids.log_data, eth.transaction_cids.tx_hash, data, eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status
|
||||||
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids, public.blocks
|
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids, public.blocks
|
||||||
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
||||||
|
AND eth.log_cids.block_number = eth.receipt_cids.block_number
|
||||||
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
AND transaction_cids.header_id = header_cids.block_hash
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
AND log_cids.leaf_mh_key = blocks.key AND header_cids.block_hash = $1`
|
AND transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
AND log_cids.leaf_mh_key = blocks.key
|
||||||
|
AND log_cids.block_number = blocks.block_number
|
||||||
|
AND header_cids.block_hash = $1`
|
||||||
|
|
||||||
args = append(args, blockHash.String())
|
args = append(args, blockHash.String())
|
||||||
id++
|
id++
|
||||||
@@ -343,14 +421,17 @@ func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptF
|
|||||||
func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
|
func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
|
||||||
log.Debug("retrieving log cids for receipt ids")
|
log.Debug("retrieving log cids for receipt ids")
|
||||||
args := make([]interface{}, 0, 4)
|
args := make([]interface{}, 0, 4)
|
||||||
pgStr := `SELECT eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
|
pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
|
||||||
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
|
eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
|
||||||
eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.index as txn_index,
|
eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.index as txn_index,
|
||||||
header_cids.block_hash, CAST(header_cids.block_number as Text)
|
header_cids.block_hash, CAST(header_cids.block_number as Text)
|
||||||
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
||||||
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
WHERE eth.log_cids.rct_id = receipt_cids.tx_id
|
||||||
|
AND eth.log_cids.block_number = eth.receipt_cids.block_number
|
||||||
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
AND transaction_cids.header_id = header_cids.block_hash`
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
AND transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number`
|
||||||
id := 1
|
id := 1
|
||||||
if blockNumber > 0 {
|
if blockNumber > 0 {
|
||||||
pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
|
pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
|
||||||
@@ -380,10 +461,13 @@ func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilte
|
|||||||
func (ecr *CIDRetriever) RetrieveRctCIDs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash, txHashes []string) ([]models.ReceiptModel, error) {
|
func (ecr *CIDRetriever) RetrieveRctCIDs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash, txHashes []string) ([]models.ReceiptModel, error) {
|
||||||
log.Debug("retrieving receipt cids for block ", blockNumber)
|
log.Debug("retrieving receipt cids for block ", blockNumber)
|
||||||
args := make([]interface{}, 0, 5)
|
args := make([]interface{}, 0, 5)
|
||||||
pgStr := `SELECT receipt_cids.tx_id, receipt_cids.leaf_cid, receipt_cids.leaf_mh_key, receipt_cids.tx_id
|
pgStr := `SELECT CAST(receipt_cids.block_number as Text), receipt_cids.tx_id, receipt_cids.leaf_cid,
|
||||||
|
receipt_cids.leaf_mh_key,
|
||||||
FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids
|
||||||
WHERE receipt_cids.tx_id = transaction_cids.tx_hash
|
WHERE receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
AND transaction_cids.header_id = header_cids.block_hash`
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
AND transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number`
|
||||||
id := 1
|
id := 1
|
||||||
if blockNumber > 0 {
|
if blockNumber > 0 {
|
||||||
pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
|
pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
|
||||||
@@ -399,8 +483,8 @@ func (ecr *CIDRetriever) RetrieveRctCIDs(tx *sqlx.Tx, rctFilter ReceiptFilter, b
|
|||||||
pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, txHashes)
|
pgStr, args = receiptFilterConditions(&id, pgStr, args, rctFilter, txHashes)
|
||||||
|
|
||||||
pgStr += ` ORDER BY transaction_cids.index`
|
pgStr += ` ORDER BY transaction_cids.index`
|
||||||
receiptCids := make([]models.ReceiptModel, 0)
|
receiptCIDs := make([]models.ReceiptModel, 0)
|
||||||
return receiptCids, tx.Select(&receiptCids, pgStr, args...)
|
return receiptCIDs, tx.Select(&receiptCIDs, pgStr, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasTopics(topics [][]string) bool {
|
func hasTopics(topics [][]string) bool {
|
||||||
@@ -416,9 +500,13 @@ func hasTopics(topics [][]string) bool {
|
|||||||
func (ecr *CIDRetriever) RetrieveStateCIDs(tx *sqlx.Tx, stateFilter StateFilter, headerID string) ([]models.StateNodeModel, error) {
|
func (ecr *CIDRetriever) RetrieveStateCIDs(tx *sqlx.Tx, stateFilter StateFilter, headerID string) ([]models.StateNodeModel, error) {
|
||||||
log.Debug("retrieving state cids for header id ", headerID)
|
log.Debug("retrieving state cids for header id ", headerID)
|
||||||
args := make([]interface{}, 0, 2)
|
args := make([]interface{}, 0, 2)
|
||||||
pgStr := `SELECT state_cids.header_id,
|
pgStr := `SELECT CAST(state_cids.block_number as Text), state_cids.header_id,
|
||||||
state_cids.state_leaf_key, state_cids.node_type, state_cids.cid, state_cids.mh_key, state_cids.state_path
|
state_cids.state_leaf_key, state_cids.node_type, state_cids.cid, state_cids.mh_key, state_cids.state_path
|
||||||
FROM eth.state_cids INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash)
|
FROM eth.state_cids
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
WHERE header_cids.block_hash = $1`
|
WHERE header_cids.block_hash = $1`
|
||||||
args = append(args, headerID)
|
args = append(args, headerID)
|
||||||
addrLen := len(stateFilter.Addresses)
|
addrLen := len(stateFilter.Addresses)
|
||||||
@@ -441,11 +529,15 @@ func (ecr *CIDRetriever) RetrieveStateCIDs(tx *sqlx.Tx, stateFilter StateFilter,
|
|||||||
func (ecr *CIDRetriever) RetrieveStorageCIDs(tx *sqlx.Tx, storageFilter StorageFilter, headerID string) ([]models.StorageNodeWithStateKeyModel, error) {
|
func (ecr *CIDRetriever) RetrieveStorageCIDs(tx *sqlx.Tx, storageFilter StorageFilter, headerID string) ([]models.StorageNodeWithStateKeyModel, error) {
|
||||||
log.Debug("retrieving storage cids for header id ", headerID)
|
log.Debug("retrieving storage cids for header id ", headerID)
|
||||||
args := make([]interface{}, 0, 3)
|
args := make([]interface{}, 0, 3)
|
||||||
pgStr := `SELECT storage_cids.header_id, storage_cids.storage_leaf_key, storage_cids.node_type,
|
pgStr := `SELECT CAST(storage_cids.block_number as Text), storage_cids.header_id, storage_cids.storage_leaf_key,
|
||||||
storage_cids.cid, storage_cids.mh_key, storage_cids.storage_path, storage_cids.state_path, state_cids.state_leaf_key
|
storage_cids.node_type, storage_cids.cid, storage_cids.mh_key, storage_cids.storage_path, storage_cids.state_path,
|
||||||
|
state_cids.state_leaf_key
|
||||||
FROM eth.storage_cids, eth.state_cids, eth.header_cids
|
FROM eth.storage_cids, eth.state_cids, eth.header_cids
|
||||||
WHERE storage_cids.header_id = state_cids.header_id AND storage_cids.state_path = state_cids.state_path
|
WHERE storage_cids.header_id = state_cids.header_id
|
||||||
|
AND storage_cids.state_path = state_cids.state_path
|
||||||
|
AND storage_cids.block_number = state_cids.block_number
|
||||||
AND state_cids.header_id = header_cids.block_hash
|
AND state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
AND header_cids.block_hash = $1`
|
AND header_cids.block_hash = $1`
|
||||||
args = append(args, headerID)
|
args = append(args, headerID)
|
||||||
id := 2
|
id := 2
|
||||||
@@ -496,6 +588,10 @@ func (ecr *CIDRetriever) RetrieveBlockByHash(blockHash common.Hash) (models.Head
|
|||||||
log.Error("header cid retrieval error")
|
log.Error("header cid retrieval error")
|
||||||
return models.HeaderModel{}, nil, nil, nil, err
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
|
}
|
||||||
var uncleCIDs []models.UncleModel
|
var uncleCIDs []models.UncleModel
|
||||||
uncleCIDs, err = ecr.RetrieveUncleCIDsByHeaderID(tx, headerCID.BlockHash)
|
uncleCIDs, err = ecr.RetrieveUncleCIDsByHeaderID(tx, headerCID.BlockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -503,7 +599,7 @@ func (ecr *CIDRetriever) RetrieveBlockByHash(blockHash common.Hash) (models.Head
|
|||||||
return models.HeaderModel{}, nil, nil, nil, err
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
var txCIDs []models.TxModel
|
var txCIDs []models.TxModel
|
||||||
txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash)
|
txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID.BlockHash, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("tx cid retrieval error")
|
log.Error("tx cid retrieval error")
|
||||||
return models.HeaderModel{}, nil, nil, nil, err
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
@@ -556,7 +652,7 @@ func (ecr *CIDRetriever) RetrieveBlockByNumber(blockNumber int64) (models.Header
|
|||||||
return models.HeaderModel{}, nil, nil, nil, err
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
}
|
}
|
||||||
var txCIDs []models.TxModel
|
var txCIDs []models.TxModel
|
||||||
txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID[0].BlockHash)
|
txCIDs, err = ecr.RetrieveTxCIDsByHeaderID(tx, headerCID[0].BlockHash, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("tx cid retrieval error")
|
log.Error("tx cid retrieval error")
|
||||||
return models.HeaderModel{}, nil, nil, nil, err
|
return models.HeaderModel{}, nil, nil, nil, err
|
||||||
@@ -576,31 +672,90 @@ func (ecr *CIDRetriever) RetrieveBlockByNumber(blockNumber int64) (models.Header
|
|||||||
// RetrieveHeaderCIDByHash returns the header for the given block hash
|
// RetrieveHeaderCIDByHash returns the header for the given block hash
|
||||||
func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) {
|
func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) {
|
||||||
log.Debug("retrieving header cids for block hash ", blockHash.String())
|
log.Debug("retrieving header cids for block hash ", blockHash.String())
|
||||||
pgStr := `SELECT block_hash,cid,mh_key FROM eth.header_cids
|
pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, CAST(td as Text),
|
||||||
|
state_root, uncle_root, tx_root, receipt_root, bloom, timestamp FROM eth.header_cids
|
||||||
WHERE block_hash = $1`
|
WHERE block_hash = $1`
|
||||||
var headerCID models.HeaderModel
|
var headerCID models.HeaderModel
|
||||||
return headerCID, tx.Get(&headerCID, pgStr, blockHash.String())
|
return headerCID, tx.Get(&headerCID, pgStr, blockHash.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveTxCIDsByHeaderID retrieves all tx CIDs for the given header id
|
// RetrieveTxCIDsByHeaderID retrieves all tx CIDs for the given header id
|
||||||
func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string) ([]models.TxModel, error) {
|
func (ecr *CIDRetriever) RetrieveTxCIDsByHeaderID(tx *sqlx.Tx, headerID string, blockNumber int64) ([]models.TxModel, error) {
|
||||||
log.Debug("retrieving tx cids for block id ", headerID)
|
log.Debug("retrieving tx cids for block id ", headerID)
|
||||||
pgStr := `SELECT * FROM eth.transaction_cids
|
pgStr := `SELECT CAST(block_number as Text), header_id, index, tx_hash, cid, mh_key,
|
||||||
WHERE header_id = $1
|
dst, src, tx_data, tx_type, value
|
||||||
|
FROM eth.transaction_cids
|
||||||
|
WHERE header_id = $1 AND block_number = $2
|
||||||
ORDER BY index`
|
ORDER BY index`
|
||||||
var txCIDs []models.TxModel
|
var txCIDs []models.TxModel
|
||||||
return txCIDs, tx.Select(&txCIDs, pgStr, headerID)
|
return txCIDs, tx.Select(&txCIDs, pgStr, headerID, blockNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveReceiptCIDsByTxIDs retrieves receipt CIDs by their associated tx IDs
|
// RetrieveReceiptCIDsByTxIDs retrieves receipt CIDs by their associated tx IDs
|
||||||
func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []string) ([]models.ReceiptModel, error) {
|
func (ecr *CIDRetriever) RetrieveReceiptCIDsByTxIDs(tx *sqlx.Tx, txHashes []string) ([]models.ReceiptModel, error) {
|
||||||
log.Debugf("retrieving receipt cids for tx hashes %v", txHashes)
|
log.Debugf("retrieving receipt cids for tx hashes %v", txHashes)
|
||||||
pgStr := `SELECT receipt_cids.tx_id, receipt_cids.leaf_cid, receipt_cids.leaf_mh_key,
|
pgStr := `SELECT CAST(receipt_cids.block_number as Text), receipt_cids.tx_id, receipt_cids.leaf_cid, receipt_cids.leaf_mh_key,
|
||||||
receipt_cids.contract, receipt_cids.contract_hash
|
receipt_cids.contract, receipt_cids.contract_hash
|
||||||
FROM eth.receipt_cids, eth.transaction_cids
|
FROM eth.receipt_cids, eth.transaction_cids
|
||||||
WHERE tx_id = ANY($1)
|
WHERE tx_id = ANY($1)
|
||||||
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
AND receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
ORDER BY transaction_cids.index`
|
ORDER BY transaction_cids.index`
|
||||||
var rctCIDs []models.ReceiptModel
|
var rctCIDs []models.ReceiptModel
|
||||||
return rctCIDs, tx.Select(&rctCIDs, pgStr, pq.Array(txHashes))
|
return rctCIDs, tx.Select(&rctCIDs, pgStr, pq.Array(txHashes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number
|
||||||
|
func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCIDRecord, error) {
|
||||||
|
log.Debug("retrieving header cids and tx cids for block number ", blockNumber)
|
||||||
|
|
||||||
|
var headerCIDs []HeaderCIDRecord
|
||||||
|
|
||||||
|
// https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
|
||||||
|
// Will use join for TransactionCIDs once preload for 1:N is supported.
|
||||||
|
err := ecr.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
|
||||||
|
return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
|
||||||
|
}).Joins("IPLD").Find(&headerCIDs, "header_cids.block_number = ?", blockNumber).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("header cid retrieval error")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerCIDs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash
|
||||||
|
func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash) (HeaderCIDRecord, error) {
|
||||||
|
log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String())
|
||||||
|
|
||||||
|
var headerCID HeaderCIDRecord
|
||||||
|
|
||||||
|
// https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
|
||||||
|
// Will use join for TransactionCIDs once preload for 1:N is supported.
|
||||||
|
err := ecr.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
|
||||||
|
return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
|
||||||
|
}).Joins("IPLD").First(&headerCID, "block_hash = ?", blockHash.String()).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("header cid retrieval error")
|
||||||
|
return headerCID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerCID, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetrieveTxCIDByHash returns the tx for the given tx hash
|
||||||
|
func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string) (TransactionCIDRecord, error) {
|
||||||
|
log.Debug("retrieving tx cid for tx hash ", txHash)
|
||||||
|
|
||||||
|
var txCID TransactionCIDRecord
|
||||||
|
|
||||||
|
err := ecr.gormDB.Joins("IPLD").First(&txCID, "tx_hash = ?", txHash).Error
|
||||||
|
if err != nil {
|
||||||
|
log.Error("header cid retrieval error")
|
||||||
|
return txCID, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return txCID, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -215,13 +216,13 @@ var _ = Describe("Retriever", func() {
|
|||||||
retriever *eth.CIDRetriever
|
retriever *eth.CIDRetriever
|
||||||
)
|
)
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
db = eth.SetupTestDB()
|
db = shared.SetupDB()
|
||||||
diffIndexer = eth.SetupTestStateDiffIndexer(ctx, params.TestChainConfig, test_helpers.Genesis.Hash())
|
diffIndexer = shared.SetupTestStateDiffIndexer(ctx, params.TestChainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
retriever = eth.NewCIDRetriever(db)
|
retriever = eth.NewCIDRetriever(db)
|
||||||
})
|
})
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
eth.TearDownTestDB(db)
|
shared.TearDownDB(db)
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Retrieve", func() {
|
Describe("Retrieve", func() {
|
||||||
@@ -248,6 +249,7 @@ var _ = Describe("Retriever", func() {
|
|||||||
AND header_cids.block_number = $1
|
AND header_cids.block_number = $1
|
||||||
ORDER BY transaction_cids.index`
|
ORDER BY transaction_cids.index`
|
||||||
err := db.Select(&expectedRctCIDsAndLeafNodes, pgStr, test_helpers.BlockNumber.Uint64())
|
err := db.Select(&expectedRctCIDsAndLeafNodes, pgStr, test_helpers.BlockNumber.Uint64())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
cids, empty, err := retriever.Retrieve(openFilter, 1)
|
cids, empty, err := retriever.Retrieve(openFilter, 1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(empty).ToNot(BeTrue())
|
Expect(empty).ToNot(BeTrue())
|
||||||
@@ -411,12 +413,13 @@ var _ = Describe("Retriever", func() {
|
|||||||
Expect(len(cids7[0].StorageNodes)).To(Equal(0))
|
Expect(len(cids7[0].StorageNodes)).To(Equal(0))
|
||||||
Expect(len(cids7[0].StateNodes)).To(Equal(1))
|
Expect(len(cids7[0].StateNodes)).To(Equal(1))
|
||||||
Expect(cids7[0].StateNodes[0]).To(Equal(models.StateNodeModel{
|
Expect(cids7[0].StateNodes[0]).To(Equal(models.StateNodeModel{
|
||||||
HeaderID: cids7[0].StateNodes[0].HeaderID,
|
BlockNumber: "1",
|
||||||
NodeType: 2,
|
HeaderID: cids7[0].StateNodes[0].HeaderID,
|
||||||
StateKey: common.BytesToHash(test_helpers.AccountLeafKey).Hex(),
|
NodeType: 2,
|
||||||
CID: test_helpers.State2CID.String(),
|
StateKey: common.BytesToHash(test_helpers.AccountLeafKey).Hex(),
|
||||||
MhKey: test_helpers.State2MhKey,
|
CID: test_helpers.State2CID.String(),
|
||||||
Path: []byte{'\x0c'},
|
MhKey: test_helpers.State2MhKey,
|
||||||
|
Path: []byte{'\x0c'},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
_, empty, err = retriever.Retrieve(rctTopicsAndAddressFilterFail, 1)
|
_, empty, err = retriever.Retrieve(rctTopicsAndAddressFilterFail, 1)
|
||||||
|
|||||||
@@ -37,9 +37,10 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
ethServerShared "github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
|
ethServerShared "github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -74,8 +75,8 @@ var _ = Describe("eth state reading tests", func() {
|
|||||||
It("test init", func() {
|
It("test init", func() {
|
||||||
// db and type initializations
|
// db and type initializations
|
||||||
var err error
|
var err error
|
||||||
db = eth.SetupTestDB()
|
db = shared.SetupDB()
|
||||||
transformer := eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
transformer := shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
backend, err = eth.NewEthBackend(db, ð.Config{
|
backend, err = eth.NewEthBackend(db, ð.Config{
|
||||||
ChainConfig: chainConfig,
|
ChainConfig: chainConfig,
|
||||||
@@ -155,7 +156,7 @@ var _ = Describe("eth state reading tests", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert some non-canonical data into the database so that we test our ability to discern canonicity
|
// Insert some non-canonical data into the database so that we test our ability to discern canonicity
|
||||||
indexAndPublisher := eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
indexAndPublisher := shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
tx, err := indexAndPublisher.PushBlock(test_helpers.MockBlock, test_helpers.MockReceipts, test_helpers.MockBlock.Difficulty())
|
tx, err := indexAndPublisher.PushBlock(test_helpers.MockBlock, test_helpers.MockReceipts, test_helpers.MockBlock.Difficulty())
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -181,7 +182,7 @@ var _ = Describe("eth state reading tests", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
defer It("test teardown", func() {
|
defer It("test teardown", func() {
|
||||||
eth.TearDownTestDB(db)
|
shared.TearDownDB(db)
|
||||||
chain.Stop()
|
chain.Stop()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
+15
-10
@@ -82,8 +82,9 @@ func (s *ResponseFilterer) filterHeaders(headerFilter HeaderFilter, response *IP
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response.Header = models.IPLDModel{
|
response.Header = models.IPLDModel{
|
||||||
Data: headerRLP,
|
BlockNumber: payload.Block.Number().String(),
|
||||||
Key: cid.String(),
|
Data: headerRLP,
|
||||||
|
Key: cid.String(),
|
||||||
}
|
}
|
||||||
if headerFilter.Uncles {
|
if headerFilter.Uncles {
|
||||||
response.Uncles = make([]models.IPLDModel, len(payload.Block.Body().Uncles))
|
response.Uncles = make([]models.IPLDModel, len(payload.Block.Body().Uncles))
|
||||||
@@ -97,8 +98,9 @@ func (s *ResponseFilterer) filterHeaders(headerFilter HeaderFilter, response *IP
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
response.Uncles[i] = models.IPLDModel{
|
response.Uncles[i] = models.IPLDModel{
|
||||||
Data: uncleRlp,
|
BlockNumber: uncle.Number.String(),
|
||||||
Key: cid.String(),
|
Data: uncleRlp,
|
||||||
|
Key: cid.String(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,8 +185,9 @@ func (s *ResponseFilterer) filerReceipts(receiptFilter ReceiptFilter, response *
|
|||||||
// TODO: Verify this filter logic.
|
// TODO: Verify this filter logic.
|
||||||
if checkReceipts(receipt, receiptFilter.Topics, topics, receiptFilter.LogAddresses, contracts, trxHashes) {
|
if checkReceipts(receipt, receiptFilter.Topics, topics, receiptFilter.LogAddresses, contracts, trxHashes) {
|
||||||
response.Receipts = append(response.Receipts, models.IPLDModel{
|
response.Receipts = append(response.Receipts, models.IPLDModel{
|
||||||
Data: rctIPLDData[idx],
|
BlockNumber: payload.Block.Number().String(),
|
||||||
Key: rctLeafCID[idx].String(),
|
Data: rctIPLDData[idx],
|
||||||
|
Key: rctLeafCID[idx].String(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,8 +285,9 @@ func (s *ResponseFilterer) filterStateAndStorage(stateFilter StateFilter, storag
|
|||||||
StateLeafKey: common.BytesToHash(stateNode.LeafKey),
|
StateLeafKey: common.BytesToHash(stateNode.LeafKey),
|
||||||
Path: stateNode.Path,
|
Path: stateNode.Path,
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: stateNode.NodeValue,
|
BlockNumber: payload.Block.Number().String(),
|
||||||
Key: cid.String(),
|
Data: stateNode.NodeValue,
|
||||||
|
Key: cid.String(),
|
||||||
},
|
},
|
||||||
Type: stateNode.NodeType,
|
Type: stateNode.NodeType,
|
||||||
})
|
})
|
||||||
@@ -300,8 +304,9 @@ func (s *ResponseFilterer) filterStateAndStorage(stateFilter StateFilter, storag
|
|||||||
StateLeafKey: common.BytesToHash(stateNode.LeafKey),
|
StateLeafKey: common.BytesToHash(stateNode.LeafKey),
|
||||||
StorageLeafKey: common.BytesToHash(storageNode.LeafKey),
|
StorageLeafKey: common.BytesToHash(storageNode.LeafKey),
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: storageNode.NodeValue,
|
BlockNumber: payload.Block.Number().String(),
|
||||||
Key: cid.String(),
|
Data: storageNode.NodeValue,
|
||||||
|
Key: cid.String(),
|
||||||
},
|
},
|
||||||
Type: storageNode.NodeType,
|
Type: storageNode.NodeType,
|
||||||
Path: storageNode.Path,
|
Path: storageNode.Path,
|
||||||
|
|||||||
+27
-19
@@ -25,9 +25,9 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -61,14 +61,16 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(stateNode.Type).To(Equal(sdtypes.Leaf))
|
Expect(stateNode.Type).To(Equal(sdtypes.Leaf))
|
||||||
if bytes.Equal(stateNode.StateLeafKey.Bytes(), test_helpers.AccountLeafKey) {
|
if bytes.Equal(stateNode.StateLeafKey.Bytes(), test_helpers.AccountLeafKey) {
|
||||||
Expect(stateNode.IPLD).To(Equal(models.IPLDModel{
|
Expect(stateNode.IPLD).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.State2IPLD.RawData(),
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.State2IPLD.Cid().String(),
|
Data: test_helpers.State2IPLD.RawData(),
|
||||||
|
Key: test_helpers.State2IPLD.Cid().String(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
if bytes.Equal(stateNode.StateLeafKey.Bytes(), test_helpers.ContractLeafKey) {
|
if bytes.Equal(stateNode.StateLeafKey.Bytes(), test_helpers.ContractLeafKey) {
|
||||||
Expect(stateNode.IPLD).To(Equal(models.IPLDModel{
|
Expect(stateNode.IPLD).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.State1IPLD.RawData(),
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.State1IPLD.Cid().String(),
|
Data: test_helpers.State1IPLD.RawData(),
|
||||||
|
Key: test_helpers.State1IPLD.Cid().String(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,8 +89,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds1.StateNodes)).To(Equal(0))
|
Expect(len(iplds1.StateNodes)).To(Equal(0))
|
||||||
Expect(len(iplds1.Receipts)).To(Equal(1))
|
Expect(len(iplds1.Receipts)).To(Equal(1))
|
||||||
Expect(iplds1.Receipts[0]).To(Equal(models.IPLDModel{
|
Expect(iplds1.Receipts[0]).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.Rct1IPLD,
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.Rct1CID.String(),
|
Data: test_helpers.Rct1IPLD,
|
||||||
|
Key: test_helpers.Rct1CID.String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds2, err := filterer.Filter(rctTopicsFilter, test_helpers.MockConvertedPayload)
|
iplds2, err := filterer.Filter(rctTopicsFilter, test_helpers.MockConvertedPayload)
|
||||||
@@ -102,8 +105,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds2.StateNodes)).To(Equal(0))
|
Expect(len(iplds2.StateNodes)).To(Equal(0))
|
||||||
Expect(len(iplds2.Receipts)).To(Equal(1))
|
Expect(len(iplds2.Receipts)).To(Equal(1))
|
||||||
Expect(iplds2.Receipts[0]).To(Equal(models.IPLDModel{
|
Expect(iplds2.Receipts[0]).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.Rct1IPLD,
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.Rct1CID.String(),
|
Data: test_helpers.Rct1IPLD,
|
||||||
|
Key: test_helpers.Rct1CID.String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds3, err := filterer.Filter(rctTopicsAndAddressFilter, test_helpers.MockConvertedPayload)
|
iplds3, err := filterer.Filter(rctTopicsAndAddressFilter, test_helpers.MockConvertedPayload)
|
||||||
@@ -117,8 +121,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds3.StateNodes)).To(Equal(0))
|
Expect(len(iplds3.StateNodes)).To(Equal(0))
|
||||||
Expect(len(iplds3.Receipts)).To(Equal(1))
|
Expect(len(iplds3.Receipts)).To(Equal(1))
|
||||||
Expect(iplds3.Receipts[0]).To(Equal(models.IPLDModel{
|
Expect(iplds3.Receipts[0]).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.Rct1IPLD,
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.Rct1CID.String(),
|
Data: test_helpers.Rct1IPLD,
|
||||||
|
Key: test_helpers.Rct1CID.String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds4, err := filterer.Filter(rctAddressesAndTopicFilter, test_helpers.MockConvertedPayload)
|
iplds4, err := filterer.Filter(rctAddressesAndTopicFilter, test_helpers.MockConvertedPayload)
|
||||||
@@ -132,8 +137,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds4.StateNodes)).To(Equal(0))
|
Expect(len(iplds4.StateNodes)).To(Equal(0))
|
||||||
Expect(len(iplds4.Receipts)).To(Equal(1))
|
Expect(len(iplds4.Receipts)).To(Equal(1))
|
||||||
Expect(iplds4.Receipts[0]).To(Equal(models.IPLDModel{
|
Expect(iplds4.Receipts[0]).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.Rct2IPLD,
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.Rct2CID.String(),
|
Data: test_helpers.Rct2IPLD,
|
||||||
|
Key: test_helpers.Rct2CID.String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds5, err := filterer.Filter(rctsForAllCollectedTrxs, test_helpers.MockConvertedPayload)
|
iplds5, err := filterer.Filter(rctsForAllCollectedTrxs, test_helpers.MockConvertedPayload)
|
||||||
@@ -165,8 +171,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds6.StateNodes)).To(Equal(0))
|
Expect(len(iplds6.StateNodes)).To(Equal(0))
|
||||||
Expect(len(iplds6.Receipts)).To(Equal(1))
|
Expect(len(iplds6.Receipts)).To(Equal(1))
|
||||||
Expect(iplds4.Receipts[0]).To(Equal(models.IPLDModel{
|
Expect(iplds4.Receipts[0]).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.Rct2IPLD,
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.Rct2CID.String(),
|
Data: test_helpers.Rct2IPLD,
|
||||||
|
Key: test_helpers.Rct2CID.String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds7, err := filterer.Filter(stateFilter, test_helpers.MockConvertedPayload)
|
iplds7, err := filterer.Filter(stateFilter, test_helpers.MockConvertedPayload)
|
||||||
@@ -181,8 +188,9 @@ var _ = Describe("Filterer", func() {
|
|||||||
Expect(len(iplds7.StateNodes)).To(Equal(1))
|
Expect(len(iplds7.StateNodes)).To(Equal(1))
|
||||||
Expect(iplds7.StateNodes[0].StateLeafKey.Bytes()).To(Equal(test_helpers.AccountLeafKey))
|
Expect(iplds7.StateNodes[0].StateLeafKey.Bytes()).To(Equal(test_helpers.AccountLeafKey))
|
||||||
Expect(iplds7.StateNodes[0].IPLD).To(Equal(models.IPLDModel{
|
Expect(iplds7.StateNodes[0].IPLD).To(Equal(models.IPLDModel{
|
||||||
Data: test_helpers.State2IPLD.RawData(),
|
BlockNumber: test_helpers.BlockNumber.String(),
|
||||||
Key: test_helpers.State2IPLD.Cid().String(),
|
Data: test_helpers.State2IPLD.RawData(),
|
||||||
|
Key: test_helpers.State2IPLD.Cid().String(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
iplds8, err := filterer.Filter(rctTopicsAndAddressFilterFail, test_helpers.MockConvertedPayload)
|
iplds8, err := filterer.Filter(rctTopicsAndAddressFilterFail, test_helpers.MockConvertedPayload)
|
||||||
|
|||||||
@@ -17,16 +17,7 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func ResolveToNodeType(nodeType int) sdtypes.NodeType {
|
func ResolveToNodeType(nodeType int) sdtypes.NodeType {
|
||||||
@@ -43,41 +34,3 @@ func ResolveToNodeType(nodeType int) sdtypes.NodeType {
|
|||||||
return sdtypes.Unknown
|
return sdtypes.Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig loads chain config from json file
|
|
||||||
func LoadConfig(chainConfigPath string) (*params.ChainConfig, error) {
|
|
||||||
file, err := os.Open(chainConfigPath)
|
|
||||||
if err != nil {
|
|
||||||
utils.Fatalf("Failed to read chain config file: %v", err)
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
chainConfig := new(params.ChainConfig)
|
|
||||||
if err := json.NewDecoder(file).Decode(chainConfig); err != nil {
|
|
||||||
utils.Fatalf("invalid chain config file: %v", err)
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("Using chain config from %s file. Content %+v", chainConfigPath, chainConfig)
|
|
||||||
|
|
||||||
return chainConfig, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainConfig returns the appropriate ethereum chain config for the provided chain id
|
|
||||||
func ChainConfig(chainID uint64) (*params.ChainConfig, error) {
|
|
||||||
switch chainID {
|
|
||||||
case 1:
|
|
||||||
return params.MainnetChainConfig, nil
|
|
||||||
case 3:
|
|
||||||
return params.RopstenChainConfig, nil
|
|
||||||
case 4:
|
|
||||||
return params.RinkebyChainConfig, nil
|
|
||||||
case 5:
|
|
||||||
return params.GoerliChainConfig, nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("chain config for chainid %d not available", chainID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+52
-20
@@ -20,12 +20,13 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fetcher interface for substituting mocks in tests
|
// Fetcher interface for substituting mocks in tests
|
||||||
@@ -99,16 +100,22 @@ func (f *IPLDFetcher) Fetch(cids CIDWrapper) (*IPLDs, error) {
|
|||||||
return iplds, err
|
return iplds, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchHeaders fetches headers
|
// FetchHeader fetches header
|
||||||
func (f *IPLDFetcher) FetchHeader(tx *sqlx.Tx, c models.HeaderModel) (models.IPLDModel, error) {
|
func (f *IPLDFetcher) FetchHeader(tx *sqlx.Tx, c models.HeaderModel) (models.IPLDModel, error) {
|
||||||
log.Debug("fetching header ipld")
|
log.Debug("fetching header ipld")
|
||||||
headerBytes, err := shared.FetchIPLDByMhKey(tx, c.MhKey)
|
blockNumber, err := strconv.ParseUint(c.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return models.IPLDModel{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
headerBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, c.MhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return models.IPLDModel{}, err
|
return models.IPLDModel{}, err
|
||||||
}
|
}
|
||||||
return models.IPLDModel{
|
return models.IPLDModel{
|
||||||
Data: headerBytes,
|
BlockNumber: c.BlockNumber,
|
||||||
Key: c.CID,
|
Data: headerBytes,
|
||||||
|
Key: c.CID,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,13 +124,18 @@ func (f *IPLDFetcher) FetchUncles(tx *sqlx.Tx, cids []models.UncleModel) ([]mode
|
|||||||
log.Debug("fetching uncle iplds")
|
log.Debug("fetching uncle iplds")
|
||||||
uncleIPLDs := make([]models.IPLDModel, len(cids))
|
uncleIPLDs := make([]models.IPLDModel, len(cids))
|
||||||
for i, c := range cids {
|
for i, c := range cids {
|
||||||
uncleBytes, err := shared.FetchIPLDByMhKey(tx, c.MhKey)
|
blockNumber, err := strconv.ParseUint(c.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
uncleBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, c.MhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
uncleIPLDs[i] = models.IPLDModel{
|
uncleIPLDs[i] = models.IPLDModel{
|
||||||
Data: uncleBytes,
|
BlockNumber: c.BlockNumber,
|
||||||
Key: c.CID,
|
Data: uncleBytes,
|
||||||
|
Key: c.CID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uncleIPLDs, nil
|
return uncleIPLDs, nil
|
||||||
@@ -134,13 +146,18 @@ func (f *IPLDFetcher) FetchTrxs(tx *sqlx.Tx, cids []models.TxModel) ([]models.IP
|
|||||||
log.Debug("fetching transaction iplds")
|
log.Debug("fetching transaction iplds")
|
||||||
trxIPLDs := make([]models.IPLDModel, len(cids))
|
trxIPLDs := make([]models.IPLDModel, len(cids))
|
||||||
for i, c := range cids {
|
for i, c := range cids {
|
||||||
txBytes, err := shared.FetchIPLDByMhKey(tx, c.MhKey)
|
blockNumber, err := strconv.ParseUint(c.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
txBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, c.MhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
trxIPLDs[i] = models.IPLDModel{
|
trxIPLDs[i] = models.IPLDModel{
|
||||||
Data: txBytes,
|
BlockNumber: c.BlockNumber,
|
||||||
Key: c.CID,
|
Data: txBytes,
|
||||||
|
Key: c.CID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return trxIPLDs, nil
|
return trxIPLDs, nil
|
||||||
@@ -151,14 +168,19 @@ func (f *IPLDFetcher) FetchRcts(tx *sqlx.Tx, cids []models.ReceiptModel) ([]mode
|
|||||||
log.Debug("fetching receipt iplds")
|
log.Debug("fetching receipt iplds")
|
||||||
rctIPLDs := make([]models.IPLDModel, len(cids))
|
rctIPLDs := make([]models.IPLDModel, len(cids))
|
||||||
for i, c := range cids {
|
for i, c := range cids {
|
||||||
rctBytes, err := shared.FetchIPLDByMhKey(tx, c.LeafMhKey)
|
blockNumber, err := strconv.ParseUint(c.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rctBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, c.LeafMhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//nodeVal, err := DecodeLeafNode(rctBytes)
|
//nodeVal, err := DecodeLeafNode(rctBytes)
|
||||||
rctIPLDs[i] = models.IPLDModel{
|
rctIPLDs[i] = models.IPLDModel{
|
||||||
Data: rctBytes,
|
BlockNumber: c.BlockNumber,
|
||||||
Key: c.LeafCID,
|
Data: rctBytes,
|
||||||
|
Key: c.LeafCID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rctIPLDs, nil
|
return rctIPLDs, nil
|
||||||
@@ -172,14 +194,19 @@ func (f *IPLDFetcher) FetchState(tx *sqlx.Tx, cids []models.StateNodeModel) ([]S
|
|||||||
if stateNode.CID == "" {
|
if stateNode.CID == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
stateBytes, err := shared.FetchIPLDByMhKey(tx, stateNode.MhKey)
|
blockNumber, err := strconv.ParseUint(stateNode.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stateBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, stateNode.MhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
stateNodes = append(stateNodes, StateNode{
|
stateNodes = append(stateNodes, StateNode{
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: stateBytes,
|
BlockNumber: stateNode.BlockNumber,
|
||||||
Key: stateNode.CID,
|
Data: stateBytes,
|
||||||
|
Key: stateNode.CID,
|
||||||
},
|
},
|
||||||
StateLeafKey: common.HexToHash(stateNode.StateKey),
|
StateLeafKey: common.HexToHash(stateNode.StateKey),
|
||||||
Type: ResolveToNodeType(stateNode.NodeType),
|
Type: ResolveToNodeType(stateNode.NodeType),
|
||||||
@@ -197,14 +224,19 @@ func (f *IPLDFetcher) FetchStorage(tx *sqlx.Tx, cids []models.StorageNodeWithSta
|
|||||||
if storageNode.CID == "" || storageNode.StateKey == "" {
|
if storageNode.CID == "" || storageNode.StateKey == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
storageBytes, err := shared.FetchIPLDByMhKey(tx, storageNode.MhKey)
|
blockNumber, err := strconv.ParseUint(storageNode.BlockNumber, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
storageBytes, err := shared.FetchIPLDByMhKeyAndBlockNumber(tx, storageNode.MhKey, blockNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
storageNodes = append(storageNodes, StorageNode{
|
storageNodes = append(storageNodes, StorageNode{
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: storageBytes,
|
BlockNumber: storageNode.BlockNumber,
|
||||||
Key: storageNode.CID,
|
Data: storageBytes,
|
||||||
|
Key: storageNode.CID,
|
||||||
},
|
},
|
||||||
StateLeafKey: common.HexToHash(storageNode.StateKey),
|
StateLeafKey: common.HexToHash(storageNode.StateKey),
|
||||||
StorageLeafKey: common.HexToHash(storageNode.StorageKey),
|
StorageLeafKey: common.HexToHash(storageNode.StorageKey),
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("IPLDFetcher", func() {
|
var _ = Describe("IPLDFetcher", func() {
|
||||||
@@ -39,8 +40,8 @@ var _ = Describe("IPLDFetcher", func() {
|
|||||||
err error
|
err error
|
||||||
tx interfaces.Batch
|
tx interfaces.Batch
|
||||||
)
|
)
|
||||||
db = eth.SetupTestDB()
|
db = shared.SetupDB()
|
||||||
pubAndIndexer = eth.SetupTestStateDiffIndexer(ctx, params.TestChainConfig, test_helpers.Genesis.Hash())
|
pubAndIndexer = shared.SetupTestStateDiffIndexer(ctx, params.TestChainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
tx, err = pubAndIndexer.PushBlock(test_helpers.MockBlock, test_helpers.MockReceipts, test_helpers.MockBlock.Difficulty())
|
tx, err = pubAndIndexer.PushBlock(test_helpers.MockBlock, test_helpers.MockReceipts, test_helpers.MockBlock.Difficulty())
|
||||||
for _, node := range test_helpers.MockStateNodes {
|
for _, node := range test_helpers.MockStateNodes {
|
||||||
@@ -54,7 +55,7 @@ var _ = Describe("IPLDFetcher", func() {
|
|||||||
|
|
||||||
})
|
})
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
eth.TearDownTestDB(db)
|
shared.TearDownDB(db)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("Fetches and returns IPLDs for the CIDs provided in the CIDWrapper", func() {
|
It("Fetches and returns IPLDs for the CIDs provided in the CIDWrapper", func() {
|
||||||
|
|||||||
+140
-39
@@ -36,93 +36,180 @@ const (
|
|||||||
|
|
||||||
RetrieveHeadersByHashesPgStr = `SELECT cid, data
|
RetrieveHeadersByHashesPgStr = `SELECT cid, data
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
header_cids.mh_key = blocks.key
|
||||||
|
AND header_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = ANY($1::VARCHAR(66)[])`
|
WHERE block_hash = ANY($1::VARCHAR(66)[])`
|
||||||
RetrieveHeadersByBlockNumberPgStr = `SELECT cid, data
|
RetrieveHeadersByBlockNumberPgStr = `SELECT cid, data
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
header_cids.mh_key = blocks.key
|
||||||
|
AND header_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_number = $1`
|
WHERE block_number = $1`
|
||||||
RetrieveHeaderByHashPgStr = `SELECT cid, data
|
RetrieveHeaderByHashPgStr = `SELECT cid, data
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
header_cids.mh_key = blocks.key
|
||||||
|
AND header_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = $1`
|
WHERE block_hash = $1`
|
||||||
RetrieveUnclesByHashesPgStr = `SELECT cid, data
|
RetrieveUnclesByHashesPgStr = `SELECT cid, data
|
||||||
FROM eth.uncle_cids
|
FROM eth.uncle_cids
|
||||||
INNER JOIN public.blocks ON (uncle_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
uncle_cids.mh_key = blocks.key
|
||||||
|
AND uncle_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = ANY($1::VARCHAR(66)[])`
|
WHERE block_hash = ANY($1::VARCHAR(66)[])`
|
||||||
RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data
|
RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data
|
||||||
FROM eth.uncle_cids
|
FROM eth.uncle_cids
|
||||||
INNER JOIN eth.header_cids ON (uncle_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (uncle_cids.mh_key = blocks.key)
|
uncle_cids.header_id = header_cids.block_hash
|
||||||
|
AND uncle_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
uncle_cids.mh_key = blocks.key
|
||||||
|
AND uncle_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = $1`
|
WHERE block_hash = $1`
|
||||||
RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data
|
RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data
|
||||||
FROM eth.uncle_cids
|
FROM eth.uncle_cids
|
||||||
INNER JOIN eth.header_cids ON (uncle_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (uncle_cids.mh_key = blocks.key)
|
uncle_cids.header_id = header_cids.block_hash
|
||||||
|
AND uncle_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
uncle_cids.mh_key = blocks.key
|
||||||
|
AND uncle_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_number = $1`
|
WHERE block_number = $1`
|
||||||
RetrieveUncleByHashPgStr = `SELECT cid, data
|
RetrieveUncleByHashPgStr = `SELECT cid, data
|
||||||
FROM eth.uncle_cids
|
FROM eth.uncle_cids
|
||||||
INNER JOIN public.blocks ON (uncle_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
uncle_cids.mh_key = blocks.key
|
||||||
|
AND uncle_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = $1`
|
WHERE block_hash = $1`
|
||||||
RetrieveTransactionsByHashesPgStr = `SELECT cid, data
|
RetrieveTransactionsByHashesPgStr = `SELECT cid, data
|
||||||
FROM eth.transaction_cids
|
FROM eth.transaction_cids
|
||||||
INNER JOIN public.blocks ON (transaction_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
transaction_cids.mh_key = blocks.key
|
||||||
|
AND transaction_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE tx_hash = ANY($1::VARCHAR(66)[])`
|
WHERE tx_hash = ANY($1::VARCHAR(66)[])`
|
||||||
RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data
|
RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data
|
||||||
FROM eth.transaction_cids
|
FROM eth.transaction_cids
|
||||||
INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (transaction_cids.mh_key = blocks.key)
|
transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
transaction_cids.mh_key = blocks.key
|
||||||
|
AND transaction_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = $1
|
WHERE block_hash = $1
|
||||||
ORDER BY eth.transaction_cids.index ASC`
|
ORDER BY eth.transaction_cids.index ASC`
|
||||||
RetrieveTransactionsByBlockNumberPgStr = `SELECT transaction_cids.cid, data
|
RetrieveTransactionsByBlockNumberPgStr = `SELECT transaction_cids.cid, data
|
||||||
FROM eth.transaction_cids
|
FROM eth.transaction_cids
|
||||||
INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (transaction_cids.mh_key = blocks.key)
|
transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
transaction_cids.mh_key = blocks.key
|
||||||
|
AND transaction_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_number = $1
|
WHERE block_number = $1
|
||||||
ORDER BY eth.transaction_cids.index ASC`
|
ORDER BY eth.transaction_cids.index ASC`
|
||||||
RetrieveTransactionByHashPgStr = `SELECT cid, data
|
RetrieveTransactionByHashPgStr = `SELECT cid, data
|
||||||
FROM eth.transaction_cids
|
FROM eth.transaction_cids
|
||||||
INNER JOIN public.blocks ON (transaction_cids.mh_key = blocks.key)
|
INNER JOIN public.blocks ON (
|
||||||
|
transaction_cids.mh_key = blocks.key
|
||||||
|
AND transaction_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE tx_hash = $1`
|
WHERE tx_hash = $1`
|
||||||
RetrieveReceiptsByTxHashesPgStr = `SELECT receipt_cids.leaf_cid, data
|
RetrieveReceiptsByTxHashesPgStr = `SELECT receipt_cids.leaf_cid, data
|
||||||
FROM eth.receipt_cids
|
FROM eth.receipt_cids
|
||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.tx_hash)
|
INNER JOIN eth.transaction_cids ON (
|
||||||
INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = blocks.key)
|
receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
receipt_cids.leaf_mh_key = blocks.key
|
||||||
|
AND receipt_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE tx_hash = ANY($1::VARCHAR(66)[])`
|
WHERE tx_hash = ANY($1::VARCHAR(66)[])`
|
||||||
RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash
|
RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash
|
||||||
FROM eth.receipt_cids
|
FROM eth.receipt_cids
|
||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.tx_hash)
|
INNER JOIN eth.transaction_cids ON (
|
||||||
INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash)
|
receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = blocks.key)
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
receipt_cids.leaf_mh_key = blocks.key
|
||||||
|
AND receipt_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_hash = $1
|
WHERE block_hash = $1
|
||||||
ORDER BY eth.transaction_cids.index ASC`
|
ORDER BY eth.transaction_cids.index ASC`
|
||||||
RetrieveReceiptsByBlockNumberPgStr = `SELECT receipt_cids.leaf_cid, data
|
RetrieveReceiptsByBlockNumberPgStr = `SELECT receipt_cids.leaf_cid, data
|
||||||
FROM eth.receipt_cids
|
FROM eth.receipt_cids
|
||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.tx_hash)
|
INNER JOIN eth.transaction_cids ON (
|
||||||
INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash)
|
receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = blocks.key)
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
transaction_cids.header_id = header_cids.block_hash
|
||||||
|
AND transaction_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
receipt_cids.leaf_mh_key = blocks.key
|
||||||
|
AND receipt_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE block_number = $1
|
WHERE block_number = $1
|
||||||
ORDER BY eth.transaction_cids.index ASC`
|
ORDER BY eth.transaction_cids.index ASC`
|
||||||
RetrieveReceiptByTxHashPgStr = `SELECT receipt_cids.leaf_cid, data
|
RetrieveReceiptByTxHashPgStr = `SELECT receipt_cids.leaf_cid, data
|
||||||
FROM eth.receipt_cids
|
FROM eth.receipt_cids
|
||||||
INNER JOIN eth.transaction_cids ON (receipt_cids.tx_id = transaction_cids.tx_hash)
|
INNER JOIN eth.transaction_cids ON (
|
||||||
INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = blocks.key)
|
receipt_cids.tx_id = transaction_cids.tx_hash
|
||||||
|
AND receipt_cids.block_number = transaction_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
receipt_cids.leaf_mh_key = blocks.key
|
||||||
|
AND receipt_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE tx_hash = $1`
|
WHERE tx_hash = $1`
|
||||||
RetrieveAccountByLeafKeyAndBlockHashPgStr = `SELECT state_cids.cid, data, state_cids.node_type
|
RetrieveAccountByLeafKeyAndBlockHashPgStr = `SELECT state_cids.cid, data, state_cids.node_type
|
||||||
FROM eth.state_cids
|
FROM eth.state_cids
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (state_cids.mh_key = blocks.key)
|
state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
state_cids.mh_key = blocks.key
|
||||||
|
AND state_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE state_leaf_key = $1
|
WHERE state_leaf_key = $1
|
||||||
AND block_number <= (SELECT block_number
|
AND header_cids.block_number <= (SELECT block_number
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
WHERE block_hash = $2)
|
WHERE block_hash = $2)
|
||||||
AND header_cids.block_hash = (SELECT canonical_header_hash(block_number))
|
AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
|
||||||
ORDER BY block_number DESC
|
ORDER BY header_cids.block_number DESC
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
RetrieveAccountByLeafKeyAndBlockNumberPgStr = `SELECT state_cids.cid, data, state_cids.node_type
|
RetrieveAccountByLeafKeyAndBlockNumberPgStr = `SELECT state_cids.cid, data, state_cids.node_type
|
||||||
FROM eth.state_cids
|
FROM eth.state_cids
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash)
|
INNER JOIN eth.header_cids ON (
|
||||||
INNER JOIN public.blocks ON (state_cids.mh_key = blocks.key)
|
state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
state_cids.mh_key = blocks.key
|
||||||
|
AND state_cids.block_number = blocks.block_number
|
||||||
|
)
|
||||||
WHERE state_leaf_key = $1
|
WHERE state_leaf_key = $1
|
||||||
AND block_number <= $2
|
AND block_number <= $2
|
||||||
ORDER BY block_number DESC
|
ORDER BY block_number DESC
|
||||||
@@ -132,9 +219,16 @@ const (
|
|||||||
INNER JOIN eth.state_cids ON (
|
INNER JOIN eth.state_cids ON (
|
||||||
storage_cids.header_id = state_cids.header_id
|
storage_cids.header_id = state_cids.header_id
|
||||||
AND storage_cids.state_path = state_cids.state_path
|
AND storage_cids.state_path = state_cids.state_path
|
||||||
|
AND storage_cids.block_number = state_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
storage_cids.mh_key = blocks.key
|
||||||
|
AND storage_cids.block_number = blocks.block_number
|
||||||
)
|
)
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash)
|
|
||||||
INNER JOIN public.blocks ON (storage_cids.mh_key = blocks.key)
|
|
||||||
WHERE state_leaf_key = $1
|
WHERE state_leaf_key = $1
|
||||||
AND storage_leaf_key = $2
|
AND storage_leaf_key = $2
|
||||||
AND block_number <= $3
|
AND block_number <= $3
|
||||||
@@ -145,16 +239,23 @@ const (
|
|||||||
INNER JOIN eth.state_cids ON (
|
INNER JOIN eth.state_cids ON (
|
||||||
storage_cids.header_id = state_cids.header_id
|
storage_cids.header_id = state_cids.header_id
|
||||||
AND storage_cids.state_path = state_cids.state_path
|
AND storage_cids.state_path = state_cids.state_path
|
||||||
|
AND storage_cids.block_number = state_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN eth.header_cids ON (
|
||||||
|
state_cids.header_id = header_cids.block_hash
|
||||||
|
AND state_cids.block_number = header_cids.block_number
|
||||||
|
)
|
||||||
|
INNER JOIN public.blocks ON (
|
||||||
|
storage_cids.mh_key = blocks.key
|
||||||
|
AND storage_cids.block_number = blocks.block_number
|
||||||
)
|
)
|
||||||
INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash)
|
|
||||||
INNER JOIN public.blocks ON (storage_cids.mh_key = blocks.key)
|
|
||||||
WHERE state_leaf_key = $1
|
WHERE state_leaf_key = $1
|
||||||
AND storage_leaf_key = $2
|
AND storage_leaf_key = $2
|
||||||
AND block_number <= (SELECT block_number
|
AND header_cids.block_number <= (SELECT block_number
|
||||||
FROM eth.header_cids
|
FROM eth.header_cids
|
||||||
WHERE block_hash = $3)
|
WHERE block_hash = $3)
|
||||||
AND header_cids.block_hash = (SELECT canonical_header_hash(block_number))
|
AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
|
||||||
ORDER BY block_number DESC
|
ORDER BY header_cids.block_number DESC
|
||||||
LIMIT 1`
|
LIMIT 1`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -17,67 +17,9 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer"
|
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
|
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/interfaces"
|
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/node"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetupTestDB() *sqlx.DB {
|
|
||||||
config := getTestDBConfig()
|
|
||||||
|
|
||||||
db, err := shared.NewDB(config.DbConnectionString(), config)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
return db
|
|
||||||
}
|
|
||||||
|
|
||||||
// TearDownTestDB is used to tear down the watcher dbs after tests
|
|
||||||
func TearDownTestDB(db *sqlx.DB) {
|
|
||||||
tx, err := db.Beginx()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM eth.transaction_cids`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM eth.receipt_cids`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM eth.state_cids`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM eth.storage_cids`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM blocks`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
_, err = tx.Exec(`DELETE FROM eth.log_cids`)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
err = tx.Commit()
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetupTestStateDiffIndexer(ctx context.Context, chainConfig *params.ChainConfig, genHash common.Hash) interfaces.StateDiffIndexer {
|
|
||||||
testInfo := node.Info{
|
|
||||||
GenesisBlock: genHash.String(),
|
|
||||||
NetworkID: "1",
|
|
||||||
ID: "1",
|
|
||||||
ClientName: "geth",
|
|
||||||
ChainID: params.TestChainConfig.ChainID.Uint64(),
|
|
||||||
}
|
|
||||||
|
|
||||||
stateDiffIndexer, err := indexer.NewStateDiffIndexer(ctx, chainConfig, testInfo, getTestDBConfig())
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
|
|
||||||
return stateDiffIndexer
|
|
||||||
}
|
|
||||||
|
|
||||||
// TxModelsContainsCID used to check if a list of TxModels contains a specific cid string
|
// TxModelsContainsCID used to check if a list of TxModels contains a specific cid string
|
||||||
func TxModelsContainsCID(txs []models.TxModel, cid string) bool {
|
func TxModelsContainsCID(txs []models.TxModel, cid string) bool {
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
@@ -97,15 +39,3 @@ func ReceiptModelsContainsCID(rcts []models.ReceiptModel, cid string) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestDBConfig() postgres.Config {
|
|
||||||
port, _ := strconv.Atoi(os.Getenv("DATABASE_PORT"))
|
|
||||||
return postgres.Config{
|
|
||||||
Hostname: os.Getenv("DATABASE_HOSTNAME"),
|
|
||||||
DatabaseName: os.Getenv("DATABASE_NAME"),
|
|
||||||
Username: os.Getenv("DATABASE_USER"),
|
|
||||||
Password: os.Getenv("DATABASE_PASSWORD"),
|
|
||||||
Port: port,
|
|
||||||
Driver: postgres.PGX,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import (
|
|||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Test variables
|
// Test variables
|
||||||
@@ -231,40 +231,44 @@ var (
|
|||||||
}
|
}
|
||||||
MockTrxMetaPostPublsh = []models.TxModel{
|
MockTrxMetaPostPublsh = []models.TxModel{
|
||||||
{
|
{
|
||||||
CID: Trx1CID.String(), // This is empty until we go to publish to ipfs
|
BlockNumber: "1",
|
||||||
MhKey: Trx1MhKey,
|
CID: Trx1CID.String(), // This is empty until we go to publish to ipfs
|
||||||
Src: SenderAddr.Hex(),
|
MhKey: Trx1MhKey,
|
||||||
Dst: Address.String(),
|
Src: SenderAddr.Hex(),
|
||||||
Index: 0,
|
Dst: Address.String(),
|
||||||
TxHash: MockTransactions[0].Hash().String(),
|
Index: 0,
|
||||||
Data: []byte{},
|
TxHash: MockTransactions[0].Hash().String(),
|
||||||
|
Data: []byte{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CID: Trx2CID.String(),
|
BlockNumber: "1",
|
||||||
MhKey: Trx2MhKey,
|
CID: Trx2CID.String(),
|
||||||
Src: SenderAddr.Hex(),
|
MhKey: Trx2MhKey,
|
||||||
Dst: AnotherAddress.String(),
|
Src: SenderAddr.Hex(),
|
||||||
Index: 1,
|
Dst: AnotherAddress.String(),
|
||||||
TxHash: MockTransactions[1].Hash().String(),
|
Index: 1,
|
||||||
Data: []byte{},
|
TxHash: MockTransactions[1].Hash().String(),
|
||||||
|
Data: []byte{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CID: Trx3CID.String(),
|
BlockNumber: "1",
|
||||||
MhKey: Trx3MhKey,
|
CID: Trx3CID.String(),
|
||||||
Src: SenderAddr.Hex(),
|
MhKey: Trx3MhKey,
|
||||||
Dst: "",
|
Src: SenderAddr.Hex(),
|
||||||
Index: 2,
|
Dst: "",
|
||||||
TxHash: MockTransactions[2].Hash().String(),
|
Index: 2,
|
||||||
Data: MockContractByteCode,
|
TxHash: MockTransactions[2].Hash().String(),
|
||||||
|
Data: MockContractByteCode,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CID: Trx4CID.String(),
|
BlockNumber: "1",
|
||||||
MhKey: Trx4MhKey,
|
CID: Trx4CID.String(),
|
||||||
Src: SenderAddr.Hex(),
|
MhKey: Trx4MhKey,
|
||||||
Dst: AnotherAddress1.String(),
|
Src: SenderAddr.Hex(),
|
||||||
Index: 3,
|
Dst: AnotherAddress1.String(),
|
||||||
TxHash: MockTransactions[3].Hash().String(),
|
Index: 3,
|
||||||
Data: []byte{},
|
TxHash: MockTransactions[3].Hash().String(),
|
||||||
|
Data: []byte{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
MockRctMeta = []models.ReceiptModel{
|
MockRctMeta = []models.ReceiptModel{
|
||||||
@@ -296,24 +300,28 @@ var (
|
|||||||
|
|
||||||
MockRctMetaPostPublish = []models.ReceiptModel{
|
MockRctMetaPostPublish = []models.ReceiptModel{
|
||||||
{
|
{
|
||||||
|
BlockNumber: "1",
|
||||||
LeafCID: Rct1CID.String(),
|
LeafCID: Rct1CID.String(),
|
||||||
LeafMhKey: Rct1MhKey,
|
LeafMhKey: Rct1MhKey,
|
||||||
Contract: "",
|
Contract: "",
|
||||||
ContractHash: "",
|
ContractHash: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
BlockNumber: "1",
|
||||||
LeafCID: Rct2CID.String(),
|
LeafCID: Rct2CID.String(),
|
||||||
LeafMhKey: Rct2MhKey,
|
LeafMhKey: Rct2MhKey,
|
||||||
Contract: "",
|
Contract: "",
|
||||||
ContractHash: "",
|
ContractHash: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
BlockNumber: "1",
|
||||||
LeafCID: Rct3CID.String(),
|
LeafCID: Rct3CID.String(),
|
||||||
LeafMhKey: Rct3MhKey,
|
LeafMhKey: Rct3MhKey,
|
||||||
Contract: ContractAddress.String(),
|
Contract: ContractAddress.String(),
|
||||||
ContractHash: ContractHash,
|
ContractHash: ContractHash,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
BlockNumber: "1",
|
||||||
LeafCID: Rct4CID.String(),
|
LeafCID: Rct4CID.String(),
|
||||||
LeafMhKey: Rct4MhKey,
|
LeafMhKey: Rct4MhKey,
|
||||||
Contract: "",
|
Contract: "",
|
||||||
@@ -326,7 +334,7 @@ var (
|
|||||||
StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes()
|
StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes()
|
||||||
StorageValue = crypto.Keccak256([]byte{1, 2, 3, 4, 5})
|
StorageValue = crypto.Keccak256([]byte{1, 2, 3, 4, 5})
|
||||||
StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
|
StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563")
|
||||||
StorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{
|
StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
|
||||||
StoragePartialPath,
|
StoragePartialPath,
|
||||||
StorageValue,
|
StorageValue,
|
||||||
})
|
})
|
||||||
@@ -336,14 +344,14 @@ var (
|
|||||||
ContractCodeHash = crypto.Keccak256Hash(MockContractByteCode)
|
ContractCodeHash = crypto.Keccak256Hash(MockContractByteCode)
|
||||||
contractPath = common.Bytes2Hex([]byte{'\x06'})
|
contractPath = common.Bytes2Hex([]byte{'\x06'})
|
||||||
ContractLeafKey = testhelpers.AddressToLeafKey(ContractAddress)
|
ContractLeafKey = testhelpers.AddressToLeafKey(ContractAddress)
|
||||||
ContractAccount, _ = rlp.EncodeToBytes(types.StateAccount{
|
ContractAccount, _ = rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: nonce1,
|
Nonce: nonce1,
|
||||||
Balance: big.NewInt(0),
|
Balance: big.NewInt(0),
|
||||||
CodeHash: ContractCodeHash.Bytes(),
|
CodeHash: ContractCodeHash.Bytes(),
|
||||||
Root: common.HexToHash(ContractRoot),
|
Root: common.HexToHash(ContractRoot),
|
||||||
})
|
})
|
||||||
ContractPartialPath = common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45")
|
ContractPartialPath = common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45")
|
||||||
ContractLeafNode, _ = rlp.EncodeToBytes([]interface{}{
|
ContractLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
|
||||||
ContractPartialPath,
|
ContractPartialPath,
|
||||||
ContractAccount,
|
ContractAccount,
|
||||||
})
|
})
|
||||||
@@ -354,14 +362,14 @@ var (
|
|||||||
AccountCodeHash = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
AccountCodeHash = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
|
||||||
AccountAddresss = common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e")
|
AccountAddresss = common.HexToAddress("0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e")
|
||||||
AccountLeafKey = testhelpers.Account2LeafKey
|
AccountLeafKey = testhelpers.Account2LeafKey
|
||||||
Account, _ = rlp.EncodeToBytes(types.StateAccount{
|
Account, _ = rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: nonce0,
|
Nonce: nonce0,
|
||||||
Balance: AccountBalance,
|
Balance: AccountBalance,
|
||||||
CodeHash: AccountCodeHash.Bytes(),
|
CodeHash: AccountCodeHash.Bytes(),
|
||||||
Root: common.HexToHash(AccountRoot),
|
Root: common.HexToHash(AccountRoot),
|
||||||
})
|
})
|
||||||
AccountPartialPath = common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45")
|
AccountPartialPath = common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45")
|
||||||
AccountLeafNode, _ = rlp.EncodeToBytes([]interface{}{
|
AccountLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{
|
||||||
AccountPartialPath,
|
AccountPartialPath,
|
||||||
Account,
|
Account,
|
||||||
})
|
})
|
||||||
@@ -391,18 +399,20 @@ var (
|
|||||||
}
|
}
|
||||||
MockStateMetaPostPublish = []models.StateNodeModel{
|
MockStateMetaPostPublish = []models.StateNodeModel{
|
||||||
{
|
{
|
||||||
CID: State1CID.String(),
|
BlockNumber: "1",
|
||||||
MhKey: State1MhKey,
|
CID: State1CID.String(),
|
||||||
Path: []byte{'\x06'},
|
MhKey: State1MhKey,
|
||||||
NodeType: 2,
|
Path: []byte{'\x06'},
|
||||||
StateKey: common.BytesToHash(ContractLeafKey).Hex(),
|
NodeType: 2,
|
||||||
|
StateKey: common.BytesToHash(ContractLeafKey).Hex(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
CID: State2CID.String(),
|
BlockNumber: "1",
|
||||||
MhKey: State2MhKey,
|
CID: State2CID.String(),
|
||||||
Path: []byte{'\x0c'},
|
MhKey: State2MhKey,
|
||||||
NodeType: 2,
|
Path: []byte{'\x0c'},
|
||||||
StateKey: common.BytesToHash(AccountLeafKey).Hex(),
|
NodeType: 2,
|
||||||
|
StateKey: common.BytesToHash(AccountLeafKey).Hex(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
MockStorageNodes = map[string][]sdtypes.StorageNode{
|
MockStorageNodes = map[string][]sdtypes.StorageNode{
|
||||||
@@ -461,12 +471,13 @@ var (
|
|||||||
StateNodes: MockStateMetaPostPublish,
|
StateNodes: MockStateMetaPostPublish,
|
||||||
StorageNodes: []models.StorageNodeWithStateKeyModel{
|
StorageNodes: []models.StorageNodeWithStateKeyModel{
|
||||||
{
|
{
|
||||||
Path: []byte{},
|
BlockNumber: "1",
|
||||||
CID: StorageCID.String(),
|
Path: []byte{},
|
||||||
MhKey: StorageMhKey,
|
CID: StorageCID.String(),
|
||||||
NodeType: 2,
|
MhKey: StorageMhKey,
|
||||||
StateKey: common.BytesToHash(ContractLeafKey).Hex(),
|
NodeType: 2,
|
||||||
StorageKey: common.BytesToHash(StorageLeafKey).Hex(),
|
StateKey: common.BytesToHash(ContractLeafKey).Hex(),
|
||||||
|
StorageKey: common.BytesToHash(StorageLeafKey).Hex(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -483,43 +494,52 @@ var (
|
|||||||
MockIPLDs = eth.IPLDs{
|
MockIPLDs = eth.IPLDs{
|
||||||
BlockNumber: new(big.Int).Set(BlockNumber),
|
BlockNumber: new(big.Int).Set(BlockNumber),
|
||||||
Header: models.IPLDModel{
|
Header: models.IPLDModel{
|
||||||
Data: HeaderIPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: HeaderIPLD.Cid().String(),
|
Data: HeaderIPLD.RawData(),
|
||||||
|
Key: HeaderIPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
Transactions: []models.IPLDModel{
|
Transactions: []models.IPLDModel{
|
||||||
{
|
{
|
||||||
Data: Trx1IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Trx1IPLD.Cid().String(),
|
Data: Trx1IPLD.RawData(),
|
||||||
|
Key: Trx1IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Trx2IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Trx2IPLD.Cid().String(),
|
Data: Trx2IPLD.RawData(),
|
||||||
|
Key: Trx2IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Trx3IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Trx3IPLD.Cid().String(),
|
Data: Trx3IPLD.RawData(),
|
||||||
|
Key: Trx3IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Trx4IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Trx4IPLD.Cid().String(),
|
Data: Trx4IPLD.RawData(),
|
||||||
|
Key: Trx4IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Receipts: []models.IPLDModel{
|
Receipts: []models.IPLDModel{
|
||||||
{
|
{
|
||||||
Data: Rct1IPLD,
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Rct1CID.String(),
|
Data: Rct1IPLD,
|
||||||
|
Key: Rct1CID.String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Rct2IPLD,
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Rct2CID.String(),
|
Data: Rct2IPLD,
|
||||||
|
Key: Rct2CID.String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Rct3IPLD,
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Rct3CID.String(),
|
Data: Rct3IPLD,
|
||||||
|
Key: Rct3CID.String(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Data: Rct4IPLD,
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: Rct4CID.String(),
|
Data: Rct4IPLD,
|
||||||
|
Key: Rct4CID.String(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
StateNodes: []eth.StateNode{
|
StateNodes: []eth.StateNode{
|
||||||
@@ -527,8 +547,9 @@ var (
|
|||||||
StateLeafKey: common.BytesToHash(ContractLeafKey),
|
StateLeafKey: common.BytesToHash(ContractLeafKey),
|
||||||
Type: sdtypes.Leaf,
|
Type: sdtypes.Leaf,
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: State1IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: State1IPLD.Cid().String(),
|
Data: State1IPLD.RawData(),
|
||||||
|
Key: State1IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
Path: []byte{'\x06'},
|
Path: []byte{'\x06'},
|
||||||
},
|
},
|
||||||
@@ -536,8 +557,9 @@ var (
|
|||||||
StateLeafKey: common.BytesToHash(AccountLeafKey),
|
StateLeafKey: common.BytesToHash(AccountLeafKey),
|
||||||
Type: sdtypes.Leaf,
|
Type: sdtypes.Leaf,
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: State2IPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: State2IPLD.Cid().String(),
|
Data: State2IPLD.RawData(),
|
||||||
|
Key: State2IPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
Path: []byte{'\x0c'},
|
Path: []byte{'\x0c'},
|
||||||
},
|
},
|
||||||
@@ -548,8 +570,9 @@ var (
|
|||||||
StorageLeafKey: common.BytesToHash(StorageLeafKey),
|
StorageLeafKey: common.BytesToHash(StorageLeafKey),
|
||||||
Type: sdtypes.Leaf,
|
Type: sdtypes.Leaf,
|
||||||
IPLD: models.IPLDModel{
|
IPLD: models.IPLDModel{
|
||||||
Data: StorageIPLD.RawData(),
|
BlockNumber: BlockNumber.String(),
|
||||||
Key: StorageIPLD.Cid().String(),
|
Data: StorageIPLD.RawData(),
|
||||||
|
Key: StorageIPLD.Cid().String(),
|
||||||
},
|
},
|
||||||
Path: []byte{},
|
Path: []byte{},
|
||||||
},
|
},
|
||||||
|
|||||||
+155
-7
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type StorageResponse struct {
|
type StorageResponse struct {
|
||||||
Cid string `json:"cid"`
|
CID string `json:"cid"`
|
||||||
Value common.Hash `json:"value"`
|
Value common.Hash `json:"value"`
|
||||||
IpldBlock hexutil.Bytes `json:"ipldBlock"`
|
IpldBlock hexutil.Bytes `json:"ipldBlock"`
|
||||||
}
|
}
|
||||||
@@ -21,14 +21,14 @@ type GetStorageAt struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LogResponse struct {
|
type LogResponse struct {
|
||||||
Topics []common.Hash `json:"topics"`
|
Topics []common.Hash `json:"topics"`
|
||||||
Data hexutil.Bytes `json:"data"`
|
Data hexutil.Bytes `json:"data"`
|
||||||
Transaction TransactionResp `json:"transaction"`
|
Transaction TransactionResponse `json:"transaction"`
|
||||||
ReceiptCID string `json:"receiptCID"`
|
ReceiptCID string `json:"receiptCID"`
|
||||||
Status int32 `json:"status"`
|
Status int32 `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionResp struct {
|
type TransactionResponse struct {
|
||||||
Hash common.Hash `json:"hash"`
|
Hash common.Hash `json:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +36,52 @@ type GetLogs struct {
|
|||||||
Responses []LogResponse `json:"getLogs"`
|
Responses []LogResponse `json:"getLogs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IPFSBlockResponse struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Data string `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCIDResponse struct {
|
||||||
|
CID string `json:"cid"`
|
||||||
|
TxHash string `json:"txHash"`
|
||||||
|
Index int32 `json:"index"`
|
||||||
|
Src string `json:"src"`
|
||||||
|
Dst string `json:"dst"`
|
||||||
|
BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCIDByTxHash struct {
|
||||||
|
Response EthTransactionCIDResponse `json:"ethTransactionCidByTxHash"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCIDsByHeaderIdResponse struct {
|
||||||
|
Nodes []EthTransactionCIDResponse `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCIDResponse struct {
|
||||||
|
CID string `json:"cid"`
|
||||||
|
BlockNumber BigInt `json:"blockNumber"`
|
||||||
|
BlockHash string `json:"blockHash"`
|
||||||
|
ParentHash string `json:"parentHash"`
|
||||||
|
Timestamp BigInt `json:"timestamp"`
|
||||||
|
StateRoot string `json:"stateRoot"`
|
||||||
|
Td BigInt `json:"td"`
|
||||||
|
TxRoot string `json:"txRoot"`
|
||||||
|
ReceiptRoot string `json:"receiptRoot"`
|
||||||
|
UncleRoot string `json:"uncleRoot"`
|
||||||
|
Bloom string `json:"bloom"`
|
||||||
|
EthTransactionCIDsByHeaderId EthTransactionCIDsByHeaderIdResponse `json:"ethTransactionCidsByHeaderId"`
|
||||||
|
BlockByMhKey IPFSBlockResponse `json:"blockByMhKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllEthHeaderCIDsResponse struct {
|
||||||
|
Nodes []EthHeaderCIDResponse `json:"nodes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllEthHeaderCIDs struct {
|
||||||
|
Response AllEthHeaderCIDsResponse `json:"allEthHeaderCids"`
|
||||||
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *gqlclient.Client
|
client *gqlclient.Client
|
||||||
}
|
}
|
||||||
@@ -117,3 +163,105 @@ func (c *Client) GetStorageAt(ctx context.Context, hash common.Hash, address com
|
|||||||
}
|
}
|
||||||
return &storageAt.Response, nil
|
return &storageAt.Response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) AllEthHeaderCIDs(ctx context.Context, condition EthHeaderCIDCondition) (*AllEthHeaderCIDsResponse, error) {
|
||||||
|
var params string
|
||||||
|
if condition.BlockHash != nil {
|
||||||
|
params = fmt.Sprintf(`blockHash: "%s"`, *condition.BlockHash)
|
||||||
|
}
|
||||||
|
if condition.BlockNumber != nil {
|
||||||
|
params += fmt.Sprintf(`blockNumber: "%s"`, condition.BlockNumber.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
getHeadersQuery := fmt.Sprintf(`
|
||||||
|
query{
|
||||||
|
allEthHeaderCids(condition: { %s }) {
|
||||||
|
nodes {
|
||||||
|
cid
|
||||||
|
blockNumber
|
||||||
|
blockHash
|
||||||
|
parentHash
|
||||||
|
timestamp
|
||||||
|
stateRoot
|
||||||
|
td
|
||||||
|
txRoot
|
||||||
|
receiptRoot
|
||||||
|
uncleRoot
|
||||||
|
bloom
|
||||||
|
blockByMhKey {
|
||||||
|
key
|
||||||
|
data
|
||||||
|
}
|
||||||
|
ethTransactionCidsByHeaderId {
|
||||||
|
nodes {
|
||||||
|
cid
|
||||||
|
txHash
|
||||||
|
index
|
||||||
|
src
|
||||||
|
dst
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, params)
|
||||||
|
|
||||||
|
req := gqlclient.NewRequest(getHeadersQuery)
|
||||||
|
req.Header.Set("Cache-Control", "no-cache")
|
||||||
|
|
||||||
|
var respData map[string]interface{}
|
||||||
|
err := c.client.Run(ctx, req, &respData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonStr, err := json.Marshal(respData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var allEthHeaderCIDs AllEthHeaderCIDs
|
||||||
|
err = json.Unmarshal(jsonStr, &allEthHeaderCIDs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &allEthHeaderCIDs.Response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) EthTransactionCIDByTxHash(ctx context.Context, txHash string) (*EthTransactionCIDResponse, error) {
|
||||||
|
getTxQuery := fmt.Sprintf(`
|
||||||
|
query{
|
||||||
|
ethTransactionCidByTxHash(txHash: "%s") {
|
||||||
|
cid
|
||||||
|
txHash
|
||||||
|
index
|
||||||
|
src
|
||||||
|
dst
|
||||||
|
blockByMhKey {
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, txHash)
|
||||||
|
|
||||||
|
req := gqlclient.NewRequest(getTxQuery)
|
||||||
|
req.Header.Set("Cache-Control", "no-cache")
|
||||||
|
|
||||||
|
var respData map[string]interface{}
|
||||||
|
err := c.client.Run(ctx, req, &respData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonStr, err := json.Marshal(respData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var ethTxCID EthTransactionCIDByTxHash
|
||||||
|
err = json.Unmarshal(jsonStr, ðTxCID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ðTxCID.Response, nil
|
||||||
|
}
|
||||||
|
|||||||
+245
-2
@@ -22,6 +22,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@@ -33,7 +34,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -1017,7 +1019,7 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Compare(rlpValue, eth.EmptyNodeValue) == 0 {
|
if bytes.Equal(rlpValue, eth.EmptyNodeValue) {
|
||||||
return &StorageResult{value: eth.EmptyNodeValue, cid: cid, ipldBlock: ipldBlock}, nil
|
return &StorageResult{value: eth.EmptyNodeValue, cid: cid, ipldBlock: ipldBlock}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,3 +1124,244 @@ func decomposeGQLLogs(logCIDs []eth.LogResult) []logsCID {
|
|||||||
|
|
||||||
return logs
|
return logs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EthTransactionCID struct {
|
||||||
|
cid string
|
||||||
|
txHash string
|
||||||
|
index int32
|
||||||
|
src string
|
||||||
|
dst string
|
||||||
|
ipfsBlock IPFSBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) Cid(ctx context.Context) string {
|
||||||
|
return t.cid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) TxHash(ctx context.Context) string {
|
||||||
|
return t.txHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) Index(ctx context.Context) int32 {
|
||||||
|
return t.index
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) Src(ctx context.Context) string {
|
||||||
|
return t.src
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) Dst(ctx context.Context) string {
|
||||||
|
return t.dst
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t EthTransactionCID) BlockByMhKey(ctx context.Context) IPFSBlock {
|
||||||
|
return t.ipfsBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCIDsConnection struct {
|
||||||
|
nodes []*EthTransactionCID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (transactionCIDResult EthTransactionCIDsConnection) Nodes(ctx context.Context) []*EthTransactionCID {
|
||||||
|
return transactionCIDResult.nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPFSBlock struct {
|
||||||
|
key string
|
||||||
|
data string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b IPFSBlock) Key(ctx context.Context) string {
|
||||||
|
return b.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b IPFSBlock) Data(ctx context.Context) string {
|
||||||
|
return b.data
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCID struct {
|
||||||
|
cid string
|
||||||
|
blockNumber BigInt
|
||||||
|
blockHash string
|
||||||
|
parentHash string
|
||||||
|
timestamp BigInt
|
||||||
|
stateRoot string
|
||||||
|
td BigInt
|
||||||
|
txRoot string
|
||||||
|
receiptRoot string
|
||||||
|
uncleRoot string
|
||||||
|
bloom string
|
||||||
|
transactions []*EthTransactionCID
|
||||||
|
ipfsBlock IPFSBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) Cid(ctx context.Context) string {
|
||||||
|
return h.cid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) BlockNumber(ctx context.Context) BigInt {
|
||||||
|
return h.blockNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) BlockHash(ctx context.Context) string {
|
||||||
|
return h.blockHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) ParentHash(ctx context.Context) string {
|
||||||
|
return h.parentHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) Timestamp(ctx context.Context) BigInt {
|
||||||
|
return h.timestamp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) StateRoot(ctx context.Context) string {
|
||||||
|
return h.stateRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) Td(ctx context.Context) BigInt {
|
||||||
|
return h.td
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) TxRoot(ctx context.Context) string {
|
||||||
|
return h.txRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) ReceiptRoot(ctx context.Context) string {
|
||||||
|
return h.receiptRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) UncleRoot(ctx context.Context) string {
|
||||||
|
return h.uncleRoot
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) Bloom(ctx context.Context) string {
|
||||||
|
return h.bloom
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) EthTransactionCidsByHeaderId(ctx context.Context) EthTransactionCIDsConnection {
|
||||||
|
return EthTransactionCIDsConnection{nodes: h.transactions}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h EthHeaderCID) BlockByMhKey(ctx context.Context) IPFSBlock {
|
||||||
|
return h.ipfsBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCIDsConnection struct {
|
||||||
|
nodes []*EthHeaderCID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (headerCIDResult EthHeaderCIDsConnection) Nodes(ctx context.Context) []*EthHeaderCID {
|
||||||
|
return headerCIDResult.nodes
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCIDCondition struct {
|
||||||
|
BlockNumber *BigInt
|
||||||
|
BlockHash *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) AllEthHeaderCids(ctx context.Context, args struct {
|
||||||
|
Condition *EthHeaderCIDCondition
|
||||||
|
}) (*EthHeaderCIDsConnection, error) {
|
||||||
|
var headerCIDs []eth.HeaderCIDRecord
|
||||||
|
var err error
|
||||||
|
if args.Condition.BlockHash != nil {
|
||||||
|
headerCID, err := r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(common.HexToHash(*args.Condition.BlockHash))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
headerCIDs = append(headerCIDs, headerCID)
|
||||||
|
} else if args.Condition.BlockNumber != nil {
|
||||||
|
headerCIDs, err = r.backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(args.Condition.BlockNumber.ToInt().Int64())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("provide block number or block hash")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin tx
|
||||||
|
tx, err := r.backend.DB.Beginx()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if p := recover(); p != nil {
|
||||||
|
shared.Rollback(tx)
|
||||||
|
panic(p)
|
||||||
|
} else if err != nil {
|
||||||
|
shared.Rollback(tx)
|
||||||
|
} else {
|
||||||
|
err = tx.Commit()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
var resultNodes []*EthHeaderCID
|
||||||
|
for _, headerCID := range headerCIDs {
|
||||||
|
var blockNumber BigInt
|
||||||
|
blockNumber.UnmarshalText([]byte(headerCID.BlockNumber))
|
||||||
|
|
||||||
|
var timestamp BigInt
|
||||||
|
timestamp.SetUint64(headerCID.Timestamp)
|
||||||
|
|
||||||
|
var td BigInt
|
||||||
|
td.UnmarshalText([]byte(headerCID.TotalDifficulty))
|
||||||
|
|
||||||
|
ethHeaderCIDNode := EthHeaderCID{
|
||||||
|
cid: headerCID.CID,
|
||||||
|
blockNumber: blockNumber,
|
||||||
|
blockHash: headerCID.BlockHash,
|
||||||
|
parentHash: headerCID.ParentHash,
|
||||||
|
timestamp: timestamp,
|
||||||
|
stateRoot: headerCID.StateRoot,
|
||||||
|
td: td,
|
||||||
|
txRoot: headerCID.TxRoot,
|
||||||
|
receiptRoot: headerCID.RctRoot,
|
||||||
|
uncleRoot: headerCID.UncleRoot,
|
||||||
|
bloom: Bytes(headerCID.Bloom).String(),
|
||||||
|
ipfsBlock: IPFSBlock{
|
||||||
|
key: headerCID.IPLD.Key,
|
||||||
|
data: Bytes(headerCID.IPLD.Data).String(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, txCID := range headerCID.TransactionCIDs {
|
||||||
|
ethHeaderCIDNode.transactions = append(ethHeaderCIDNode.transactions, &EthTransactionCID{
|
||||||
|
cid: txCID.CID,
|
||||||
|
txHash: txCID.TxHash,
|
||||||
|
index: int32(txCID.Index),
|
||||||
|
src: txCID.Src,
|
||||||
|
dst: txCID.Dst,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
resultNodes = append(resultNodes, ðHeaderCIDNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &EthHeaderCIDsConnection{
|
||||||
|
nodes: resultNodes,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) EthTransactionCidByTxHash(ctx context.Context, args struct {
|
||||||
|
TxHash string
|
||||||
|
}) (*EthTransactionCID, error) {
|
||||||
|
txCID, err := r.backend.Retriever.RetrieveTxCIDByHash(args.TxHash)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &EthTransactionCID{
|
||||||
|
cid: txCID.CID,
|
||||||
|
txHash: txCID.TxHash,
|
||||||
|
index: int32(txCID.Index),
|
||||||
|
src: txCID.Src,
|
||||||
|
dst: txCID.Dst,
|
||||||
|
ipfsBlock: IPFSBlock{
|
||||||
|
key: txCID.IPLD.Key,
|
||||||
|
data: Bytes(txCID.IPLD.Data).String(),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
+92
-10
@@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
@@ -35,10 +36,11 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth/test_helpers"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth/test_helpers"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/graphql"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/graphql"
|
||||||
ethServerShared "github.com/vulcanize/ipld-eth-server/pkg/shared"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
|
ethServerShared "github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("GraphQL", func() {
|
var _ = Describe("GraphQL", func() {
|
||||||
@@ -65,8 +67,8 @@ var _ = Describe("GraphQL", func() {
|
|||||||
|
|
||||||
It("test init", func() {
|
It("test init", func() {
|
||||||
var err error
|
var err error
|
||||||
db = eth.SetupTestDB()
|
db = shared.SetupDB()
|
||||||
transformer := eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
transformer := shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
backend, err = eth.NewEthBackend(db, ð.Config{
|
backend, err = eth.NewEthBackend(db, ð.Config{
|
||||||
ChainConfig: chainConfig,
|
ChainConfig: chainConfig,
|
||||||
@@ -130,7 +132,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert some non-canonical data into the database so that we test our ability to discern canonicity
|
// Insert some non-canonical data into the database so that we test our ability to discern canonicity
|
||||||
indexAndPublisher := eth.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
indexAndPublisher := shared.SetupTestStateDiffIndexer(ctx, chainConfig, test_helpers.Genesis.Hash())
|
||||||
|
|
||||||
blockHash = test_helpers.MockBlock.Hash()
|
blockHash = test_helpers.MockBlock.Hash()
|
||||||
contractAddress = test_helpers.ContractAddr
|
contractAddress = test_helpers.ContractAddr
|
||||||
@@ -166,7 +168,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
defer It("test teardown", func() {
|
defer It("test teardown", func() {
|
||||||
err := graphQLServer.Stop()
|
err := graphQLServer.Stop()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
eth.TearDownTestDB(db)
|
shared.TearDownDB(db)
|
||||||
chain.Stop()
|
chain.Stop()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -179,7 +181,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
{
|
{
|
||||||
Topics: test_helpers.MockLog1.Topics,
|
Topics: test_helpers.MockLog1.Topics,
|
||||||
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
|
Data: hexutil.Bytes(test_helpers.MockLog1.Data),
|
||||||
Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[0].Hash()},
|
Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[0].Hash()},
|
||||||
ReceiptCID: test_helpers.Rct1CID.String(),
|
ReceiptCID: test_helpers.Rct1CID.String(),
|
||||||
Status: int32(test_helpers.MockReceipts[0].Status),
|
Status: int32(test_helpers.MockReceipts[0].Status),
|
||||||
},
|
},
|
||||||
@@ -196,7 +198,7 @@ var _ = Describe("GraphQL", func() {
|
|||||||
{
|
{
|
||||||
Topics: test_helpers.MockLog6.Topics,
|
Topics: test_helpers.MockLog6.Topics,
|
||||||
Data: hexutil.Bytes(test_helpers.MockLog6.Data),
|
Data: hexutil.Bytes(test_helpers.MockLog6.Data),
|
||||||
Transaction: graphql.TransactionResp{Hash: test_helpers.MockTransactions[3].Hash()},
|
Transaction: graphql.TransactionResponse{Hash: test_helpers.MockTransactions[3].Hash()},
|
||||||
ReceiptCID: test_helpers.Rct4CID.String(),
|
ReceiptCID: test_helpers.Rct4CID.String(),
|
||||||
Status: int32(test_helpers.MockReceipts[3].Status),
|
Status: int32(test_helpers.MockReceipts[3].Status),
|
||||||
},
|
},
|
||||||
@@ -249,4 +251,84 @@ var _ = Describe("GraphQL", func() {
|
|||||||
Expect(storageRes.Value).To(Equal(common.Hash{}))
|
Expect(storageRes.Value).To(Equal(common.Hash{}))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Describe("allEthHeaderCids", func() {
|
||||||
|
It("Retrieves header_cids that matches the provided blockNumber", func() {
|
||||||
|
allEthHeaderCIDsResp, err := client.AllEthHeaderCIDs(ctx, graphql.EthHeaderCIDCondition{BlockNumber: new(graphql.BigInt).SetUint64(2)})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
headerCIDs, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockNumber(2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
for idx, headerCID := range headerCIDs {
|
||||||
|
ethHeaderCID := allEthHeaderCIDsResp.Nodes[idx]
|
||||||
|
|
||||||
|
compareEthHeaderCID(ethHeaderCID, headerCID)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("Retrieves header_cids that matches the provided blockHash", func() {
|
||||||
|
blockHash := blocks[1].Hash().String()
|
||||||
|
allEthHeaderCIDsResp, err := client.AllEthHeaderCIDs(ctx, graphql.EthHeaderCIDCondition{BlockHash: &blockHash})
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
headerCID, err := backend.Retriever.RetrieveHeaderAndTxCIDsByBlockHash(blocks[1].Hash())
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(len(allEthHeaderCIDsResp.Nodes)).To(Equal(1))
|
||||||
|
ethHeaderCID := allEthHeaderCIDsResp.Nodes[0]
|
||||||
|
compareEthHeaderCID(ethHeaderCID, headerCID)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("ethTransactionCidByTxHash", func() {
|
||||||
|
It("Retrieves tx_cid that matches the provided txHash", func() {
|
||||||
|
txHash := blocks[2].Transactions()[0].Hash().String()
|
||||||
|
ethTransactionCIDResp, err := client.EthTransactionCIDByTxHash(ctx, txHash)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
txCID, err := backend.Retriever.RetrieveTxCIDByHash(txHash)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
compareEthTxCID(*ethTransactionCIDResp, txCID)
|
||||||
|
|
||||||
|
Expect(ethTransactionCIDResp.BlockByMhKey.Data).To(Equal(graphql.Bytes(txCID.IPLD.Data).String()))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
func compareEthHeaderCID(ethHeaderCID graphql.EthHeaderCIDResponse, headerCID eth.HeaderCIDRecord) {
|
||||||
|
blockNumber, err := strconv.ParseInt(headerCID.BlockNumber, 10, 64)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
td, err := strconv.ParseInt(headerCID.TotalDifficulty, 10, 64)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(ethHeaderCID.CID).To(Equal(headerCID.CID))
|
||||||
|
Expect(ethHeaderCID.BlockNumber).To(Equal(*new(graphql.BigInt).SetUint64(uint64(blockNumber))))
|
||||||
|
Expect(ethHeaderCID.BlockHash).To(Equal(headerCID.BlockHash))
|
||||||
|
Expect(ethHeaderCID.ParentHash).To(Equal(headerCID.ParentHash))
|
||||||
|
Expect(ethHeaderCID.Timestamp).To(Equal(*new(graphql.BigInt).SetUint64(headerCID.Timestamp)))
|
||||||
|
Expect(ethHeaderCID.StateRoot).To(Equal(headerCID.StateRoot))
|
||||||
|
Expect(ethHeaderCID.Td).To(Equal(*new(graphql.BigInt).SetUint64(uint64(td))))
|
||||||
|
Expect(ethHeaderCID.TxRoot).To(Equal(headerCID.TxRoot))
|
||||||
|
Expect(ethHeaderCID.ReceiptRoot).To(Equal(headerCID.RctRoot))
|
||||||
|
Expect(ethHeaderCID.UncleRoot).To(Equal(headerCID.UncleRoot))
|
||||||
|
Expect(ethHeaderCID.Bloom).To(Equal(graphql.Bytes(headerCID.Bloom).String()))
|
||||||
|
|
||||||
|
for tIdx, txCID := range headerCID.TransactionCIDs {
|
||||||
|
ethTxCID := ethHeaderCID.EthTransactionCIDsByHeaderId.Nodes[tIdx]
|
||||||
|
compareEthTxCID(ethTxCID, txCID)
|
||||||
|
}
|
||||||
|
|
||||||
|
Expect(ethHeaderCID.BlockByMhKey.Data).To(Equal(graphql.Bytes(headerCID.IPLD.Data).String()))
|
||||||
|
Expect(ethHeaderCID.BlockByMhKey.Key).To(Equal(headerCID.IPLD.Key))
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareEthTxCID(ethTxCID graphql.EthTransactionCIDResponse, txCID eth.TransactionCIDRecord) {
|
||||||
|
Expect(ethTxCID.CID).To(Equal(txCID.CID))
|
||||||
|
Expect(ethTxCID.TxHash).To(Equal(txCID.TxHash))
|
||||||
|
Expect(ethTxCID.Index).To(Equal(int32(txCID.Index)))
|
||||||
|
Expect(ethTxCID.Src).To(Equal(txCID.Src))
|
||||||
|
Expect(ethTxCID.Dst).To(Equal(txCID.Dst))
|
||||||
|
}
|
||||||
|
|||||||
+70
-22
@@ -25,8 +25,7 @@ const schema string = `
|
|||||||
# An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles.
|
# An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles.
|
||||||
scalar Bytes
|
scalar Bytes
|
||||||
# BigInt is a large integer. Input is accepted as either a JSON number or as a string.
|
# BigInt is a large integer. Input is accepted as either a JSON number or as a string.
|
||||||
# Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all
|
# Input and output strings may be either decimal or 0x-prefixed hexadecimal depending upon the resolver implementation.
|
||||||
# 0x-prefixed hexadecimal.
|
|
||||||
scalar BigInt
|
scalar BigInt
|
||||||
# Long is a 64 bit unsigned integer.
|
# Long is a 64 bit unsigned integer.
|
||||||
scalar Long
|
scalar Long
|
||||||
@@ -138,16 +137,16 @@ const schema string = `
|
|||||||
# empty, results will not be filtered by address.
|
# empty, results will not be filtered by address.
|
||||||
addresses: [Address!]
|
addresses: [Address!]
|
||||||
# Topics list restricts matches to particular event topics. Each event has a list
|
# Topics list restricts matches to particular event topics. Each event has a list
|
||||||
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
||||||
# topic. Non-empty elements represent an alternative that matches any of the
|
# topic. Non-empty elements represent an alternative that matches any of the
|
||||||
# contained topics.
|
# contained topics.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
# - [] or nil matches any topic list
|
# - [] or nil matches any topic list
|
||||||
# - [[A]] matches topic A in first position
|
# - [[A]] matches topic A in first position
|
||||||
# - [[], [B]] matches any topic in first position, B in second position
|
# - [[], [B]] matches any topic in first position, B in second position
|
||||||
# - [[A], [B]] matches topic A in first position, B in second position
|
# - [[A], [B]] matches topic A in first position, B in second position
|
||||||
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
||||||
topics: [[Bytes32!]!]
|
topics: [[Bytes32!]!]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,16 +257,16 @@ const schema string = `
|
|||||||
# empty, results will not be filtered by address.
|
# empty, results will not be filtered by address.
|
||||||
addresses: [Address!]
|
addresses: [Address!]
|
||||||
# Topics list restricts matches to particular event topics. Each event has a list
|
# Topics list restricts matches to particular event topics. Each event has a list
|
||||||
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
||||||
# topic. Non-empty elements represent an alternative that matches any of the
|
# topic. Non-empty elements represent an alternative that matches any of the
|
||||||
# contained topics.
|
# contained topics.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
# - [] or nil matches any topic list
|
# - [] or nil matches any topic list
|
||||||
# - [[A]] matches topic A in first position
|
# - [[A]] matches topic A in first position
|
||||||
# - [[], [B]] matches any topic in first position, B in second position
|
# - [[], [B]] matches any topic in first position, B in second position
|
||||||
# - [[A], [B]] matches topic A in first position, B in second position
|
# - [[A], [B]] matches topic A in first position, B in second position
|
||||||
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
||||||
topics: [[Bytes32!]!]
|
topics: [[Bytes32!]!]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,6 +281,49 @@ const schema string = `
|
|||||||
ipldBlock: Bytes!
|
ipldBlock: Bytes!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input EthHeaderCidCondition {
|
||||||
|
blockNumber: BigInt
|
||||||
|
blockHash: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCid {
|
||||||
|
cid: String!
|
||||||
|
txHash: String!
|
||||||
|
index: Int!
|
||||||
|
src: String!
|
||||||
|
dst: String!
|
||||||
|
blockByMhKey: IPFSBlock!
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthTransactionCidsConnection {
|
||||||
|
nodes: [EthTransactionCid]!
|
||||||
|
}
|
||||||
|
|
||||||
|
type IPFSBlock {
|
||||||
|
key: String!
|
||||||
|
data: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCid {
|
||||||
|
cid: String!
|
||||||
|
blockNumber: BigInt!
|
||||||
|
blockHash: String!
|
||||||
|
parentHash: String!
|
||||||
|
timestamp: BigInt!
|
||||||
|
stateRoot: String!
|
||||||
|
td: BigInt!
|
||||||
|
txRoot: String!
|
||||||
|
receiptRoot: String!
|
||||||
|
uncleRoot: String!
|
||||||
|
bloom: String!
|
||||||
|
ethTransactionCidsByHeaderId: EthTransactionCidsConnection!
|
||||||
|
blockByMhKey: IPFSBlock!
|
||||||
|
}
|
||||||
|
|
||||||
|
type EthHeaderCidsConnection {
|
||||||
|
nodes: [EthHeaderCid]!
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
# Block fetches an Ethereum block by number or by hash. If neither is
|
# Block fetches an Ethereum block by number or by hash. If neither is
|
||||||
# supplied, the most recent known block is returned.
|
# supplied, the most recent known block is returned.
|
||||||
@@ -302,5 +344,11 @@ const schema string = `
|
|||||||
|
|
||||||
# Get contract logs by block hash and contract address.
|
# Get contract logs by block hash and contract address.
|
||||||
getLogs(blockHash: Bytes32!, contract: Address): [Log!]
|
getLogs(blockHash: Bytes32!, contract: Address): [Log!]
|
||||||
|
|
||||||
|
# PostGraphile alternative to get headers with transactions using block number or block hash.
|
||||||
|
allEthHeaderCids(condition: EthHeaderCidCondition): EthHeaderCidsConnection
|
||||||
|
|
||||||
|
# PostGraphile alternative to get transactions using transaction hash.
|
||||||
|
ethTransactionCidByTxHash(txHash: String!): EthTransactionCid
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import (
|
|||||||
"github.com/graph-gophers/graphql-go/relay"
|
"github.com/graph-gophers/graphql-go/relay"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service encapsulates a GraphQL service.
|
// Service encapsulates a GraphQL service.
|
||||||
@@ -69,7 +69,7 @@ func (s *Service) Start(server *p2p.Server) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := node.NewHTTPHandlerStack(s.handler, s.cors, s.vhosts)
|
handler := node.NewHTTPHandlerStack(s.handler, s.cors, s.vhosts, nil)
|
||||||
|
|
||||||
// start http server
|
// start http server
|
||||||
_, addr, err := node.StartHTTPEndpoint(s.endpoint, rpc.DefaultHTTPTimeouts, handler)
|
_, addr, err := node.StartHTTPEndpoint(s.endpoint, rpc.DefaultHTTPTimeouts, handler)
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
// VulcanizeDB
|
||||||
|
// Copyright © 2022 Vulcanize
|
||||||
|
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package graphql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bytes marshals as a JSON string with \x prefix.
|
||||||
|
// The empty slice marshals as "\x".
|
||||||
|
type Bytes []byte
|
||||||
|
|
||||||
|
// MarshalText implements encoding.TextMarshaler
|
||||||
|
func (b Bytes) MarshalText() ([]byte, error) {
|
||||||
|
result := make([]byte, len(b)*2+2)
|
||||||
|
copy(result, `\x`)
|
||||||
|
hex.Encode(result[2:], b)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the hex encoding of b.
|
||||||
|
func (b Bytes) String() string {
|
||||||
|
return b.encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode encodes b as a hex string with "\x" prefix.
|
||||||
|
// This is to make the output to be the same as given by postgraphile.
|
||||||
|
// graphql-go prepends another "\" to the output resulting in prefix "\\x".
|
||||||
|
func (b Bytes) encode() string {
|
||||||
|
result := make([]byte, len(b)*2+2)
|
||||||
|
copy(result, `\x`)
|
||||||
|
hex.Encode(result[2:], b)
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
type BigInt big.Int
|
||||||
|
|
||||||
|
// ToInt converts b to a big.Int.
|
||||||
|
func (b *BigInt) ToInt() *big.Int {
|
||||||
|
return (*big.Int)(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns value of b as a decimal string.
|
||||||
|
func (b *BigInt) String() string {
|
||||||
|
return b.ToInt().String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetUint64 sets b to x and returns x.
|
||||||
|
func (b *BigInt) SetUint64(x uint64) *BigInt {
|
||||||
|
var val big.Int
|
||||||
|
val.SetUint64(x)
|
||||||
|
*b = (BigInt)(val)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText implements encoding.TextMarshaler
|
||||||
|
func (b BigInt) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(b.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText implements encoding.TextUnmarshaler
|
||||||
|
func (b *BigInt) UnmarshalText(input []byte) error {
|
||||||
|
raw, err := checkNumberText(input)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(raw) > 64 {
|
||||||
|
return hexutil.ErrBig256Range
|
||||||
|
}
|
||||||
|
|
||||||
|
var val big.Int
|
||||||
|
val.SetString(string(input[:]), 10)
|
||||||
|
*b = (BigInt)(val)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if BigInt implements the provided GraphQL type.
|
||||||
|
func (b BigInt) ImplementsGraphQLType(name string) bool { return name == "BigInt" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
|
func (b *BigInt) UnmarshalGraphQL(input interface{}) error {
|
||||||
|
var err error
|
||||||
|
switch input := input.(type) {
|
||||||
|
case string:
|
||||||
|
return b.UnmarshalText([]byte(input))
|
||||||
|
case int32:
|
||||||
|
var num big.Int
|
||||||
|
num.SetInt64(int64(input))
|
||||||
|
*b = BigInt(num)
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unexpected type %T for BigInt", input)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkNumberText(input []byte) (raw []byte, err error) {
|
||||||
|
if len(input) == 0 {
|
||||||
|
return nil, nil // empty strings are allowed
|
||||||
|
}
|
||||||
|
if len(input) > 1 && input[0] == '0' {
|
||||||
|
return nil, hexutil.ErrLeadingZero
|
||||||
|
}
|
||||||
|
return input, nil
|
||||||
|
}
|
||||||
+1
-1
@@ -20,7 +20,7 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/net"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("API", func() {
|
var _ = Describe("API", func() {
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ func StartHTTPEndpoint(endpoint string, apis []rpc.API, modules []string, cors [
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Fatalf("Could not register HTTP API: %w", err)
|
utils.Fatalf("Could not register HTTP API: %w", err)
|
||||||
}
|
}
|
||||||
handler := node.NewHTTPHandlerStack(srv, cors, vhosts)
|
handler := node.NewHTTPHandlerStack(srv, cors, vhosts, nil)
|
||||||
|
|
||||||
// start http server
|
// start http server
|
||||||
_, addr, err := node.StartHTTPEndpoint(endpoint, rpc.DefaultHTTPTimeouts, handler)
|
_, addr, err := node.StartHTTPEndpoint(endpoint, rpc.DefaultHTTPTimeouts, handler)
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/prom"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/prom"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/node"
|
"github.com/ethereum/go-ethereum/node"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/prom"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/prom"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StartWSEndpoint starts a websocket endpoint.
|
// StartWSEndpoint starts a websocket endpoint.
|
||||||
|
|||||||
+17
-4
@@ -20,9 +20,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIName is the namespace used for the state diffing service API
|
// APIName is the namespace used for the state diffing service API
|
||||||
@@ -33,13 +34,15 @@ const APIVersion = "0.0.1"
|
|||||||
|
|
||||||
// PublicServerAPI is the public api for the watcher
|
// PublicServerAPI is the public api for the watcher
|
||||||
type PublicServerAPI struct {
|
type PublicServerAPI struct {
|
||||||
w Server
|
w Server
|
||||||
|
rpc *rpc.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPublicServerAPI creates a new PublicServerAPI with the provided underlying Server process
|
// NewPublicServerAPI creates a new PublicServerAPI with the provided underlying Server process
|
||||||
func NewPublicServerAPI(w Server) *PublicServerAPI {
|
func NewPublicServerAPI(w Server, client *rpc.Client) *PublicServerAPI {
|
||||||
return &PublicServerAPI{
|
return &PublicServerAPI{
|
||||||
w: w,
|
w: w,
|
||||||
|
rpc: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,3 +84,13 @@ func (api *PublicServerAPI) Stream(ctx context.Context, params eth.SubscriptionS
|
|||||||
|
|
||||||
return rpcSub, nil
|
return rpcSub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WatchAddress makes a geth WatchAddress API call with the given operation and args
|
||||||
|
func (api *PublicServerAPI) WatchAddress(operation types.OperationType, args []types.WatchAddressArg) error {
|
||||||
|
err := api.rpc.Call(nil, "statediff_watchAddress", operation, args)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
+6
-7
@@ -27,14 +27,13 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
|
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/prom"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/prom"
|
ethServerShared "github.com/vulcanize/ipld-eth-server/v4/pkg/shared"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/shared"
|
|
||||||
ethServerShared "github.com/vulcanize/ipld-eth-server/pkg/shared"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Env variables
|
// Env variables
|
||||||
@@ -202,7 +201,7 @@ func NewConfig() (*Config, error) {
|
|||||||
c.IpldGraphqlEnabled = ipldGraphqlEnabled
|
c.IpldGraphqlEnabled = ipldGraphqlEnabled
|
||||||
|
|
||||||
overrideDBConnConfig(&c.DBConfig)
|
overrideDBConnConfig(&c.DBConfig)
|
||||||
serveDB, err := shared.NewDB(c.DBConfig.DbConnectionString(), c.DBConfig)
|
serveDB, err := ethServerShared.NewDB(c.DBConfig.DbConnectionString(), c.DBConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -223,9 +222,9 @@ func NewConfig() (*Config, error) {
|
|||||||
}
|
}
|
||||||
chainConfigPath := viper.GetString("ethereum.chainConfig")
|
chainConfigPath := viper.GetString("ethereum.chainConfig")
|
||||||
if chainConfigPath != "" {
|
if chainConfigPath != "" {
|
||||||
c.ChainConfig, err = eth.LoadConfig(chainConfigPath)
|
c.ChainConfig, err = statediff.LoadConfig(chainConfigPath)
|
||||||
} else {
|
} else {
|
||||||
c.ChainConfig, err = eth.ChainConfig(nodeInfo.ChainID)
|
c.ChainConfig, err = statediff.ChainConfig(nodeInfo.ChainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.loadGroupCacheConfig()
|
c.loadGroupCacheConfig()
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import (
|
|||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/net"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -129,7 +129,7 @@ func (sap *Service) APIs() []rpc.API {
|
|||||||
{
|
{
|
||||||
Namespace: APIName,
|
Namespace: APIName,
|
||||||
Version: APIVersion,
|
Version: APIVersion,
|
||||||
Service: NewPublicServerAPI(sap),
|
Service: NewPublicServerAPI(sap, sap.client),
|
||||||
Public: true,
|
Public: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-38
@@ -18,11 +18,9 @@ package shared
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/ipld"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
dshelp "github.com/ipfs/go-ipfs-ds-help"
|
dshelp "github.com/ipfs/go-ipfs-ds-help"
|
||||||
node "github.com/ipfs/go-ipld-format"
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@@ -50,31 +48,11 @@ func Rollback(tx *sqlx.Tx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishIPLD is used to insert an ipld into Postgres blockstore with the provided tx
|
// FetchIPLDByMhKeyAndBlockNumber is used to retrieve an ipld from Postgres blockstore with the provided tx, mhkey string and blockNumber
|
||||||
func PublishIPLD(tx *sqlx.Tx, i node.Node) error {
|
func FetchIPLDByMhKeyAndBlockNumber(tx *sqlx.Tx, mhKey string, blockNumber uint64) ([]byte, error) {
|
||||||
dbKey := dshelp.MultihashToDsKey(i.Cid().Hash())
|
pgStr := `SELECT data FROM public.blocks WHERE key = $1 AND block_number = $2`
|
||||||
prefixedKey := blockstore.BlockPrefix.String() + dbKey.String()
|
|
||||||
raw := i.RawData()
|
|
||||||
_, err := tx.Exec(`INSERT INTO public.blocks (key, data) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING`, prefixedKey, raw)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FetchIPLD is used to retrieve an ipld from Postgres blockstore with the provided tx and cid string
|
|
||||||
func FetchIPLD(tx *sqlx.Tx, cid string) ([]byte, error) {
|
|
||||||
mhKey, err := MultihashKeyFromCIDString(cid)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pgStr := `SELECT data FROM public.blocks WHERE key = $1`
|
|
||||||
var block []byte
|
var block []byte
|
||||||
return block, tx.Get(&block, pgStr, mhKey)
|
return block, tx.Get(&block, pgStr, mhKey, blockNumber)
|
||||||
}
|
|
||||||
|
|
||||||
// FetchIPLDByMhKey is used to retrieve an ipld from Postgres blockstore with the provided tx and mhkey string
|
|
||||||
func FetchIPLDByMhKey(tx *sqlx.Tx, mhKey string) ([]byte, error) {
|
|
||||||
pgStr := `SELECT data FROM public.blocks WHERE key = $1`
|
|
||||||
var block []byte
|
|
||||||
return block, tx.Get(&block, pgStr, mhKey)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultihashKeyFromCID converts a cid into a blockstore-prefixed multihash db key string
|
// MultihashKeyFromCID converts a cid into a blockstore-prefixed multihash db key string
|
||||||
@@ -92,15 +70,3 @@ func MultihashKeyFromCIDString(c string) (string, error) {
|
|||||||
dbKey := dshelp.MultihashToDsKey(dc.Hash())
|
dbKey := dshelp.MultihashToDsKey(dc.Hash())
|
||||||
return blockstore.BlockPrefix.String() + dbKey.String(), nil
|
return blockstore.BlockPrefix.String() + dbKey.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishRaw derives a cid from raw bytes and provided codec and multihash type, and writes it to the db tx
|
|
||||||
func PublishRaw(tx *sqlx.Tx, codec, mh uint64, raw []byte) (string, error) {
|
|
||||||
c, err := ipld.RawdataToCid(codec, raw, mh)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
dbKey := dshelp.MultihashToDsKey(c.Hash())
|
|
||||||
prefixedKey := blockstore.BlockPrefix.String() + dbKey.String()
|
|
||||||
_, err = tx.Exec(`INSERT INTO public.blocks (key, data) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING`, prefixedKey, raw)
|
|
||||||
return c.String(), err
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -18,8 +18,20 @@ package shared
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/indexer"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/indexer/interfaces"
|
||||||
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
"github.com/ethereum/go-ethereum/statediff/indexer/models"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/indexer/node"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IPLDsContainBytes used to check if a list of strings contains a particular string
|
// IPLDsContainBytes used to check if a list of strings contains a particular string
|
||||||
@@ -31,3 +43,73 @@ func IPLDsContainBytes(iplds []models.IPLDModel, b []byte) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupDB is use to setup a db for watcher tests
|
||||||
|
func SetupDB() *sqlx.DB {
|
||||||
|
config := getTestDBConfig()
|
||||||
|
|
||||||
|
db, err := NewDB(config.DbConnectionString(), config)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
// TearDownDB is used to tear down the watcher dbs after tests
|
||||||
|
func TearDownDB(db *sqlx.DB) {
|
||||||
|
tx, err := db.Beginx()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM nodes`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.header_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.uncle_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.transaction_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.receipt_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.state_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.storage_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.state_accounts`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.access_list_elements`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM blocks`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth.log_cids`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
_, err = tx.Exec(`DELETE FROM eth_meta.watched_addresses`)
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
err = tx.Commit()
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetupTestStateDiffIndexer(ctx context.Context, chainConfig *params.ChainConfig, genHash common.Hash) interfaces.StateDiffIndexer {
|
||||||
|
testInfo := node.Info{
|
||||||
|
GenesisBlock: genHash.String(),
|
||||||
|
NetworkID: "1",
|
||||||
|
ID: "1",
|
||||||
|
ClientName: "geth",
|
||||||
|
ChainID: params.TestChainConfig.ChainID.Uint64(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_, stateDiffIndexer, err := indexer.NewStateDiffIndexer(ctx, chainConfig, testInfo, getTestDBConfig())
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
|
||||||
|
return stateDiffIndexer
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTestDBConfig() postgres.Config {
|
||||||
|
port, _ := strconv.Atoi(os.Getenv("DATABASE_PORT"))
|
||||||
|
return postgres.Config{
|
||||||
|
Hostname: os.Getenv("DATABASE_HOSTNAME"),
|
||||||
|
DatabaseName: os.Getenv("DATABASE_NAME"),
|
||||||
|
Username: os.Getenv("DATABASE_USER"),
|
||||||
|
Password: os.Getenv("DATABASE_PASSWORD"),
|
||||||
|
Port: port,
|
||||||
|
Driver: postgres.SQLX,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,17 +3,8 @@ set -o xtrace
|
|||||||
|
|
||||||
export ETH_FORWARD_ETH_CALLS=false
|
export ETH_FORWARD_ETH_CALLS=false
|
||||||
export DB_WRITE=true
|
export DB_WRITE=true
|
||||||
export ETH_HTTP_PATH=""
|
|
||||||
export ETH_PROXY_ON_ERROR=false
|
export ETH_PROXY_ON_ERROR=false
|
||||||
|
|
||||||
# Clear up existing docker images and volume.
|
|
||||||
docker-compose down --remove-orphans --volumes
|
|
||||||
|
|
||||||
# Build and start the containers.
|
|
||||||
# Note: Build only if `ipld-eth-server` or other container code is modified. Otherwise comment this line.
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml build eth-server
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d ipld-eth-db dapptools contract eth-server
|
|
||||||
|
|
||||||
export PGPASSWORD=password
|
export PGPASSWORD=password
|
||||||
export DATABASE_USER=vdbm
|
export DATABASE_USER=vdbm
|
||||||
export DATABASE_PORT=8077
|
export DATABASE_PORT=8077
|
||||||
|
|||||||
Regular → Executable
-9
@@ -3,17 +3,8 @@ set -o xtrace
|
|||||||
|
|
||||||
export ETH_FORWARD_ETH_CALLS=true
|
export ETH_FORWARD_ETH_CALLS=true
|
||||||
export DB_WRITE=false
|
export DB_WRITE=false
|
||||||
export ETH_HTTP_PATH="dapptools:8545"
|
|
||||||
export ETH_PROXY_ON_ERROR=false
|
export ETH_PROXY_ON_ERROR=false
|
||||||
|
|
||||||
# Clear up existing docker images and volume.
|
|
||||||
docker-compose down --remove-orphans --volumes
|
|
||||||
|
|
||||||
# Build and start the containers.
|
|
||||||
# Note: Build only if `ipld-eth-server` or other container code is modified. Otherwise comment this line.
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml build eth-server
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d ipld-eth-db dapptools contract eth-server
|
|
||||||
|
|
||||||
export PGPASSWORD=password
|
export PGPASSWORD=password
|
||||||
export DATABASE_USER=vdbm
|
export DATABASE_USER=vdbm
|
||||||
export DATABASE_PORT=8077
|
export DATABASE_PORT=8077
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
# Clear up existing docker images and volume.
|
#!/bin/bash
|
||||||
docker-compose down --remove-orphans --volumes
|
|
||||||
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d ipld-eth-db
|
set -e
|
||||||
PGPASSWORD=password DATABASE_USER=vdbm DATABASE_PORT=8077 DATABASE_PASSWORD=password DATABASE_HOSTNAME=127.0.0.1 DATABASE_NAME=vulcanize_testing make test
|
|
||||||
|
mkdir -p out
|
||||||
|
|
||||||
|
# Remove existing docker-tsdb directory
|
||||||
|
rm -rf out/docker-tsdb/
|
||||||
|
|
||||||
|
# Copy over files to setup TimescaleDB
|
||||||
|
ID=$(docker create vulcanize/ipld-eth-db:v4.1.1-alpha)
|
||||||
|
docker cp $ID:/app/docker-tsdb out/docker-tsdb/
|
||||||
|
docker rm -v $ID
|
||||||
|
|
||||||
|
# Spin up TimescaleDB
|
||||||
|
docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml up ipld-eth-db
|
||||||
|
trap "docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml down --remove-orphans --volumes; rm -rf out/" SIGINT SIGTERM ERR
|
||||||
|
sleep 45
|
||||||
|
|
||||||
|
# Run unit tests
|
||||||
|
go clean -testcache
|
||||||
|
PGPASSWORD=password DATABASE_USER=vdbm DATABASE_PORT=8066 DATABASE_PASSWORD=password DATABASE_HOSTNAME=127.0.0.1 DATABASE_NAME=vulcanize_testing_v4 make test
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml down --remove-orphans --volumes
|
||||||
|
rm -rf out/
|
||||||
|
|||||||
+121
-12
@@ -1,15 +1,124 @@
|
|||||||
|
# Test Insructions
|
||||||
|
|
||||||
Spin up services:
|
## Setup
|
||||||
```
|
|
||||||
docker-compose -f docker-compose.test.yml -f docker-compose.yml up -d db dapptools contract eth-server
|
|
||||||
```
|
|
||||||
|
|
||||||
Running unit tests:
|
- Clone [stack-orchestrator](https://github.com/vulcanize/stack-orchestrator), [ipld-eth-db](https://github.com/vulcanize/ipld-eth-db) [go-ethereum](https://github.com/vulcanize/go-ethereum) repositories.
|
||||||
```bash
|
|
||||||
make test_local
|
|
||||||
```
|
|
||||||
|
|
||||||
Running integration test:
|
- Checkout [v4 release](https://github.com/vulcanize/ipld-eth-db/releases/tag/v4.1.1-alpha) in ipld-eth-db repo.
|
||||||
```bash
|
```bash
|
||||||
make integrationtest_local
|
# In ipld-eth-db repo.
|
||||||
```
|
git checkout v4.1.1-alpha
|
||||||
|
```
|
||||||
|
|
||||||
|
- Checkout [v4 release](https://github.com/vulcanize/go-ethereum/releases/tag/v1.10.18-statediff-4.0.2-alpha) in go-ethereum repo.
|
||||||
|
```bash
|
||||||
|
# In go-ethereum repo.
|
||||||
|
git checkout v1.10.18-statediff-4.0.2-alpha
|
||||||
|
```
|
||||||
|
|
||||||
|
- Checkout working commit in stack-orchestrator repo.
|
||||||
|
```bash
|
||||||
|
# In stack-orchestrator repo.
|
||||||
|
git checkout 418957a1f745c921b21286c13bb033f922a91ae9
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
- Run unit tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In ipld-eth-server root directory.
|
||||||
|
./scripts/run_unit_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run integration tests:
|
||||||
|
|
||||||
|
- In stack-orchestrator repo, create config file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd helper-scripts
|
||||||
|
|
||||||
|
./create-config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
A `config.sh` will be created in the root directory.
|
||||||
|
|
||||||
|
- Update/Edit the generated config file with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Path to ipld-eth-server repo.
|
||||||
|
vulcanize_ipld_eth_db=~/ipld-eth-db/
|
||||||
|
|
||||||
|
# Path to go-ethereum repo.
|
||||||
|
vulcanize_go_ethereum=~/go-ethereum/
|
||||||
|
|
||||||
|
# Path to ipld-eth-server repo.
|
||||||
|
vulcanize_ipld_eth_server=~/ipld-eth-server/
|
||||||
|
|
||||||
|
# Path to test contract.
|
||||||
|
vulcanize_test_contract=~/ipld-eth-server/test/contract
|
||||||
|
|
||||||
|
db_write=true
|
||||||
|
eth_forward_eth_calls=false
|
||||||
|
eth_proxy_on_error=false
|
||||||
|
eth_http_path="go-ethereum:8545"
|
||||||
|
ipld_eth_server_db_dependency=access-node
|
||||||
|
go_ethereum_db_dependency=access-node
|
||||||
|
connecting_db_name=vulcanize_testing_v4
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run stack-orchestrator:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In stack-orchestrator root directory.
|
||||||
|
cd helper-scripts
|
||||||
|
|
||||||
|
./wrapper.sh \
|
||||||
|
-e docker \
|
||||||
|
-d ../docker/latest/docker-compose-timescale-db.yml \
|
||||||
|
-d ../docker/local/docker-compose-db-migration.yml \
|
||||||
|
-d ../docker/local/docker-compose-go-ethereum.yml \
|
||||||
|
-d ../docker/local/docker-compose-ipld-eth-server.yml \
|
||||||
|
-d ../docker/local/docker-compose-contract.yml \
|
||||||
|
-v remove \
|
||||||
|
-p ../config.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- Run test:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# In ipld-eth-server root directory.
|
||||||
|
./scripts/run_integration_test.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
- Update stack-orchestrator `config.sh` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Path to go-ethereum repo.
|
||||||
|
vulcanize_go_ethereum=~/go-ethereum/
|
||||||
|
|
||||||
|
# Path to ipld-eth-server repo.
|
||||||
|
vulcanize_ipld_eth_server=~/ipld-eth-server/
|
||||||
|
|
||||||
|
# Path to test contract.
|
||||||
|
vulcanize_test_contract=~/ipld-eth-server/test/contract
|
||||||
|
|
||||||
|
db_write=false
|
||||||
|
eth_forward_eth_calls=true
|
||||||
|
eth_proxy_on_error=false
|
||||||
|
eth_http_path="go-ethereum:8545"
|
||||||
|
ipld_eth_server_db_dependency=access-node
|
||||||
|
go_ethereum_db_dependency=access-node
|
||||||
|
connecting_db_name=vulcanize_testing_v4
|
||||||
|
```
|
||||||
|
|
||||||
|
- Stop the stack-orchestrator and start again using the same command
|
||||||
|
|
||||||
|
- Run integration tests for direct proxy fall-through of eth_calls:
|
||||||
|
```bash
|
||||||
|
./scripts/run_integration_test_forward_eth_calls.sh
|
||||||
|
```
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// SPDX-License-Identifier: AGPL-3.0
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
|
|
||||||
|
contract SLVToken is ERC20 {
|
||||||
|
uint256 private countA;
|
||||||
|
uint256 private countB;
|
||||||
|
|
||||||
|
constructor() ERC20("Silver", "SLV") {}
|
||||||
|
|
||||||
|
function incrementCountA() public {
|
||||||
|
countA = countA + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function incrementCountB() public {
|
||||||
|
countB = countB + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
receive() external payable {}
|
||||||
|
|
||||||
|
function destroy() public {
|
||||||
|
selfdestruct(payable(msg.sender));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,15 +17,26 @@ task("accounts", "Prints the list of accounts", async () => {
|
|||||||
* @type import('hardhat/config').HardhatUserConfig
|
* @type import('hardhat/config').HardhatUserConfig
|
||||||
*/
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
solidity: "0.8.0",
|
solidity: {
|
||||||
|
version: "0.8.0",
|
||||||
|
settings: {
|
||||||
|
outputSelection: {
|
||||||
|
'*': {
|
||||||
|
'*': [
|
||||||
|
'abi', 'storageLayout',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
networks: {
|
networks: {
|
||||||
local: {
|
local: {
|
||||||
url: 'http://127.0.0.1:8545',
|
url: 'http://127.0.0.1:8545',
|
||||||
chainId: 4
|
chainId: 99
|
||||||
},
|
},
|
||||||
docker: {
|
docker: {
|
||||||
url: process.env.ETH_ADDR,
|
url: process.env.ETH_ADDR,
|
||||||
chainId: 4
|
chainId: 99
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+36
-88
@@ -11,7 +11,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openzeppelin/contracts": "^4.0.0",
|
"@openzeppelin/contracts": "^4.0.0",
|
||||||
"fastify": "^3.14.2",
|
"fastify": "^3.14.2",
|
||||||
"hardhat": "^2.2.0"
|
"hardhat": "^2.2.0",
|
||||||
|
"solidity-create2-deployer": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
@@ -469,7 +470,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz",
|
||||||
"integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==",
|
"integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -496,7 +496,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz",
|
||||||
"integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==",
|
"integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -521,7 +520,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz",
|
||||||
"integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==",
|
"integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -544,7 +542,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz",
|
||||||
"integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==",
|
"integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -567,7 +564,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz",
|
||||||
"integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==",
|
"integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -586,7 +582,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz",
|
||||||
"integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==",
|
"integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -606,7 +601,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz",
|
||||||
"integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==",
|
"integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -627,7 +621,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz",
|
||||||
"integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==",
|
"integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -646,7 +639,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz",
|
||||||
"integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==",
|
"integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -665,7 +657,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.0.tgz",
|
||||||
"integrity": "sha512-dvTMs/4XGSc57cYOW0KjgX1NdTujUu7mNb6PQdJWg08m9ULzPyGZuBkFJnijBcp6vTOCQ59RwjboWgNWw393og==",
|
"integrity": "sha512-dvTMs/4XGSc57cYOW0KjgX1NdTujUu7mNb6PQdJWg08m9ULzPyGZuBkFJnijBcp6vTOCQ59RwjboWgNWw393og==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -693,7 +684,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz",
|
||||||
"integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==",
|
"integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -719,7 +709,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz",
|
||||||
"integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==",
|
"integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -749,7 +738,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz",
|
||||||
"integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==",
|
"integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -780,7 +768,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz",
|
||||||
"integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==",
|
"integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -799,14 +786,12 @@
|
|||||||
"node_modules/@ethersproject/keccak256/node_modules/js-sha3": {
|
"node_modules/@ethersproject/keccak256/node_modules/js-sha3": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
||||||
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=",
|
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@ethersproject/logger": {
|
"node_modules/@ethersproject/logger": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz",
|
||||||
"integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==",
|
"integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -822,7 +807,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz",
|
||||||
"integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==",
|
"integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -841,7 +825,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz",
|
||||||
"integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==",
|
"integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -861,7 +844,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz",
|
||||||
"integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==",
|
"integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -880,7 +862,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.0.tgz",
|
||||||
"integrity": "sha512-FjpZL2lSXrYpQDg2fMjugZ0HjQD9a+2fOOoRhhihh+Z+qi/xZ8vIlPoumrEP1DzIG4DBV6liUqLNqnX2C6FIAA==",
|
"integrity": "sha512-FjpZL2lSXrYpQDg2fMjugZ0HjQD9a+2fOOoRhhihh+Z+qi/xZ8vIlPoumrEP1DzIG4DBV6liUqLNqnX2C6FIAA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -917,7 +898,6 @@
|
|||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||||
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
|
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.3.0"
|
"node": ">=8.3.0"
|
||||||
},
|
},
|
||||||
@@ -938,7 +918,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz",
|
||||||
"integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==",
|
"integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -958,7 +937,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz",
|
||||||
"integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==",
|
"integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -978,7 +956,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz",
|
||||||
"integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==",
|
"integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -999,7 +976,6 @@
|
|||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
||||||
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
@@ -1009,7 +985,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz",
|
||||||
"integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==",
|
"integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1032,7 +1007,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz",
|
||||||
"integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==",
|
"integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1055,7 +1029,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz",
|
||||||
"integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==",
|
"integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1076,7 +1049,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.0.tgz",
|
||||||
"integrity": "sha512-s10crRLZEA0Bgv6FGEl/AKkTw9f+RVUrlWDX1rHnD4ZncPFeiV2AJr4nT7QSUhxJdFPvjyKRDb3nEH27dIqcPQ==",
|
"integrity": "sha512-s10crRLZEA0Bgv6FGEl/AKkTw9f+RVUrlWDX1rHnD4ZncPFeiV2AJr4nT7QSUhxJdFPvjyKRDb3nEH27dIqcPQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1103,7 +1075,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz",
|
||||||
"integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==",
|
"integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1124,7 +1095,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz",
|
||||||
"integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==",
|
"integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1157,7 +1127,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz",
|
||||||
"integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==",
|
"integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1180,7 +1149,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz",
|
||||||
"integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==",
|
"integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -1630,8 +1598,7 @@
|
|||||||
"node_modules/aes-js": {
|
"node_modules/aes-js": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
|
||||||
"integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=",
|
"integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/agent-base": {
|
"node_modules/agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
@@ -1870,8 +1837,7 @@
|
|||||||
"node_modules/bech32": {
|
"node_modules/bech32": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
||||||
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
|
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/binary-extensions": {
|
"node_modules/binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
@@ -2774,7 +2740,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.0.tgz",
|
||||||
"integrity": "sha512-2L6Ge6wMBw02FlRoCLg4E0Elt3khMNlW6ULawa10mMeeZToYJ5+uCfiuTuB+XZ6om1Y7wuO9ZzezP8FsU2M/+g==",
|
"integrity": "sha512-2L6Ge6wMBw02FlRoCLg4E0Elt3khMNlW6ULawa10mMeeZToYJ5+uCfiuTuB+XZ6om1Y7wuO9ZzezP8FsU2M/+g==",
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "individual",
|
"type": "individual",
|
||||||
@@ -5427,7 +5392,7 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "2.1.2",
|
||||||
"whatwg-fetch": "2.0.4"
|
"whatwg-fetch": "2.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -7533,7 +7498,7 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-fetch": "^2.6.7"
|
"node-fetch": "~1.7.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
|
"node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/is-stream": {
|
||||||
@@ -7545,7 +7510,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
|
"node_modules/ganache-core/node_modules/fetch-ponyfill/node_modules/node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "1.7.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -9217,7 +9182,7 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ganache-core/node_modules/node-fetch": {
|
"node_modules/ganache-core/node_modules/node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.1.2",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -14740,6 +14705,17 @@
|
|||||||
"semver": "bin/semver"
|
"semver": "bin/semver"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/solidity-create2-deployer": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/solidity-create2-deployer/-/solidity-create2-deployer-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-bB5d8fPt4dWsOoRodrsyfWKcjiv77IFl84+e6EckMMGYlfL2ZFqUoMz6tnqqiUFrM9abF1p6dWFOgJ/3zVc8yQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ethers": "^5.0.14"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/sonic-boom": {
|
"node_modules/sonic-boom": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
|
||||||
@@ -16056,7 +16032,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.1.0.tgz",
|
||||||
"integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==",
|
"integrity": "sha512-N/W9Sbn1/C6Kh2kuHRjf/hX6euMK4+9zdJRBB8sDWmihVntjUAfxbusGZKzDQD8i3szAHhTz8K7XADV5iFNfJw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/address": "^5.1.0",
|
"@ethersproject/address": "^5.1.0",
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
@@ -16073,7 +16048,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.1.0.tgz",
|
||||||
"integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==",
|
"integrity": "sha512-8dJUnT8VNvPwWhYIau4dwp7qe1g+KgdRm4XTWvjkI9gAT2zZa90WF5ApdZ3vl1r6NDmnn6vUVvyphClRZRteTQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
@@ -16088,7 +16062,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.1.0.tgz",
|
||||||
"integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==",
|
"integrity": "sha512-qQDMkjGZSSJSKl6AnfTgmz9FSnzq3iEoEbHTYwjDlEAv+LNP7zd4ixCcVWlWyk+2siud856M5CRhAmPdupeN9w==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-provider": "^5.1.0",
|
"@ethersproject/abstract-provider": "^5.1.0",
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
@@ -16101,7 +16074,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.1.0.tgz",
|
||||||
"integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==",
|
"integrity": "sha512-rfWQR12eHn2cpstCFS4RF7oGjfbkZb0oqep+BfrT+gWEGWG2IowJvIsacPOvzyS1jhNF4MQ4BS59B04Mbovteg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
@@ -16114,7 +16086,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.1.0.tgz",
|
||||||
"integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==",
|
"integrity": "sha512-npD1bLvK4Bcxz+m4EMkx+F8Rd7CnqS9DYnhNu0/GlQBXhWjvfoAZzk5HJ0f1qeyp8d+A86PTuzLOGOXf4/CN8g==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0"
|
"@ethersproject/bytes": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -16123,7 +16094,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.1.0.tgz",
|
||||||
"integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==",
|
"integrity": "sha512-vBKr39bum7DDbOvkr1Sj19bRMEPA4FnST6Utt6xhDzI7o7L6QNkDn2yrCfP+hnvJGhZFKtLygWwqlTBZoBXYLg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/properties": "^5.1.0"
|
"@ethersproject/properties": "^5.1.0"
|
||||||
@@ -16133,7 +16103,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.1.0.tgz",
|
||||||
"integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==",
|
"integrity": "sha512-wUvQlhTjPjFXIdLPOuTrFeQmSa6Wvls1bGXQNQWvB/SEn1NsTCE8PmumIEZxmOPjSHl1eV2uyHP5jBm5Cgj92Q==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/logger": "^5.1.0",
|
"@ethersproject/logger": "^5.1.0",
|
||||||
@@ -16144,7 +16113,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.1.0.tgz",
|
||||||
"integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==",
|
"integrity": "sha512-sGTxb+LVjFxJcJeUswAIK6ncgOrh3D8c192iEJd7mLr95V6du119rRfYT/b87WPkZ5I3gRBUYIYXtdgCWACe8g==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/logger": "^5.1.0"
|
"@ethersproject/logger": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -16153,7 +16121,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.1.0.tgz",
|
||||||
"integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==",
|
"integrity": "sha512-0/SuHrxc8R8k+JiLmJymxHJbojUDWBQqO+b+XFdwaP0jGzqC09YDy/CAlSZB6qHsBifY8X3I89HcK/oMqxRdBw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bignumber": "^5.1.0"
|
"@ethersproject/bignumber": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -16162,7 +16129,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.1.0.tgz",
|
||||||
"integrity": "sha512-dvTMs/4XGSc57cYOW0KjgX1NdTujUu7mNb6PQdJWg08m9ULzPyGZuBkFJnijBcp6vTOCQ59RwjboWgNWw393og==",
|
"integrity": "sha512-dvTMs/4XGSc57cYOW0KjgX1NdTujUu7mNb6PQdJWg08m9ULzPyGZuBkFJnijBcp6vTOCQ59RwjboWgNWw393og==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abi": "^5.1.0",
|
"@ethersproject/abi": "^5.1.0",
|
||||||
"@ethersproject/abstract-provider": "^5.1.0",
|
"@ethersproject/abstract-provider": "^5.1.0",
|
||||||
@@ -16180,7 +16146,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.1.0.tgz",
|
||||||
"integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==",
|
"integrity": "sha512-fNwry20yLLPpnRRwm3fBL+2ksgO+KMadxM44WJmRIoTKzy4269+rbq9KFoe2LTqq2CXJM2CE70beGaNrpuqflQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-signer": "^5.1.0",
|
"@ethersproject/abstract-signer": "^5.1.0",
|
||||||
"@ethersproject/address": "^5.1.0",
|
"@ethersproject/address": "^5.1.0",
|
||||||
@@ -16196,7 +16161,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.1.0.tgz",
|
||||||
"integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==",
|
"integrity": "sha512-obIWdlujloExPHWJGmhJO/sETOOo7SEb6qemV4f8kyFoXg+cJK+Ta9SvBrj7hsUK85n3LZeZJZRjjM7oez3Clg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-signer": "^5.1.0",
|
"@ethersproject/abstract-signer": "^5.1.0",
|
||||||
"@ethersproject/basex": "^5.1.0",
|
"@ethersproject/basex": "^5.1.0",
|
||||||
@@ -16216,7 +16180,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.1.0.tgz",
|
||||||
"integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==",
|
"integrity": "sha512-00n2iBy27w8zrGZSiU762UOVuzCQZxUZxopsZC47++js6xUFuI74DHcJ5K/2pddlF1YBskvmMuboEu1geK8mnA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-signer": "^5.1.0",
|
"@ethersproject/abstract-signer": "^5.1.0",
|
||||||
"@ethersproject/address": "^5.1.0",
|
"@ethersproject/address": "^5.1.0",
|
||||||
@@ -16237,7 +16200,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.1.0.tgz",
|
||||||
"integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==",
|
"integrity": "sha512-vrTB1W6AEYoadww5c9UyVJ2YcSiyIUTNDRccZIgwTmFFoSHwBtcvG1hqy9RzJ1T0bMdATbM9Hfx2mJ6H0i7Hig==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"js-sha3": "0.5.7"
|
"js-sha3": "0.5.7"
|
||||||
@@ -16246,22 +16208,19 @@
|
|||||||
"js-sha3": {
|
"js-sha3": {
|
||||||
"version": "0.5.7",
|
"version": "0.5.7",
|
||||||
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
|
||||||
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=",
|
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ethersproject/logger": {
|
"@ethersproject/logger": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.1.0.tgz",
|
||||||
"integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw==",
|
"integrity": "sha512-wtUaD1lBX10HBXjjKV9VHCBnTdUaKQnQ2XSET1ezglqLdPdllNOIlLfhyCRqXm5xwcjExVI5ETokOYfjPtaAlw=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@ethersproject/networks": {
|
"@ethersproject/networks": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.1.0.tgz",
|
||||||
"integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==",
|
"integrity": "sha512-A/NIrIED/G/IgU1XUukOA3WcFRxn2I4O5GxsYGA5nFlIi+UZWdGojs85I1VXkR1gX9eFnDXzjE6OtbgZHjFhIA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/logger": "^5.1.0"
|
"@ethersproject/logger": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -16270,7 +16229,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.1.0.tgz",
|
||||||
"integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==",
|
"integrity": "sha512-B8cUbHHTgs8OtgJIafrRcz/YPDobVd5Ru8gTnShOiM9EBuFpYHQpq3+8iQJ6pyczDu6HP/oc/njAsIBhwFZYew==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/sha2": "^5.1.0"
|
"@ethersproject/sha2": "^5.1.0"
|
||||||
@@ -16280,7 +16238,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.1.0.tgz",
|
||||||
"integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==",
|
"integrity": "sha512-519KKTwgmH42AQL3+GFV3SX6khYEfHsvI6v8HYejlkigSDuqttdgVygFTDsGlofNFchhDwuclrxQnD5B0YLNMg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/logger": "^5.1.0"
|
"@ethersproject/logger": "^5.1.0"
|
||||||
}
|
}
|
||||||
@@ -16289,7 +16246,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.1.0.tgz",
|
||||||
"integrity": "sha512-FjpZL2lSXrYpQDg2fMjugZ0HjQD9a+2fOOoRhhihh+Z+qi/xZ8vIlPoumrEP1DzIG4DBV6liUqLNqnX2C6FIAA==",
|
"integrity": "sha512-FjpZL2lSXrYpQDg2fMjugZ0HjQD9a+2fOOoRhhihh+Z+qi/xZ8vIlPoumrEP1DzIG4DBV6liUqLNqnX2C6FIAA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-provider": "^5.1.0",
|
"@ethersproject/abstract-provider": "^5.1.0",
|
||||||
"@ethersproject/abstract-signer": "^5.1.0",
|
"@ethersproject/abstract-signer": "^5.1.0",
|
||||||
@@ -16316,7 +16272,6 @@
|
|||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||||
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
|
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {}
|
"requires": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16325,7 +16280,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.1.0.tgz",
|
||||||
"integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==",
|
"integrity": "sha512-+uuczLQZ4+no9cP6TCoCktXx0u2YbNaRT7lRkSt12d8263e702f0u+4JnnRO8Qmv5nylWJebnqCHzyxP+6mLqw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/logger": "^5.1.0"
|
"@ethersproject/logger": "^5.1.0"
|
||||||
@@ -16335,7 +16289,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.1.0.tgz",
|
||||||
"integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==",
|
"integrity": "sha512-vDTyHIwNPrecy55gKGZ47eJZhBm8LLBxihzi5ou+zrSvYTpkSTWRcKUlXFDFQVwfWB+P5PGyERAdiDEI76clxw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/logger": "^5.1.0"
|
"@ethersproject/logger": "^5.1.0"
|
||||||
@@ -16345,7 +16298,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.1.0.tgz",
|
||||||
"integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==",
|
"integrity": "sha512-+fNSeZRstOpdRJpdGUkRONFCaiAqWkc91zXgg76Nlp5ndBQE25Kk5yK8gCPG1aGnCrbariiPr5j9DmrYH78JCA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/logger": "^5.1.0",
|
"@ethersproject/logger": "^5.1.0",
|
||||||
@@ -16356,7 +16308,6 @@
|
|||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
|
||||||
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
"integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
@@ -16368,7 +16319,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.1.0.tgz",
|
||||||
"integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==",
|
"integrity": "sha512-tE5LFlbmdObG8bY04NpuwPWSRPgEswfxweAI1sH7TbP0ml1elNfqcq7ii/3AvIN05i5U0Pkm3Tf8bramt8MmLw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/logger": "^5.1.0",
|
"@ethersproject/logger": "^5.1.0",
|
||||||
@@ -16381,7 +16331,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.1.0.tgz",
|
||||||
"integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==",
|
"integrity": "sha512-kPodsGyo9zg1g9XSXp1lGhFaezBAUUsAUB1Vf6OkppE5Wksg4Et+x3kG4m7J/uShDMP2upkJtHNsIBK2XkVpKQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
@@ -16394,7 +16343,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.1.0.tgz",
|
||||||
"integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==",
|
"integrity": "sha512-perBZy0RrmmL0ejiFGUOlBVjMsUceqLut3OBP3zP96LhiJWWbS8u1NqQVgN4/Gyrbziuda66DxiQocXhsvx+Sw==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/constants": "^5.1.0",
|
"@ethersproject/constants": "^5.1.0",
|
||||||
@@ -16405,7 +16353,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.1.0.tgz",
|
||||||
"integrity": "sha512-s10crRLZEA0Bgv6FGEl/AKkTw9f+RVUrlWDX1rHnD4ZncPFeiV2AJr4nT7QSUhxJdFPvjyKRDb3nEH27dIqcPQ==",
|
"integrity": "sha512-s10crRLZEA0Bgv6FGEl/AKkTw9f+RVUrlWDX1rHnD4ZncPFeiV2AJr4nT7QSUhxJdFPvjyKRDb3nEH27dIqcPQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/address": "^5.1.0",
|
"@ethersproject/address": "^5.1.0",
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
@@ -16422,7 +16369,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.1.0.tgz",
|
||||||
"integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==",
|
"integrity": "sha512-isvJrx6qG0nKWfxsGORNjmOq/nh175fStfvRTA2xEKrGqx8JNJY83fswu4GkILowfriEM/eYpretfJnfzi7YhA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bignumber": "^5.1.0",
|
"@ethersproject/bignumber": "^5.1.0",
|
||||||
"@ethersproject/constants": "^5.1.0",
|
"@ethersproject/constants": "^5.1.0",
|
||||||
@@ -16433,7 +16379,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.1.0.tgz",
|
||||||
"integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==",
|
"integrity": "sha512-ULmUtiYQLTUS+y3DgkLzRhFEK10zMwmjOthnjiZxee3Q/MVwr3rnmuAnXIUZrPjna6hvUPnyRIdW5XuF0Ld0YQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abstract-provider": "^5.1.0",
|
"@ethersproject/abstract-provider": "^5.1.0",
|
||||||
"@ethersproject/abstract-signer": "^5.1.0",
|
"@ethersproject/abstract-signer": "^5.1.0",
|
||||||
@@ -16456,7 +16401,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.1.0.tgz",
|
||||||
"integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==",
|
"integrity": "sha512-LTeluWgTq04+RNqAkVhpydPcRZK/kKxD2Vy7PYGrAD27ABO9kTqTBKwiOuzTyAHKUQHfnvZbXmxBXJAGViSDcA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/base64": "^5.1.0",
|
"@ethersproject/base64": "^5.1.0",
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
@@ -16469,7 +16413,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.1.0.tgz",
|
||||||
"integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==",
|
"integrity": "sha512-NsUCi/TpBb+oTFvMSccUkJGtp5o/84eOyqp5q5aBeiNBSLkYyw21znRn9mAmxZgySpxgruVgKbaapnYPgvctPQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/bytes": "^5.1.0",
|
"@ethersproject/bytes": "^5.1.0",
|
||||||
"@ethersproject/hash": "^5.1.0",
|
"@ethersproject/hash": "^5.1.0",
|
||||||
@@ -16871,8 +16814,7 @@
|
|||||||
"aes-js": {
|
"aes-js": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
|
||||||
"integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=",
|
"integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"agent-base": {
|
"agent-base": {
|
||||||
"version": "6.0.2",
|
"version": "6.0.2",
|
||||||
@@ -17059,8 +17001,7 @@
|
|||||||
"bech32": {
|
"bech32": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
||||||
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==",
|
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
@@ -17807,7 +17748,6 @@
|
|||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.1.0.tgz",
|
||||||
"integrity": "sha512-2L6Ge6wMBw02FlRoCLg4E0Elt3khMNlW6ULawa10mMeeZToYJ5+uCfiuTuB+XZ6om1Y7wuO9ZzezP8FsU2M/+g==",
|
"integrity": "sha512-2L6Ge6wMBw02FlRoCLg4E0Elt3khMNlW6ULawa10mMeeZToYJ5+uCfiuTuB+XZ6om1Y7wuO9ZzezP8FsU2M/+g==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethersproject/abi": "5.1.0",
|
"@ethersproject/abi": "5.1.0",
|
||||||
"@ethersproject/abstract-provider": "5.1.0",
|
"@ethersproject/abstract-provider": "5.1.0",
|
||||||
@@ -19810,7 +19750,7 @@
|
|||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "2.1.2",
|
||||||
"whatwg-fetch": "2.0.4"
|
"whatwg-fetch": "2.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -21621,7 +21561,7 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-fetch": "^2.6.7"
|
"node-fetch": "~1.7.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-stream": {
|
"is-stream": {
|
||||||
@@ -21629,7 +21569,7 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "1.7.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"encoding": "^0.1.11",
|
"encoding": "^0.1.11",
|
||||||
@@ -22827,7 +22767,7 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.7",
|
"version": "2.1.2",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-gyp-build": {
|
"node-gyp-build": {
|
||||||
@@ -26969,6 +26909,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"solidity-create2-deployer": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/solidity-create2-deployer/-/solidity-create2-deployer-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-bB5d8fPt4dWsOoRodrsyfWKcjiv77IFl84+e6EckMMGYlfL2ZFqUoMz6tnqqiUFrM9abF1p6dWFOgJ/3zVc8yQ==",
|
||||||
|
"requires": {
|
||||||
|
"ethers": "^5.0.14"
|
||||||
|
}
|
||||||
|
},
|
||||||
"sonic-boom": {
|
"sonic-boom": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz",
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@openzeppelin/contracts": "^4.0.0",
|
"@openzeppelin/contracts": "^4.0.0",
|
||||||
"fastify": "^3.14.2",
|
"fastify": "^3.14.2",
|
||||||
"hardhat": "^2.2.0"
|
"hardhat": "^2.2.0",
|
||||||
|
"solidity-create2-deployer": "^0.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
|
|||||||
+112
-1
@@ -1,6 +1,14 @@
|
|||||||
const fastify = require('fastify')({ logger: true });
|
const fastify = require('fastify')({ logger: true });
|
||||||
const hre = require("hardhat");
|
const hre = require("hardhat");
|
||||||
|
|
||||||
|
const {
|
||||||
|
deployContract,
|
||||||
|
isDeployed
|
||||||
|
} = require("solidity-create2-deployer");
|
||||||
|
|
||||||
|
const { getStorageSlotKey, deployCreate2Factory } = require('./utils');
|
||||||
|
|
||||||
|
const CREATE2_FACTORY_ADDRESS = '0x4a27c059FD7E383854Ea7DE6Be9c390a795f6eE3'
|
||||||
|
|
||||||
// readiness check
|
// readiness check
|
||||||
fastify.get('/v1/healthz', async (req, reply) => {
|
fastify.get('/v1/healthz', async (req, reply) => {
|
||||||
@@ -63,6 +71,109 @@ fastify.get('/v1/sendEth', async (req, reply) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
fastify.get('/v1/deploySLVContract', async (req, reply) => {
|
||||||
|
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||||
|
const token = await SLVToken.deploy();
|
||||||
|
const receipt = await token.deployTransaction.wait();
|
||||||
|
|
||||||
|
return {
|
||||||
|
address: token.address,
|
||||||
|
txHash: token.deployTransaction.hash,
|
||||||
|
blockNumber: receipt.blockNumber,
|
||||||
|
blockHash: receipt.blockHash,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.get('/v1/destroySLVContract', async (req, reply) => {
|
||||||
|
const addr = req.query.addr;
|
||||||
|
|
||||||
|
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||||
|
const token = SLVToken.attach(addr);
|
||||||
|
|
||||||
|
const tx = await token.destroy();
|
||||||
|
const receipt = await tx.wait();
|
||||||
|
|
||||||
|
return {
|
||||||
|
blockNumber: receipt.blockNumber,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
fastify.get('/v1/incrementCountA', async (req, reply) => {
|
||||||
|
const addr = req.query.addr;
|
||||||
|
|
||||||
|
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||||
|
const token = await SLVToken.attach(addr);
|
||||||
|
|
||||||
|
const tx = await token.incrementCountA();
|
||||||
|
const receipt = await tx.wait();
|
||||||
|
|
||||||
|
return {
|
||||||
|
blockNumber: receipt.blockNumber,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.get('/v1/incrementCountB', async (req, reply) => {
|
||||||
|
const addr = req.query.addr;
|
||||||
|
|
||||||
|
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||||
|
const token = await SLVToken.attach(addr);
|
||||||
|
|
||||||
|
const tx = await token.incrementCountB();
|
||||||
|
const receipt = await tx.wait();
|
||||||
|
|
||||||
|
return {
|
||||||
|
blockNumber: receipt.blockNumber,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.get('/v1/getStorageKey', async (req, reply) => {
|
||||||
|
const contract = req.query.contract;
|
||||||
|
const label = req.query.label;
|
||||||
|
|
||||||
|
const key = await getStorageSlotKey(contract, label)
|
||||||
|
|
||||||
|
return {
|
||||||
|
key
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fastify.get('/v1/create2Contract', async (req, reply) => {
|
||||||
|
const contract = req.query.contract;
|
||||||
|
const salt = req.query.salt;
|
||||||
|
|
||||||
|
const provider = hre.ethers.provider;
|
||||||
|
const signer = await hre.ethers.getSigner();
|
||||||
|
const isFactoryDeployed = await isDeployed(CREATE2_FACTORY_ADDRESS, provider);
|
||||||
|
|
||||||
|
if (!isFactoryDeployed) {
|
||||||
|
await deployCreate2Factory(provider, signer)
|
||||||
|
}
|
||||||
|
|
||||||
|
const contractFactory = await hre.ethers.getContractFactory(contract);
|
||||||
|
const bytecode = contractFactory.bytecode;
|
||||||
|
const constructorTypes = [];
|
||||||
|
const constructorArgs = [];
|
||||||
|
|
||||||
|
const { txHash, address, receipt } = await deployContract({
|
||||||
|
salt,
|
||||||
|
contractBytecode: bytecode,
|
||||||
|
constructorTypes: constructorTypes,
|
||||||
|
constructorArgs: constructorArgs,
|
||||||
|
signer
|
||||||
|
});
|
||||||
|
|
||||||
|
const success = await isDeployed(address, provider);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return {
|
||||||
|
address,
|
||||||
|
txHash,
|
||||||
|
blockNumber: receipt.blockNumber,
|
||||||
|
blockHash: receipt.blockHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
try {
|
try {
|
||||||
await fastify.listen(3000, '0.0.0.0');
|
await fastify.listen(3000, '0.0.0.0');
|
||||||
@@ -72,4 +183,4 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
const { artifacts } = require("hardhat")
|
||||||
|
const { utils, BigNumber } = require("ethers")
|
||||||
|
const { deployFactory } = require("solidity-create2-deployer");
|
||||||
|
|
||||||
|
const CREATE2_FACTORY_ACCOUNT = '0x2287Fa6efdEc6d8c3E0f4612ce551dEcf89A357A';
|
||||||
|
|
||||||
|
async function getStorageLayout(contractName) {
|
||||||
|
const artifact = await artifacts.readArtifact(contractName);
|
||||||
|
const buildInfo = await artifacts.getBuildInfo(`${artifact.sourceName}:${artifact.contractName}`);
|
||||||
|
|
||||||
|
if (!buildInfo) {
|
||||||
|
throw new Error('storageLayout not present in compiler output.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = buildInfo.output;
|
||||||
|
const { storageLayout } = output.contracts[artifact.sourceName][artifact.contractName];
|
||||||
|
|
||||||
|
if (!storageLayout) {
|
||||||
|
throw new Error('Contract hasn\'t been compiled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return storageLayout;
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getStorageSlotKey(contractName, variableName) {
|
||||||
|
storageLayout = await getStorageLayout(contractName)
|
||||||
|
|
||||||
|
const { storage } = storageLayout;
|
||||||
|
const targetState = storage.find((state) => state.label === variableName);
|
||||||
|
|
||||||
|
// Throw if state variable could not be found in storage layout.
|
||||||
|
if (!targetState) {
|
||||||
|
throw new Error('Variable not present in storage layout.');
|
||||||
|
}
|
||||||
|
|
||||||
|
key = utils.hexlify(BigNumber.from(targetState.slot));
|
||||||
|
return key
|
||||||
|
};
|
||||||
|
|
||||||
|
async function deployCreate2Factory(provider, signer) {
|
||||||
|
// Send eth to account as required to deploy create2 factory contract.
|
||||||
|
let tx = {
|
||||||
|
to: CREATE2_FACTORY_ACCOUNT,
|
||||||
|
value: utils.parseEther('0.01')
|
||||||
|
}
|
||||||
|
|
||||||
|
const txResponse = await signer.sendTransaction(tx);
|
||||||
|
await txResponse.wait()
|
||||||
|
|
||||||
|
// Deploy create2 factory contract.
|
||||||
|
await deployFactory(provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { getStorageSlotKey, deployCreate2Factory }
|
||||||
@@ -13,8 +13,8 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
integration "github.com/vulcanize/ipld-eth-server/test"
|
integration "github.com/vulcanize/ipld-eth-server/v4/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Integration test", func() {
|
var _ = Describe("Integration test", func() {
|
||||||
@@ -38,11 +38,14 @@ var _ = Describe("Integration test", func() {
|
|||||||
var txErr error
|
var txErr error
|
||||||
sleepInterval := 2 * time.Second
|
sleepInterval := 2 * time.Second
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
if !directProxyEthCalls {
|
||||||
|
Skip("skipping direct-proxy-forwarding integration tests")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
Describe("get Block", func() {
|
Describe("get Block", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -94,9 +97,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Transaction", func() {
|
Describe("Transaction", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -122,9 +122,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Receipt", func() {
|
Describe("Receipt", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -142,9 +139,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("FilterLogs", func() {
|
Describe("FilterLogs", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -174,9 +168,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("CodeAt", func() {
|
Describe("CodeAt", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -224,9 +215,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
Describe("Get balance", func() {
|
Describe("Get balance", func() {
|
||||||
address := "0x1111111111111111111111111111111111111112"
|
address := "0x1111111111111111111111111111111111111112"
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
tx, txErr = integration.SendEth(address, "0.01")
|
tx, txErr = integration.SendEth(address, "0.01")
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -286,9 +274,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Get Storage", func() {
|
Describe("Get Storage", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
||||||
|
|
||||||
@@ -392,9 +377,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("eth call", func() {
|
Describe("eth call", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
||||||
|
|
||||||
@@ -445,9 +427,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Chain ID", func() {
|
Describe("Chain ID", func() {
|
||||||
It("Check chain id", func() {
|
It("Check chain id", func() {
|
||||||
if !directProxyEthCalls {
|
|
||||||
Skip("skipping direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
_, err := gethClient.ChainID(ctx)
|
_, err := gethClient.ChainID(ctx)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
|||||||
+108
@@ -5,6 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/statediff/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContractDeployed struct {
|
type ContractDeployed struct {
|
||||||
@@ -27,6 +30,14 @@ type Tx struct {
|
|||||||
BlockHash string `json:"blockHash"`
|
BlockHash string `json:"blockHash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StorageKey struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CountIncremented struct {
|
||||||
|
BlockNumber int64 `json:"blockNumber"`
|
||||||
|
}
|
||||||
|
|
||||||
const srvUrl = "http://localhost:3000"
|
const srvUrl = "http://localhost:3000"
|
||||||
|
|
||||||
func DeployContract() (*ContractDeployed, error) {
|
func DeployContract() (*ContractDeployed, error) {
|
||||||
@@ -77,3 +88,100 @@ func SendEth(to string, value string) (*Tx, error) {
|
|||||||
|
|
||||||
return &tx, nil
|
return &tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func DeploySLVContract() (*ContractDeployed, error) {
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/v1/deploySLVContract", srvUrl))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var contract ContractDeployed
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
err = decoder.Decode(&contract)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &contract, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DestroySLVContract(addr string) (*ContractDestroyed, error) {
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/v1/destroySLVContract?addr=%s", srvUrl, addr))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data ContractDestroyed
|
||||||
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
|
||||||
|
return &data, decoder.Decode(&data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IncrementCount(addr string, count string) (*CountIncremented, error) {
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/v1/incrementCount%s?addr=%s", srvUrl, count, addr))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var blockNumber CountIncremented
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
err = decoder.Decode(&blockNumber)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &blockNumber, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetStorageSlotKey(contract string, label string) (*StorageKey, error) {
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/v1/getStorageKey?contract=%s&label=%s", srvUrl, contract, label))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var key StorageKey
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
err = decoder.Decode(&key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ClearWatchedAddresses(gethRPCClient *rpc.Client) error {
|
||||||
|
gethMethod := "statediff_watchAddress"
|
||||||
|
args := []types.WatchAddressArg{}
|
||||||
|
|
||||||
|
// Clear watched addresses
|
||||||
|
gethErr := gethRPCClient.Call(nil, gethMethod, types.Clear, args)
|
||||||
|
if gethErr != nil {
|
||||||
|
return gethErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Create2Contract(contractName string, salt string) (*ContractDeployed, error) {
|
||||||
|
res, err := http.Get(fmt.Sprintf("%s/v1/create2Contract?contract=%s&salt=%s", srvUrl, contractName, salt))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var contract ContractDeployed
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(res.Body)
|
||||||
|
err = decoder.Decode(&contract)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &contract, nil
|
||||||
|
}
|
||||||
|
|||||||
+83
-30
@@ -16,8 +16,8 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/ipld-eth-server/pkg/eth"
|
"github.com/vulcanize/ipld-eth-server/v4/pkg/eth"
|
||||||
integration "github.com/vulcanize/ipld-eth-server/test"
|
integration "github.com/vulcanize/ipld-eth-server/v4/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
const nonExistingBlockHash = "0x111111111111111111111111111111111111111111111111111111111111111"
|
const nonExistingBlockHash = "0x111111111111111111111111111111111111111111111111111111111111111"
|
||||||
@@ -49,11 +49,14 @@ var _ = Describe("Integration test", func() {
|
|||||||
var txErr error
|
var txErr error
|
||||||
sleepInterval := 2 * time.Second
|
sleepInterval := 2 * time.Second
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
if directProxyEthCalls {
|
||||||
|
Skip("skipping no-direct-proxy-forwarding integration tests")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
Describe("get Block", func() {
|
Describe("get Block", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -123,9 +126,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Transaction", func() {
|
Describe("Transaction", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -157,9 +157,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Receipt", func() {
|
Describe("Receipt", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -187,9 +184,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("FilterLogs", func() {
|
Describe("FilterLogs", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -220,9 +214,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("CodeAt", func() {
|
Describe("CodeAt", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -270,9 +261,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
Describe("Get balance", func() {
|
Describe("Get balance", func() {
|
||||||
address := "0x1111111111111111111111111111111111111112"
|
address := "0x1111111111111111111111111111111111111112"
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
tx, txErr = integration.SendEth(address, "0.01")
|
tx, txErr = integration.SendEth(address, "0.01")
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
})
|
})
|
||||||
@@ -335,10 +323,12 @@ var _ = Describe("Integration test", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Describe("Get Storage", func() {
|
Describe("Get Storage", func() {
|
||||||
|
var slvContract *integration.ContractDeployed
|
||||||
|
var slvCountA *big.Int
|
||||||
|
|
||||||
|
contractSalt := "SLVContractSalt"
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
||||||
|
|
||||||
@@ -418,12 +408,48 @@ var _ = Describe("Integration test", func() {
|
|||||||
Expect(gethStorage).To(Equal(ipldStorage))
|
Expect(gethStorage).To(Equal(ipldStorage))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("get storage for SLV countA after tx", func() {
|
||||||
|
slvContract, contractErr = integration.Create2Contract("SLVToken", contractSalt)
|
||||||
|
Expect(contractErr).ToNot(HaveOccurred())
|
||||||
|
countAIndex := "0x5"
|
||||||
|
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
|
||||||
|
gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
gethCountA := new(big.Int).SetBytes(gethStorage)
|
||||||
|
slvCountA = gethCountA
|
||||||
|
|
||||||
|
ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
ipldCountA := new(big.Int).SetBytes(ipldStorage)
|
||||||
|
Expect(ipldCountA.String()).To(Equal(slvCountA.String()))
|
||||||
|
|
||||||
|
_, txErr = integration.IncrementCount(slvContract.Address, "A")
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
slvCountA.Add(slvCountA, big.NewInt(1))
|
||||||
|
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
|
||||||
|
ipldStorage, err = ipldClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
ipldCountA = new(big.Int).SetBytes(ipldStorage)
|
||||||
|
Expect(ipldCountA.String()).To(Equal(slvCountA.String()))
|
||||||
|
})
|
||||||
|
|
||||||
It("get storage after self destruct", func() {
|
It("get storage after self destruct", func() {
|
||||||
totalSupplyIndex := "0x2"
|
totalSupplyIndex := "0x2"
|
||||||
|
countAIndex := "0x5"
|
||||||
|
|
||||||
tx, err := integration.DestroyContract(contract.Address)
|
tx, err := integration.DestroyContract(contract.Address)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
slvTx, err := integration.DestroyContract(slvContract.Address)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
time.Sleep(sleepInterval)
|
time.Sleep(sleepInterval)
|
||||||
|
|
||||||
gethStorage1, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1))
|
gethStorage1, err := gethClient.StorageAt(ctx, common.HexToAddress(contract.Address), common.HexToHash(totalSupplyIndex), big.NewInt(tx.BlockNumber-1))
|
||||||
@@ -447,14 +473,44 @@ var _ = Describe("Integration test", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
Expect(ipldStorage2).To(Equal(ipldStorage3))
|
Expect(ipldStorage2).To(Equal(ipldStorage3))
|
||||||
|
|
||||||
|
// Check for SLV contract
|
||||||
|
gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), big.NewInt(slvTx.BlockNumber))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(gethStorage).To(Equal(eth.EmptyNodeValue))
|
||||||
|
|
||||||
|
ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), big.NewInt(slvTx.BlockNumber))
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(ipldStorage).To(Equal(gethStorage))
|
||||||
|
|
||||||
|
slvCountA.Set(big.NewInt(0))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("get storage after redeploying", func() {
|
||||||
|
slvContract, contractErr = integration.Create2Contract("SLVToken", contractSalt)
|
||||||
|
Expect(contractErr).ToNot(HaveOccurred())
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
|
||||||
|
countAIndex := "0x5"
|
||||||
|
|
||||||
|
gethStorage, err := gethClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
gethCountA := new(big.Int).SetBytes(gethStorage)
|
||||||
|
Expect(gethCountA.String()).To(Equal(slvCountA.String()))
|
||||||
|
|
||||||
|
ipldStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(slvContract.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
ipldCountA := new(big.Int).SetBytes(ipldStorage)
|
||||||
|
Expect(ipldCountA.String()).To(Equal(slvCountA.String()))
|
||||||
|
|
||||||
|
Expect(gethStorage).To(Equal(ipldStorage))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("eth call", func() {
|
Describe("eth call", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
contract, contractErr = integration.DeployContract()
|
contract, contractErr = integration.DeployContract()
|
||||||
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
erc20TotalSupply, bigIntResult = new(big.Int).SetString("1000000000000000000000", 10)
|
||||||
|
|
||||||
@@ -505,9 +561,6 @@ var _ = Describe("Integration test", func() {
|
|||||||
|
|
||||||
Describe("Chain ID", func() {
|
Describe("Chain ID", func() {
|
||||||
It("Check chain id", func() {
|
It("Check chain id", func() {
|
||||||
if directProxyEthCalls {
|
|
||||||
Skip("skipping no-direct-proxy-forwarding integration tests")
|
|
||||||
}
|
|
||||||
gethChainId, err := gethClient.ChainID(ctx)
|
gethChainId, err := gethClient.ChainID(ctx)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
@@ -537,7 +590,7 @@ func compareTxs(tx1 *types.Transaction, tx2 *types.Transaction) {
|
|||||||
Expect(tx1.Hash()).To(Equal(tx2.Hash()))
|
Expect(tx1.Hash()).To(Equal(tx2.Hash()))
|
||||||
Expect(tx1.Size()).To(Equal(tx2.Size()))
|
Expect(tx1.Size()).To(Equal(tx2.Size()))
|
||||||
|
|
||||||
signer := types.NewEIP155Signer(big.NewInt(4))
|
signer := types.NewEIP155Signer(big.NewInt(99))
|
||||||
|
|
||||||
gethSender, err := types.Sender(signer, tx1)
|
gethSender, err := types.Sender(signer, tx1)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|||||||
@@ -0,0 +1,670 @@
|
|||||||
|
package integration_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
integration "github.com/vulcanize/ipld-eth-server/v4/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
gethMethod = "statediff_watchAddress"
|
||||||
|
ipldMethod = "vdb_watchAddress"
|
||||||
|
|
||||||
|
sleepInterval = 2 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("WatchAddress integration test", func() {
|
||||||
|
dbWrite, err := strconv.ParseBool(os.Getenv("DB_WRITE"))
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
gethHttpPath := "http://127.0.0.1:8545"
|
||||||
|
gethRPCClient, err := rpc.Dial(gethHttpPath)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
ipldEthHttpPath := "http://127.0.0.1:8081"
|
||||||
|
ipldClient, err := ethclient.Dial(ipldEthHttpPath)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ipldRPCClient, err := rpc.Dial(ipldEthHttpPath)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
var (
|
||||||
|
ctx = context.Background()
|
||||||
|
|
||||||
|
txErr error
|
||||||
|
contractErr error
|
||||||
|
incErr error
|
||||||
|
|
||||||
|
contract1 *integration.ContractDeployed
|
||||||
|
contract2 *integration.ContractDeployed
|
||||||
|
contract3 *integration.ContractDeployed
|
||||||
|
|
||||||
|
countAIndex string
|
||||||
|
|
||||||
|
prevBalance1 *big.Int
|
||||||
|
prevBalance2 *big.Int
|
||||||
|
prevBalance3 *big.Int
|
||||||
|
|
||||||
|
actualBalance1 *big.Int
|
||||||
|
actualBalance2 *big.Int
|
||||||
|
actualBalance3 *big.Int
|
||||||
|
|
||||||
|
prevCountA1 *big.Int
|
||||||
|
prevCountA2 *big.Int
|
||||||
|
prevCountA3 *big.Int
|
||||||
|
|
||||||
|
actualCountA1 *big.Int
|
||||||
|
actualCountA2 *big.Int
|
||||||
|
actualCountA3 *big.Int
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
if !dbWrite {
|
||||||
|
Skip("skipping WatchAddress API integration tests")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
It("test init", func() {
|
||||||
|
// Deploy three contracts
|
||||||
|
contract1, contractErr = integration.DeploySLVContract()
|
||||||
|
Expect(contractErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
contract2, contractErr = integration.DeploySLVContract()
|
||||||
|
Expect(contractErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
contract3, contractErr = integration.DeploySLVContract()
|
||||||
|
Expect(contractErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// Get the storage slot key
|
||||||
|
storageSlotAKey, err := integration.GetStorageSlotKey("SLVToken", "countA")
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countAIndex = storageSlotAKey.Key
|
||||||
|
|
||||||
|
// Clear out watched addresses
|
||||||
|
err = integration.ClearWatchedAddresses(gethRPCClient)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// Get initial balances for all the contracts
|
||||||
|
// Contract 1
|
||||||
|
actualBalance1 = big.NewInt(0)
|
||||||
|
initBalance1, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(initBalance1.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1 = big.NewInt(0)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
actualBalance2 = big.NewInt(0)
|
||||||
|
initBalance2, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(initBalance2.String()).To(Equal(actualBalance2.String()))
|
||||||
|
prevBalance2 = big.NewInt(0)
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
actualBalance3 = big.NewInt(0)
|
||||||
|
initBalance3, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(initBalance3.String()).To(Equal(actualBalance3.String()))
|
||||||
|
prevBalance3 = big.NewInt(0)
|
||||||
|
|
||||||
|
// Get initial storage values for the contracts
|
||||||
|
// Contract 1, countA
|
||||||
|
actualCountA1 = big.NewInt(0)
|
||||||
|
ipldCountA1Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ipldCountA1 := new(big.Int).SetBytes(ipldCountA1Storage)
|
||||||
|
Expect(ipldCountA1.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1 = big.NewInt(0)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
actualCountA2 = big.NewInt(0)
|
||||||
|
ipldCountA2Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ipldCountA2 := new(big.Int).SetBytes(ipldCountA2Storage)
|
||||||
|
Expect(ipldCountA2.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA2 = big.NewInt(0)
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
actualCountA3 = big.NewInt(0)
|
||||||
|
ipldCountA3Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
ipldCountA3 := new(big.Int).SetBytes(ipldCountA3Storage)
|
||||||
|
Expect(ipldCountA3.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA3 = big.NewInt(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
defer It("test cleanup", func() {
|
||||||
|
// Clear out watched addresses
|
||||||
|
err := integration.ClearWatchedAddresses(gethRPCClient)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("no contracts being watched", func() {
|
||||||
|
It("indexes state for all the contracts", func() {
|
||||||
|
// WatchedAddresses = []
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1.Set(actualBalance1)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String()))
|
||||||
|
prevBalance2.Set(actualBalance2)
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String()))
|
||||||
|
prevBalance3.Set(actualBalance3)
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1.Set(actualCountA1)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA2.Set(actualCountA2)
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(actualCountA3.String()))
|
||||||
|
prevCountA3.Set(actualCountA3)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("one contract being watched", func() {
|
||||||
|
It("indexes state only for the watched contract", func() {
|
||||||
|
operation := sdtypes.Add
|
||||||
|
args := []sdtypes.WatchAddressArg{
|
||||||
|
{
|
||||||
|
Address: contract1.Address,
|
||||||
|
CreatedAt: uint64(contract1.BlockNumber),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// WatchedAddresses = [Contract1]
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1.Set(actualBalance1)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String()))
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String()))
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1.Set(actualCountA1)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(prevCountA2.String()))
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(prevCountA3.String()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("contract added to a non-empty watch-list", func() {
|
||||||
|
It("indexes state only for the watched contracts", func() {
|
||||||
|
operation := sdtypes.Add
|
||||||
|
args := []sdtypes.WatchAddressArg{
|
||||||
|
{
|
||||||
|
Address: contract2.Address,
|
||||||
|
CreatedAt: uint64(contract2.BlockNumber),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// WatchedAddresses = [Contract1, Contract2]
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1.Set(actualBalance1)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String()))
|
||||||
|
prevBalance2.Set(actualBalance2)
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String()))
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1.Set(actualCountA1)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA2.Set(actualCountA2)
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(prevCountA3.String()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("contract removed from the watch-list", func() {
|
||||||
|
It("indexes state only for the watched contract", func() {
|
||||||
|
operation := sdtypes.Remove
|
||||||
|
args := []sdtypes.WatchAddressArg{
|
||||||
|
{
|
||||||
|
Address: contract1.Address,
|
||||||
|
CreatedAt: uint64(contract1.BlockNumber),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// WatchedAddresses = [Contract2]
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(prevBalance1.String()))
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String()))
|
||||||
|
prevBalance2.Set(actualBalance2)
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String()))
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(prevCountA1.String()))
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA2.Set(actualCountA2)
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(prevCountA3.String()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("list of watched addresses set", func() {
|
||||||
|
It("indexes state only for the watched contracts", func() {
|
||||||
|
operation := sdtypes.Set
|
||||||
|
args := []sdtypes.WatchAddressArg{
|
||||||
|
{
|
||||||
|
Address: contract1.Address,
|
||||||
|
CreatedAt: uint64(contract1.BlockNumber),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Address: contract3.Address,
|
||||||
|
CreatedAt: uint64(contract3.BlockNumber),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// WatchedAddresses = [Contract1, Contract3]
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1.Set(actualBalance1)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String()))
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String()))
|
||||||
|
prevBalance3.Set(actualBalance3)
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1.Set(actualCountA1)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(prevCountA2.String()))
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(actualCountA3.String()))
|
||||||
|
prevCountA3.Set(actualCountA3)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("list of watched addresses cleared", func() {
|
||||||
|
It("indexes state for all the contracts", func() {
|
||||||
|
operation := sdtypes.Clear
|
||||||
|
args := []sdtypes.WatchAddressArg{}
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
// WatchedAddresses = []
|
||||||
|
// Send eth to all three contract accounts
|
||||||
|
// Contract 1
|
||||||
|
_, txErr = integration.SendEth(contract1.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String()))
|
||||||
|
prevBalance1.Set(actualBalance1)
|
||||||
|
|
||||||
|
// Contract 2
|
||||||
|
_, txErr = integration.SendEth(contract2.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String()))
|
||||||
|
prevBalance2.Set(actualBalance2)
|
||||||
|
|
||||||
|
// Contract 3
|
||||||
|
_, txErr = integration.SendEth(contract3.Address, "0.01")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(txErr).ToNot(HaveOccurred())
|
||||||
|
actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000))
|
||||||
|
|
||||||
|
balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String()))
|
||||||
|
prevBalance3.Set(actualBalance3)
|
||||||
|
|
||||||
|
// Increment counts
|
||||||
|
// Contract 1, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract1.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA1.Add(actualCountA1, big.NewInt(1))
|
||||||
|
|
||||||
|
countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage)
|
||||||
|
Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String()))
|
||||||
|
prevCountA1.Set(actualCountA1)
|
||||||
|
|
||||||
|
// Contract 2, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract2.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA2.Add(actualCountA2, big.NewInt(1))
|
||||||
|
|
||||||
|
countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage)
|
||||||
|
Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String()))
|
||||||
|
prevCountA2.Set(actualCountA2)
|
||||||
|
|
||||||
|
// Contract 3, countA
|
||||||
|
_, incErr = integration.IncrementCount(contract3.Address, "A")
|
||||||
|
time.Sleep(sleepInterval)
|
||||||
|
Expect(incErr).ToNot(HaveOccurred())
|
||||||
|
actualCountA3.Add(actualCountA3, big.NewInt(1))
|
||||||
|
|
||||||
|
countA3AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract3.Address), common.HexToHash(countAIndex), nil)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
countA3AfterIncrement := new(big.Int).SetBytes(countA3AfterIncrementStorage)
|
||||||
|
Expect(countA3AfterIncrement.String()).To(Equal(actualCountA3.String()))
|
||||||
|
prevCountA3.Set(actualCountA3)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Context("with invalid args", func() {
|
||||||
|
It("returns an error on invalid operation arg", func() {
|
||||||
|
operation := "WrongOp"
|
||||||
|
args := []sdtypes.WatchAddressArg{}
|
||||||
|
|
||||||
|
gethErr := gethRPCClient.Call(nil, gethMethod, operation, args)
|
||||||
|
Expect(gethErr).To(HaveOccurred())
|
||||||
|
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).To(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(ipldErr).To(Equal(gethErr))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns an error on args of invalid type", func() {
|
||||||
|
operation := sdtypes.Add
|
||||||
|
args := []string{"WrongArg"}
|
||||||
|
|
||||||
|
gethErr := gethRPCClient.Call(nil, gethMethod, operation, args)
|
||||||
|
Expect(gethErr).To(HaveOccurred())
|
||||||
|
|
||||||
|
ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args)
|
||||||
|
Expect(ipldErr).To(HaveOccurred())
|
||||||
|
|
||||||
|
Expect(ipldErr).To(Equal(gethErr))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user