Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

account min-balance #825

Closed
wants to merge 62 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
3e9c0c3
markdown lint
Jan 14, 2022
eadb8a7
Merge remote-tracking branch 'origin' into tzaffi/min-balance
Jan 14, 2022
1432816
update submodule
Jan 15, 2022
957070c
more control ovedr submodule
Jan 15, 2022
5a67bc5
typo
Jan 15, 2022
f0da64b
experimental differ scripts
Jan 15, 2022
bbfb7fe
reporting diffs
Jan 15, 2022
45babc0
reasonable looking reports
Jan 15, 2022
7f658fe
human friendly parity report
Jan 16, 2022
98205d0
maybe now it's human legible
Jan 16, 2022
0e0f61f
maybe now it human legible
Jan 16, 2022
cdd986e
reporting in good shape
Jan 16, 2022
779a347
summary code
Jan 16, 2022
2851191
wip
Jan 17, 2022
bde9d1a
rm
Jan 17, 2022
23a7264
rm
Jan 17, 2022
b727bdb
yaml is the best
Jan 17, 2022
ceb74ae
looking good
Jan 17, 2022
a7335a0
bare essentials diff of swaggers
Jan 17, 2022
997de01
set asserted diffs as drops and full
Jan 17, 2022
3405292
simplification
Jan 17, 2022
207fcfa
simplify
Jan 17, 2022
bf42127
imports reorg
Jan 17, 2022
8281a16
simplify
Jan 17, 2022
835b4b2
refresh submodule
Jan 17, 2022
7814815
pyaml in the right requirements.txt
Jan 17, 2022
81f5ab6
add algod v. indexer parity check to circle
Jan 17, 2022
1f73166
parity test
Jan 17, 2022
73ff3fe
try parity again (.PHONYness)
Jan 17, 2022
0f701cb
sync instead of force
Jan 17, 2022
b7dc9c0
don't need requirements in parity anymore
Jan 17, 2022
600c873
EOL
Jan 17, 2022
4ff2e35
Update parity/test_indexer_v_algod.py
tzaffi Jan 17, 2022
f3fe681
remove extra space
Jan 17, 2022
289bf2b
investigatory comment
Jan 18, 2022
e352b1c
update swagger for min-balance and a couple of others out of sync
Jan 19, 2022
a5ed930
stub the MinBalance using an Enricher()
Jan 20, 2022
e225d5a
pass lint
Jan 20, 2022
c5730ef
skip parity test by removing it from .PHONY
Jan 20, 2022
82341ba
do pg port changes bork circle?
Jan 20, 2022
73d6cae
did the tests get borked? yes - common.sh actually needs port 5434
Jan 20, 2022
a18bc0b
rename swagger make command
Jan 20, 2022
317ea61
remove parity test from Circle (memorializing issue https://github.co…
Jan 20, 2022
aa8673b
revert
Jan 20, 2022
84846e2
min-balance should not be required, especially when rewinding
Jan 21, 2022
a9906aa
enriching fetchAccounts with MinBalance
Jan 25, 2022
054de94
Update Makefile
tzaffi Jan 25, 2022
f8e5b39
Update Makefile
tzaffi Jan 25, 2022
7ef690b
oops == nil
tzaffi Jan 25, 2022
2bc1eb1
go fmt
Jan 25, 2022
e73ec07
lint
Jan 25, 2022
b11545f
Update api/handlers_test.go
tzaffi Jan 25, 2022
fe41ad9
Merge remote-tracking branch 'origin' into tzaffi/min-balance
Jan 25, 2022
6e8aa8b
breakout algodvindexer into its own PR
Jan 25, 2022
522a03a
re-merge
Jan 25, 2022
f31b049
Update accounting/calculated.go
tzaffi Jan 25, 2022
2610b8a
Merge remote-tracking branch 'origin/develop' into tzaffi/min-balance
Jan 25, 2022
e28e1d0
merge
Jan 25, 2022
bbd3c66
revert
Jan 25, 2022
aca823c
Merge branch 'develop' of https://github.com/algorand/indexer into tz…
Jan 28, 2022
481e45d
replace entire &blockheader with &blockheader.CurrentProtocol
Jan 31, 2022
d45da61
fmt
Jan 31, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@ export GO_IMAGE = golang:$(shell go version | cut -d ' ' -f 3 | tail -c +3 )
cmd/algorand-indexer/algorand-indexer: idb/postgres/internal/schema/setup_postgres_sql.go go-algorand
cd cmd/algorand-indexer && go build -ldflags="${GOLDFLAGS}"

go-algorand:
git submodule update --init && cd third_party/go-algorand && \
# TODO: allow specifying the branch
go-algorand-submodule:
tzaffi marked this conversation as resolved.
Show resolved Hide resolved
git submodule update --init --force --remote
tzaffi marked this conversation as resolved.
Show resolved Hide resolved

go-algorand-build:
cd third_party/go-algorand && \
make crypto/libs/`scripts/ostype.sh`/`scripts/archtype.sh`/lib/libsodium.a

go-algorand: go-algorand-submodule go-algorand-build

idb/postgres/internal/schema/setup_postgres_sql.go: idb/postgres/internal/schema/setup_postgres.sql
cd idb/postgres/internal/schema && go generate

Expand Down
106 changes: 62 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
<!-- markdownlint-disable MD041 -->
Copy link
Contributor Author

@tzaffi tzaffi Jan 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linting with vscode's markdownlint extension

<!-- markdownlint-disable MD033 -->

| master <br> [![CircleCI](https://circleci.com/gh/algorand/indexer/tree/master.svg?style=svg)](https://circleci.com/gh/algorand/indexer/tree/master) | develop <br> [![CircleCI](https://circleci.com/gh/algorand/indexer/tree/develop.svg?style=svg)](https://circleci.com/gh/algorand/indexer/tree/develop) |
| --- | --- |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |

# Algorand Indexer

The Indexer is a standalone service that reads committed blocks from the Algorand blockchain and maintains a database of transactions and accounts that are searchable and indexed.

# Tested Requirements Versions

* [go 1.16](https://golang.org/dl/)
* [Postgres 13](https://www.postgresql.org/download/)
- [go 1.16](https://golang.org/dl/)
- [Postgres 13](https://www.postgresql.org/download/)

# Quickstart

We prepared a docker compose file to bring up indexer and Postgres preloaded with some data. From the root directory run:
```

```bash
~$ docker-compose up
```

Once running, here are a few commands to try out:

```bash
~$ curl "localhost:8980/v2/assets?name=bogo"
~$ curl "localhost:8980/v2/transactions?limit=1"
Expand All @@ -32,27 +37,28 @@ Once running, here are a few commands to try out:
# Features

- Search and filter accounts, transactions, assets, and asset balances with many different parameters:
- Round
- Date
- Address (Sender|Receiver)
- Balances
- Signature type
- Transaction type
- Asset holdings
- Asset name
- More
- Round
- Date
- Address (Sender|Receiver)
- Balances
- Signature type
- Transaction type
- Asset holdings
- Asset name
- More
- Lookup historic account data for a particular round.
- Result paging
- Enriched transaction and account data:
- Confirmation round (block containing the transaction)
- Confirmation time
- Signature type
- Asset ID
- Close amount when applicable
- Rewards
- Confirmation round (block containing the transaction)
- Confirmation time
- Signature type
- Asset ID
- Close amount when applicable
- Rewards
- Human readable field names instead of the space optimized protocol level names.

There are a number of technical features as well:

- Abstracted database layer. We want to support many different backend databases.
- Optimized Postgres DB backend.
- User defined API token.
Expand All @@ -72,33 +78,40 @@ Indexer works by fetching blocks one at a time, processing the block data, and l
As of the end of July 2021, storing all the raw blocks in MainNet is about 609 GB and the PostgreSQL database of transactions and accounts is about 495 GB. Much of that size difference is the Indexer ignoring cryptographic signature data; relying on `algod` to validate blocks. Dropping that, the Indexer can focus on the 'what happened' details of transactions and accounts.

There are two primary modes of operation:
* [Database updater](#database-updater)
* [Read only](#read-only)

### Database updater
- [Database updater](#database-updater)
- [Read only](#read-only)

## Database updater

In this mode, the database will be populated with data fetched from an [Algorand archival node](https://developer.algorand.org/docs/run-a-node/setup/types/#archival-mode). Because every block must be fetched to bootstrap the database, the initial import for a ledger with a long history will take a while. If the daemon is terminated, it will resume processing wherever it left off.

Keeping the indexer daemon as close as possible to the database helps minimize latency. For example, if using AWS EC2 and RDS, we suggest putting EC2 in the same VPC, Region, and even Availability Zone.

You should use a process manager, like systemd, to ensure the daemon is always running. Indexer will continue to update the database as new blocks are created.

To start indexer as a daemon in update mode, provide the required fields:
```

```bash
~$ algorand-indexer daemon --algod-net yournode.com:1234 --algod-token token --genesis ~/path/to/genesis.json --postgres "user=readonly password=YourPasswordHere {other connection string options for your database}"
```

Alternatively if indexer is running on the same host as the archival node, a simplified command may be used:
```

```bash
~$ algorand-indexer daemon --algod-net yournode.com:1234 -d /path/to/algod/data/dir --postgres "user=readonly password=YourPasswordHere {other connection string options for your database}"
```

### Read only
## Read only

It is possible to set up one daemon as a writer and one or more readers. The Indexer pulling new data from algod can be started as above. Starting the indexer daemon without $ALGORAND_DATA or -d/--algod/--algod-net/--algod-token will start it without writing new data to the database. For further isolation, a `readonly` user can be created for the database.
```

```bash
~$ algorand-indexer daemon --no-algod --postgres "user=readonly password=YourPasswordHere {other connection string options for your database}"
```

The Postgres backend does specifically note the username "readonly" and changes behavior to avoid writing to the database. But the primary benefit is that Postgres can enforce restricted access to this user. This can be configured with:

```sql
CREATE USER readonly LOGIN PASSWORD 'YourPasswordHere';
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM readonly;
Expand All @@ -108,7 +121,8 @@ GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
## Authorization

When `--token your-token` is provided, an authentication header is required. For example:
```

```bash
~$ curl localhost:8980/transactions -H "X-Indexer-API-Token: your-token"
```

Expand All @@ -119,8 +133,8 @@ The `/metrics` endpoint is configured with the `--metrics-mode` option and confi
There are different settings:
| Setting | Description |
| ------- | ----------- |
| ON | Metrics for each REST endpoint in addition to application metrics. |
| OFF | No metrics endpoint. |
| ON | Metrics for each REST endpoint in addition to application metrics. |
| OFF | No metrics endpoint. |
| VERBOSE | Separate metrics for each combination of query parameters. This option should be used with caution, there are many combinations of query parameters which could cause extra memory load depending on usage patterns. |

# Settings
Expand All @@ -145,30 +159,33 @@ Settings can be provided from the command line, a configuration file, or an envi

The command line arguments always take priority over the config file and environment variables.

```
```bash
~$ ./algorand-indexer daemon --pidfile /var/lib/algorand/algorand-indexer.pid --algod /var/lib/algorand --postgres "host=mydb.mycloud.com user=postgres password=password dbname=mainnet"`
```


## Configuration file

Default values are placed in the configuration file. They can be overridden with environment variables and command line arguments.

The configuration file must named **indexer**, **indexer.yml**, or **indexer.yaml**. It must also be in the correct location. Only one configuration file is loaded, the path is searched in the following order:
* `./` (current working directory)
* `$HOME`
* `$HOME/.algorand-indexer`
* `$HOME/.config/algorand-indexer`
* `/etc/algorand-indexer/`

- `./` (current working directory)
- `$HOME`
- `$HOME/.algorand-indexer`
- `$HOME/.config/algorand-indexer`
- `/etc/algorand-indexer/`

Here is an example **indexer.yml** file:
```

```bash
postgres-connection-string: "host=mydb.mycloud.com user=postgres password=password dbname=mainnet"
pidfile: "/var/lib/algorand/algorand-indexer.pid"
algod-data-dir: "/var/lib/algorand"
```

If it is in the current working directory along with the indexer command we can start the indexer daemon with:
```

```bash
~$ ./algorand-indexer daemon
```

Expand All @@ -177,7 +194,8 @@ If it is in the current working directory along with the indexer command we can
Environment variables are also available to configure indexer. Environment variables override settings in the config file and are overridden by command line arguments.

The same indexer configuration from earlier can be made in bash with the following:
```

```bash
~$ export INDEXER_POSTGRES_CONNECTION_STRING="host=mydb.mycloud.com user=postgres password=password dbname=mainnet"
~$ export INDEXER_PIDFILE="/var/lib/algorand/algorand-indexer.pid"
~$ export INDEXER_ALGOD_DATA_DIR="/var/lib/algorand"
Expand All @@ -188,7 +206,7 @@ The same indexer configuration from earlier can be made in bash with the followi

`/lib/systemd/system/algorand-indexer.service` can be partially overridden by creating `/etc/systemd/system/algorand-indexer.service.d/local.conf`. The most common things to override will be the command line and pidfile. The overriding local.conf file might be this:

```
```bash
[Service]
ExecStart=
ExecStart=/usr/bin/algorand-indexer daemon --pidfile /var/lib/algorand/algorand-indexer.pid --algod /var/lib/algorand --postgres "host=mydb.mycloud.com user=postgres password=password dbname=mainnet"
Expand All @@ -198,9 +216,9 @@ PIDFile=/var/lib/algorand/algorand-indexer.pid

The systemd unit file can be found in source at [misc/systemd/algorand-indexer.service](misc/systemd/algorand-indexer.service)

Note that the service assumes an `algorand` group and user. If the [Algorand package](https://github.com/algorand/go-algorand/) has already been installed on the same machine, this group and user has already been created. However, if the Indexer is running stand-alone, the group and user will need to be created before starting the daemon:
Note that the service assumes an `algorand` group and user. If the [Algorand package](https://github.com/algorand/go-algorand/) has already been installed on the same machine, this group and user has already been created. However, if the Indexer is running stand-alone, the group and user will need to be created before starting the daemon:

```
```bash
adduser --system --group --home /var/lib/algorand --no-create-home algorand
```

Expand All @@ -213,9 +231,9 @@ sudo systemctl start algorand-indexer

If you wish to run multiple indexers on one server under systemd, see the comments in `/lib/systemd/system/[email protected]` or [misc/systemd/[email protected]](misc/systemd/[email protected])

# Unique Database Configurations
# Unique Database Configurations

Load balancing:
Load balancing:
If indexer is deployed with a clustered database using multiple readers behind a load balancer, query discrepancies are possible due to database replication lag. Users should check the `current-round` response field and be prepared to retry queries when stale data is detected.

<!-- USAGE_END_MARKER_LINE -->
Expand Down
3 changes: 2 additions & 1 deletion api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ We are using a documentation driven process.
The API is defined using [OpenAPI v2](https://swagger.io/specification/v2/) in **indexer.oas2.yml**.

## Updating REST API

The Makefile will install our fork of **oapi-codegen**, use `make oapi-codegen` to install it directly.

1. Document your changes by editing **indexer.oas2.yml**
1. Document your changes by editing **indexer.oas2.json**
Copy link
Contributor Author

@tzaffi tzaffi Jan 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

2. Regenerate the endpoints by running **generate.sh**. The sources at **generated/** will be updated.
3. Update the implementation in **handlers.go**. It is sometimes useful to consult **generated/routes.go** to make sure the handler properly implements **ServerInterface**.

Expand Down
1 change: 1 addition & 0 deletions parity/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*_OUT.yml
Empty file added parity/__init__.py
Empty file.
Loading