From 2a96a8b179ca22a4689eabfccf59825073d70d8d Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:28:25 -0300 Subject: [PATCH 01/11] create env example --- .env.example | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..143012a --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +LOG_LEVEL="info" # debug, info, warn, error +DB_URL="postgres://user:password@localhost:5432/dbName" # URL to connect to the postgres database +WORKER_NUM=15 # Number of workers to run concurrent alchemy/EL node requests +ALCHEMY_URL="https://eth-mainnet.g.alchemy.com/v2/KEY" # Alchemy API URL +EL_ENDPOINT="http://localhost:8545" # Ethereum Layer 1 endpoint, can also be alchemy or infura From f08a46cf782c47425658d86eab659cb88150b4fc Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 12:28:31 -0300 Subject: [PATCH 02/11] dockerize --- Dockerfile | 22 ++++++++++++++++++++++ docker-compose.yml | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3c24521 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM golang:1.21-alpine as builder +RUN apk add --update git +RUN apk add --update gcc +RUN apk add --update g++ +RUN apk add --update openssh-client +RUN apk add --update make + +RUN mkdir /app +WORKDIR /app +ADD . . + +RUN go get +RUN go build -o ./build/eth_pokhar + + +FROM alpine:latest +RUN apk --no-cache add ca-certificates +WORKDIR / +COPY --from=builder /app/build/eth_pokhar ./ +COPY --from=builder /app/db/migrations ./db/migrations + +ENTRYPOINT ["sh", "-c"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..46c12b0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,24 @@ +version: "3.7" + +services: + eth-pokhar: + build: + context: ./ + dockerfile: Dockerfile + init: true + command: >- + "./eth_pokhar beacon_depositors_transactions + --log-level=${LOG_LEVEL} + --el-endpoint=${EL_ENDPOINT} + --db-url=${DB_URL} + --workers-num=${WORKER_NUM} + --alchemy-url=${ALCHEMY_URL} + && + ./eth_pokhar identify + --log-level=${LOG_LEVEL} + --el-endpoint=${EL_ENDPOINT} + --db-url=${DB_URL} + --workers-num=${WORKER_NUM} + --alchemy-url=${ALCHEMY_URL} + --recreate-table" + network_mode: "host" From 7bd12d7c6857c48e9435c68148200ddce7905d9a Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:16:52 -0300 Subject: [PATCH 03/11] add db to docker --- .env.example | 5 +++++ .gitignore | 2 ++ docker-compose.yml | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/.env.example b/.env.example index 143012a..1d9875e 100644 --- a/.env.example +++ b/.env.example @@ -3,3 +3,8 @@ DB_URL="postgres://user:password@localhost:5432/dbName" # URL to connect to the WORKER_NUM=15 # Number of workers to run concurrent alchemy/EL node requests ALCHEMY_URL="https://eth-mainnet.g.alchemy.com/v2/KEY" # Alchemy API URL EL_ENDPOINT="http://localhost:8545" # Ethereum Layer 1 endpoint, can also be alchemy or infura + +DATABASE_NAME=name # Your database name +DATABASE_USERNAME=user # Your database username +DATABASE_PASSWORD=pass # Your database password +LOCAL_PORT=5439 # Port where you connect to the database container diff --git a/.gitignore b/.gitignore index 97b7a6d..461174a 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,5 @@ .env .vscode + +app-data diff --git a/docker-compose.yml b/docker-compose.yml index 46c12b0..f1c3498 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,3 +22,16 @@ services: --alchemy-url=${ALCHEMY_URL} --recreate-table" network_mode: "host" + depends_on: + - db + db: + image: postgres + restart: always + environment: + POSTGRES_USER: ${DATABASE_USERNAME} + POSTGRES_PASSWORD: ${DATABASE_PASSWORD} + POSTGRES_DB: ${DATABASE_NAME} + volumes: + - ./app-data/:/var/lib/postgresql/data/ + ports: + - "127.0.0.1:${LOCAL_PORT}:5432" From d8074d0299a6b1a187c8cb7642fe5c888ced8ec3 Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:39:40 -0300 Subject: [PATCH 04/11] change log into info --- beacon-depositors-transactions/routines.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/beacon-depositors-transactions/routines.go b/beacon-depositors-transactions/routines.go index 04a22e8..9cc37b9 100644 --- a/beacon-depositors-transactions/routines.go +++ b/beacon-depositors-transactions/routines.go @@ -100,7 +100,7 @@ func (b *BeaconDepositorsTransactions) downloadBeaconDeposits() { if err != nil { log.Fatalf("Error parsing block number: %s", err.Error()) } - log.Debugf("Downloaded 1000 more deposits on block %d", num) + log.Infof("Downloaded 1000 more deposits on block %d", num) params.PageKey = newPageKey firstCall = false err = b.processDepositTransfers(newTransfers, b.iConfig.Workers) From 6f43bfeb5b340963a5ac1284ac471f45aaad269f Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:40:43 -0300 Subject: [PATCH 05/11] create dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..7ff9721 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +app-data From 4e34031174dfbb05ac7b7ba91cd911f03225110b Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:41:03 -0300 Subject: [PATCH 06/11] update readme --- README.md | 164 ++++++++++++++++++++++++- repository-images/table_priorities.jpg | Bin 0 -> 70118 bytes 2 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 repository-images/table_priorities.jpg diff --git a/README.md b/README.md index 534adc5..66786af 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,160 @@ # eth-pokhar -Tool to identify validators <> entities in the Ethereum consensus layer +Eth-pokhar is a go tool that helps in the process of identifying the pool/entity that operates each validator in the Ethereum beacon chain. + +Identifying staking entities is tricky since this isn’t on-chain data in most cases. In the case of pools like Lido and Rocketpool, since they use smart contracts for creating their validators, the data is on-chain and can be easily identified. + +For the rest of the entities, other methods can be used like observing patterns in the depositor addresses like the ones found in this repository: [eth-deposits](https://github.com/alrevuelta/eth-deposits), and other off-chain data from contacts/data sources. When creating validators an address must deposit 32 ETH on the beaconchain contract. In most cases, entities share the same deposit address throughout multiple validators. By knowing a few of these cases, one can extrapolate the information and identify all of the validators that were generated by those addresses and thus identify the entities. + +This tool is used for tagging validators in [ethseer.io](https://ethseer.io/?network=mainnet). + +## Pre-requisites + +To use the tool, the following requirements must be met: + +- An alchemy API key (the free tier is enough). See [here](https://www.alchemy.com/pricing) +- Access to a Ethereum EL node + +Expect this tool to make the following amount of requests to the Ethereum EL node on the first run: + +- ~1.5m [eth_getTransactionReceipt](https://docs.alchemy.com/reference/eth-gettransactionreceipt) requests +- ~1.5m [eth_call](https://docs.alchemy.com/reference/eth-call) requests + +And the following amount of requests to the alchemy API on each run: + +- ~300k [alchemy_getAssetTransfers](https://docs.alchemy.com/reference/alchemy-getassettransfers) requests + +## Available commands + +### `beacon_depositors_transactions` + +Fetches the transactions of the depositors of the beaconchain contract. + +Available options (configurable in the `.env` file): + +``` +OPTIONS: + --el-endpoint value Execution node endpoint (default: http://localhost:8545) [$EL_ENDPOINT] + --db-url value Database where to store transactions (default: postgres://user:password@localhost:5432/dbName) [$DB_URL] + --log-level value Log level: debug, warn, info, error (default: info) [$LOG_LEVEL] + --workers-num value Number of workers to process API requests (default: 10) [$WORKER_NUM] + --alchemy-url value Alchemy url (default: https://eth-mainnet.g.alchemy.com/v2/KEY) [$ALCHEMY_URL] + --help, -h show help +``` + +### `identify` + +Identify the pool in which validators are participating or the entity who operates the validators. + +Available options (configurable in the `.env` file): + +``` +OPTIONS: + --el-endpoint value Execution node endpoint (default: http://localhost:8545) [$EL_ENDPOINT] + --db-url value Database where to store transactions (default: postgres://user:password@localhost:5432/dbName) [$DB_URL] + --log-level value Log level: debug, warn, info, error (default: info) [$LOG_LEVEL] + --alchemy-url value Alchemy url (default: https://eth-mainnet.g.alchemy.com/v2/KEY) [$ALCHEMY_URL] + --workers-num value Number of workers to process API requests (default: 10) [$WORKER_NUM] + --recreate-table Recreate the t_identified_validators table, meant to be used when one of the methodologies of identification changes (default: false) + --help, -h show help +``` + +## Running with Docker (recommended) + +To run the tool with docker, you can use the following commands: + +First, create a `.env` file on the root folder. You can use the `.env.example` file as a template. + +Then, run the following command to build the tool: + +```bash +docker-compose build +``` + +Finally, run the tool with the following command: + +```bash +docker-compose up -d +``` + +## Output + +The tool will create a database with the following tables: + +### `t_beacon_deposits` + +This table stores the deposits made to the beaconchain contract. It has the following columns: + +- `f_block_num`: The block number in which the deposit was made. +- `f_depositor`: The address of the depositor. +- `f_tx_hash`: The transaction hash of the deposit. +- `f_validator_pubkey`: The public key of the validator. + +### `t_beacon_depositors_transactions` + +This table stores the incoming/outgoing transactions of the depositors of the beaconchain contract. It has the following columns: + +- `f_block_num`: The block number in which the transaction was made. +- `f_value`: The value of the transaction. +- `f_from`: The address from which the transaction was made. +- `f_to`: The address to which the transaction was made. +- `f_tx_hash`: The transaction hash of the transaction. +- `f_depositor`: The address of the depositor to which the transaction is related. + +### `t_depositors_insert` + +This table stores the depositors that are used to identify the pool in which the validators are participating See [Utilizing custom off-chain data](#utilizing-custom-off-chain-data) for more information. It has the following columns: + +- `f_depositor`: The address of the depositor. +- `f_pool_name`: The name of the pool in which the validators are participating. + +### `t_validators_insert` + +This table stores the validators that are used to identify the pool in which the validators are participating. See [Utilizing custom off-chain data](#utilizing-custom-off-chain-data) for more information. It has the following columns: + +- `f_validator_pubkey`: The public key of the validator. +- `f_pool_name`: The name of the pool in which the validators are participating. + +### `t_lido` + +This table stores the validators that are participating in the Lido pool. See [Lido operators](https://operatorportal.lido.fi/) for more information. It has the following columns: + +- `f_validator_pubkey`: The public key of the validator. +- `f_operator`: The name of the operator of the validator. +- `f_operator_index`: The index of the operator in the Lido pool. + +### `t_rocketpool` + +This table stores the validators that are participating in the Rocketpool pool. It has the following columns: + +- `f_validator_pubkey`: The public key of the validator. + +### `t_identified_validators` (End result) + +This table stores the validators with the pool/entity that operates them. Unidentified validators will have a `f_pool_name` value of `others`. It has the following columns: + +- `f_validator_pubkey`: The public key of the validator. +- `f_pool_name`: The name of the pool in which the validators are participating. + +## Utilizing custom off-chain data + +As mentioned before, the tool can be used to identify validators by using off-chain data. For this purpose, two tables are created in the database on the first run: `t_depositors_insert` and `t_validators_insert`. + +### `t_depositors_insert` + +This table has the columns `f_depositor` and `f_pool_name`. The `identify` command will use this table to identify the pool in which the validators are participating. The `f_depositor` column is the address of the depositor and the `f_pool_name` is the name of the pool in which the validators are participating. All validators that have the same depositor address will be tagged with the `f_pool_name` value. + +### `t_validators_insert` + +This table has the columns `f_validator_pubkey` and `f_pool_name`. The `identify` command will use this table to identify the pool in which the validators are participating. The `f_validator_pubkey` column is the address of the validator and the `f_pool_name` is the name of the pool in which the validators are participating. These values will be used to tag the validators. + +## Identification priority + +Since the end table `t_identified_validators` is the result of the identification process, validators' pool/entity will be tagged in the following order (if the validator is already tagged, the next step will override the previous tag, resulting in the last tag being the one that is stored): + +

+ table_priorities +

## Database migrations @@ -9,3 +163,11 @@ More specifically, one could clean the migrations by forcing the version with `
If specific upgrades or downgrades need to be done manually, one could do this with
`migrate -path database/migration/ -database "postgresql://username:secretkey@localhost:5432/database_name?sslmode=disable" -verbose up` + +## Benchmarks + +TODO + +## Maintainers + +@santi1234567 diff --git a/repository-images/table_priorities.jpg b/repository-images/table_priorities.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3c99b23ec9c9aa114ea47ccb34ab01b61bdb9bf7 GIT binary patch literal 70118 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

xbWN-Rj_4sJ9KbT;bGHZv<*#qd?qlZsH{R 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 SukHC~#?k-4L!$io;=ch>)!MxP literal 0 HcmV?d00001 From aae3c284d3d11916beaa525760ccb2573bc8a5e7 Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:06:52 -0300 Subject: [PATCH 07/11] update logs --- .../beacon_depositors_transactions.go | 6 ++--- identify/identify.go | 27 +++++++++++++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/beacon-depositors-transactions/beacon_depositors_transactions.go b/beacon-depositors-transactions/beacon_depositors_transactions.go index f9e12a2..608666f 100644 --- a/beacon-depositors-transactions/beacon_depositors_transactions.go +++ b/beacon-depositors-transactions/beacon_depositors_transactions.go @@ -86,7 +86,7 @@ func (b *BeaconDepositorsTransactions) Run() { log.Info("Downloading new beacon deposits...") b.downloadBeaconDeposits() duration := time.Since(initTime).Seconds() - log.Info("Finished downloading new beacon deposits in ", duration) + log.Infof("Finished downloading new beacon deposits in %f seconds", duration) } if !b.stop { @@ -94,10 +94,10 @@ func (b *BeaconDepositorsTransactions) Run() { log.Info("Updating depositors transactions...") b.updateDepositorsTransactions() duration := time.Since(initTime).Seconds() - log.Info("Finished updating depositors transactions in ", duration) + log.Infof("Finished updating depositors transactions in %f seconds", duration) } totalDuration := time.Since(totalInitTime).Seconds() - log.Info("Finished beacon_depositors_transactions in ", totalDuration) + log.Infof("Finished beacon_depositors_transactions in %f seconds", totalDuration) b.CloseConnections() log.Debug("Sending signal that beacon_depositors_transactions finished") diff --git a/identify/identify.go b/identify/identify.go index f845dd6..5dfae73 100644 --- a/identify/identify.go +++ b/identify/identify.go @@ -70,47 +70,57 @@ func (i *Identify) Run() { log.Info("Starting Identify routine") if i.iConfig.RecreateTable && !i.stop { + startTime := time.Now() log.Info("Truncating identified validators table") err := i.dbClient.TruncateIdentifiedValidators() if err != nil { log.Fatalf("Error truncating identified validators table: %v", err) } - log.Info("Truncated identified validators") + endTime := time.Now() + log.Infof("Truncated identified validators table in %v", endTime.Sub(startTime)) } if !i.stop { + startTime := time.Now() log.Info("Adding new validators to database") err := i.dbClient.AddNewValidators() if err != nil { log.Fatalf("Error adding new validators to database: %v", err) } - log.Info("Added new validators to database") + endTime := time.Now() + log.Infof("Added new validators to database in %v", endTime.Sub(startTime)) } if !i.stop { + startTime := time.Now() log.Info("Applying validators insert") err := i.dbClient.ApplyValidatorsInsert() if err != nil { log.Fatalf("Error applying validators insert: %v", err) } - log.Info("Applied validators insert") + endTime := time.Now() + log.Infof("Applied validators insert in %v", endTime.Sub(startTime)) } if !i.stop { + startTime := time.Now() log.Info("Applying depositors insert") err := i.dbClient.ApplyDepositorsInsert() if err != nil { log.Fatalf("Error applying depositors insert: %v", err) } - log.Info("Applied depositors insert") + endTime := time.Now() + log.Infof("Applied depositors insert in %v", endTime.Sub(startTime)) } if !i.stop { + startTime := time.Now() log.Info("Identifying coinbase validators") err := i.dbClient.IdentifyCoinbaseValidators() if err != nil { log.Fatalf("Error identifying coinbase validators: %v", err) } - log.Info("Identified coinbase validators") + endTime := time.Now() + log.Infof("Identified coinbase validators in %v", endTime.Sub(startTime)) } if !i.stop { @@ -123,7 +133,7 @@ func (i *Identify) Run() { } log.WithFields(log.Fields{ "NewDetectedKeys": len(newRocketpoolKeys), - "Duration": time.Since(startTime), + "Duration (s)": time.Since(startTime), }).Info("RocketPool Keys:") i.dbClient.CopyRocketpoolValidators(newRocketpoolKeys) err = i.dbClient.IdentifyRocketpoolValidators() @@ -133,10 +143,11 @@ func (i *Identify) Run() { log.Info("Identified rocketpool validators") } if !i.stop { + startTime := time.Now() log.Info("Identifying lido validators") i.IdentifyLidoValidators() - - log.Info("Identified lido validators") + endTime := time.Now() + log.Infof("Identified lido validators in %v", endTime.Sub(startTime)) } endTime := time.Now() From f8de9b450aa0fab0b05eae25ee26d8289071d901 Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:07:01 -0300 Subject: [PATCH 08/11] add benchmarks --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66786af..a3235c3 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,19 @@ If specific upgrades or downgrades need to be done manually, one could do this w ## Benchmarks -TODO +Utilizing Alchemy as EL node and API, with a local database, these are the benchmarks for the tool: + +- `beacon_depositors_transactions`: + - Fetching deposits on the first run: 1h 16m + - Fetching depositors transactions: 15h 22m + - Total time: 16h 38m +- `identify`: + - Fetching Rocketpool validators on the first run: 38m + - Fetching Lido validators on the first run: 4h 13m + - Total time: 4h 51m +- Total time for the first run: 21h 29m + +If running the tool on a weekly basis, expect the tool to take around 16h to run considering that the process of fetching depositors transactions will be done on every run. ## Maintainers From d77e5f0a4350245e145f912ab7aa95b12bb7b39a Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:08:38 -0300 Subject: [PATCH 09/11] add note --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a3235c3..d502a90 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,8 @@ This table stores the validators with the pool/entity that operates them. Uniden As mentioned before, the tool can be used to identify validators by using off-chain data. For this purpose, two tables are created in the database on the first run: `t_depositors_insert` and `t_validators_insert`. +**Important note**: addresses must be all lowercase and without the `0x` prefix. + ### `t_depositors_insert` This table has the columns `f_depositor` and `f_pool_name`. The `identify` command will use this table to identify the pool in which the validators are participating. The `f_depositor` column is the address of the depositor and the `f_pool_name` is the name of the pool in which the validators are participating. All validators that have the same depositor address will be tagged with the `f_pool_name` value. From b6ed302d039c6544ada2fac8a46e46934a5af6d9 Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Thu, 15 Feb 2024 17:22:19 -0300 Subject: [PATCH 10/11] add restart policy --- docker-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index f1c3498..f8d0652 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,11 @@ services: network_mode: "host" depends_on: - db + deploy: + restart_policy: + condition: on-failure + max_attempts: 5 + db: image: postgres restart: always From 43872fc1afcde39a0c2bd2cef92eb9c0001cf47b Mon Sep 17 00:00:00 2001 From: santi1234567 <45318759+santi1234567@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:19:18 -0300 Subject: [PATCH 11/11] rmeove unused apks --- Dockerfile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3c24521..d2e9c73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,4 @@ FROM golang:1.21-alpine as builder -RUN apk add --update git -RUN apk add --update gcc -RUN apk add --update g++ -RUN apk add --update openssh-client -RUN apk add --update make - RUN mkdir /app WORKDIR /app ADD . . @@ -14,7 +8,6 @@ RUN go build -o ./build/eth_pokhar FROM alpine:latest -RUN apk --no-cache add ca-certificates WORKDIR / COPY --from=builder /app/build/eth_pokhar ./ COPY --from=builder /app/db/migrations ./db/migrations