Skip to content

Commit 18666d1

Browse files
committed
Merge branch 'release/2.1.0-beta'
2 parents d5bbaf6 + dadff88 commit 18666d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+6608
-1271
lines changed

.travis.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ addons:
1616
- python3-wheel
1717

1818
install:
19-
- pip3 install boto3
20-
#- docker run -d -e POSTGES_USER=algorand -e POSTGRES_PASSWORD=indexer -e POSTGRES_DB=indexer-db -p 5432:5432 -t postgres
19+
- pip3 install boto3 markdown2
2120

2221
script:
2322
- make
2423
- go test ./...
25-
#- python3 misc/e2etest.py "host=localhost port=5432 user=algorand password=indexer dbname='indexer-db' sslmode=disable"
24+
- make package
25+
- docker build -t e2e_tests -f docker/Dockerfile.mule .
26+
- docker run --rm -t e2e_tests mule/e2e.sh
27+

.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.3
1+
2.1.0-beta

Jenkinsfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@Library('go-algorand-ci')_
2+
3+
muleCI('mule.yaml')
4+

Makefile

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
SRCPATH := $(shell pwd)
2-
OS_TYPE := $(shell ./scripts/ostype.sh)
3-
ARCH := $(shell ./scripts/archtype.sh)
4-
PKG_DIR = $(SRCPATH)/tmp/node_pkgs/$(OS_TYPE)/$(ARCH)
2+
VERSION := $(shell $(SRCPATH)/mule/scripts/compute_build_number.sh)
3+
OS_TYPE := $(shell $(SRCPATH)/mule/scripts/ostype.sh)
4+
ARCH := $(shell $(SRCPATH)/mule/scripts/archtype.sh)
5+
PKG_DIR = $(SRCPATH)/tmp/node_pkgs/$(OS_TYPE)/$(ARCH)/$(VERSION)
56

67
# This is the default target, build the indexer:
78
cmd/algorand-indexer/algorand-indexer: idb/setup_postgres_sql.go types/protocols_json.go .PHONY
@@ -13,22 +14,29 @@ idb/setup_postgres_sql.go: idb/setup_postgres.sql
1314
types/protocols_json.go: types/protocols.json types/consensus.go
1415
cd types && go generate
1516

16-
mocks: idb/dummy.go
17+
idb/mocks/IndexerDb.go: idb/dummy.go
18+
go get github.com/vektra/mockery/.../
1719
cd idb && mockery -name=IndexerDb
1820

21+
deploy:
22+
mule/deploy.sh
23+
1924
package: clean setup
2025
misc/release.py --outdir $(PKG_DIR)
2126

2227
setup:
2328
mkdir -p $(PKG_DIR)
2429

25-
test: mocks
30+
sign:
31+
mule/sign.sh
32+
33+
test: idb/mocks/IndexerDb.go
2634
go test ./...
2735

36+
test-package:
37+
mule/e2e.sh
38+
2839
clean:
2940
rm -rf $(PKG_DIR)
3041

3142
.PHONY:
32-
33-
###### TARGETS FOR CICD PROCESS ######
34-
include ./mule/Makefile.mule

README.md

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

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

6+
# Minimum Version Requirements
7+
8+
* go 1.13
9+
* Postgres 11
10+
611
# Quickstart
712

813
We prepared a docker compose file to bring up indexer and postgres preloaded with some data. From the root directory run:
@@ -12,13 +17,14 @@ We prepared a docker compose file to bring up indexer and postgres preloaded wit
1217

1318
Once running, here are a few commands to try out:
1419
```bash
15-
~$ curl "localhost:8980/assets?name=bogo"
16-
~$ curl "localhost:8980/transactions?limit=1"
17-
~$ curl "localhost:8980/transactions?round=10"
18-
~$ curl "localhost:8980/transactions?tx-type=acfg"
19-
~$ curl "localhost:8980/accounts?asset-id=9"
20-
~$ curl "localhost:8980/accounts/ZBBRQD73JH5KZ7XRED6GALJYJUXOMBBP3X2Z2XFA4LATV3MUJKKMKG7SHA?round=15"
21-
~$ curl "localhost:8980/assets/9/balances"
20+
~$ curl "localhost:8980/v2/assets?name=bogo"
21+
~$ curl "localhost:8980/v2/transactions?limit=1"
22+
~$ curl "localhost:8980/v2/transactions?round=10"
23+
~$ curl "localhost:8980/v2/transactions?tx-type=acfg"
24+
~$ curl "localhost:8980/v2/accounts?asset-id=9"
25+
~$ curl "localhost:8980/v2/accounts/ZBBRQD73JH5KZ7XRED6GALJYJUXOMBBP3X2Z2XFA4LATV3MUJKKMKG7SHA?round=15"
26+
~$ curl "localhost:8980/v2/assets/9/balances"
27+
~$ curl "localhost:8980/health"
2228
```
2329

2430
# Features
@@ -73,12 +79,12 @@ You should use a process manager, like systemd, to ensure the daemon is always r
7379

7480
To start indexer as a daemon in update mode, provide the required fields:
7581
```
76-
~$ algorand-indexer daemon --algodAddr yournode.com:1234 --algodToken token --genesis ~/path/to/genesis.json --postgres "user=readonly password=YourPasswordHere {other connection string options for your database}"
82+
~$ 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}"
7783
```
7884

7985
Alternatively if indexer is running on the same host as the archival node, a simplified command may be used:
8086
```
81-
~$ algorand-indexer daemon --algodAddr yournode.com:1234 -d /path/to/algod/data/dir --postgres "user=readonly password=YourPasswordHere {other connection string options for your database}"
87+
~$ 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}"
8288
```
8389

8490
### Read only
@@ -107,6 +113,7 @@ When `--token your-token` is provided, an authentication header is required. For
107113

108114
```
109115
[Service]
116+
ExecStart=
110117
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"
111118
PIDFile=/var/lib/algorand/algorand-indexer.pid
112119

accounting/accounting.go

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,7 @@ func (accounting *AccountingState) commitRound() error {
7070
if err != nil {
7171
return err
7272
}
73-
accounting.AlgoUpdates = nil
74-
accounting.AccountTypes = nil
75-
accounting.AccountDataUpdates = nil
76-
accounting.AssetUpdates = nil
77-
accounting.AcfgUpdates = nil
78-
accounting.TxnAssetUpdates = nil
79-
accounting.FreezeUpdates = nil
80-
accounting.AssetCloses = nil
81-
accounting.AssetDestroys = nil
73+
accounting.RoundUpdates.Clear()
8274
accounting.dirty = false
8375
return nil
8476
}
@@ -203,7 +195,10 @@ func blankLsig(lsig atypes.LogicSig) bool {
203195
return len(lsig.Logic) == 0
204196
}
205197

206-
func (accounting *AccountingState) AddTransaction(round uint64, intra int, txnbytes []byte) (err error) {
198+
func (accounting *AccountingState) AddTransaction(txnr *idb.TxnRow) (err error) {
199+
round := txnr.Round
200+
intra := txnr.Intra
201+
txnbytes := txnr.TxnBytes
207202
var stxn types.SignedTxnWithAD
208203
err = msgpack.Decode(txnbytes, &stxn)
209204
if err != nil {
@@ -295,19 +290,14 @@ func (accounting *AccountingState) AddTransaction(round uint64, intra int, txnby
295290
}
296291
} else if stxn.Txn.Type == "acfg" {
297292
assetId := uint64(stxn.Txn.ConfigAsset)
298-
if assetId == 0 {
299-
// create an asset
300-
txnCounter, err := accounting.getTxnCounter(round - 1)
301-
if err != nil {
302-
return fmt.Errorf("acfg get TxnCounter round %d, %v", round, err)
303-
}
304-
assetId = txnCounter + uint64(intra) + 1
305-
accounting.updateTxnAsset(round, intra, assetId)
293+
isNew := assetId == 0
294+
if isNew {
295+
assetId = txnr.AssetId
306296
}
307297
if stxn.Txn.AssetParams.IsZero() {
308298
accounting.destroyAsset(assetId)
309299
} else {
310-
accounting.AcfgUpdates = append(accounting.AcfgUpdates, idb.AcfgUpdate{AssetId: assetId, Creator: stxn.Txn.Sender, Params: stxn.Txn.AssetParams})
300+
accounting.AcfgUpdates = append(accounting.AcfgUpdates, idb.AcfgUpdate{AssetId: assetId, IsNew: isNew, Creator: stxn.Txn.Sender, Params: stxn.Txn.AssetParams})
311301
accounting.defaultFrozen[assetId] = stxn.Txn.AssetParams.DefaultFrozen
312302
if stxn.Txn.ConfigAsset == 0 {
313303
// initial creation, give all initial value to creator
@@ -333,6 +323,69 @@ func (accounting *AccountingState) AddTransaction(round uint64, intra int, txnby
333323
}
334324
} else if stxn.Txn.Type == "afrz" {
335325
accounting.freezeAsset(stxn.Txn.FreezeAccount, uint64(stxn.Txn.FreezeAsset), stxn.Txn.AssetFrozen)
326+
} else if stxn.Txn.Type == "appl" {
327+
hasGlobal := (len(stxn.EvalDelta.GlobalDelta) > 0) || (len(stxn.Txn.ApprovalProgram) > 0) || (len(stxn.Txn.ClearStateProgram) > 0) || stxn.Txn.OnCompletion == atypes.DeleteApplicationOC
328+
appid := uint64(stxn.Txn.ApplicationID)
329+
if appid == 0 {
330+
// creation
331+
appid = txnr.AssetId
332+
}
333+
if hasGlobal {
334+
agd := idb.AppDelta{
335+
AppIndex: int64(appid),
336+
Round: round,
337+
Intra: intra,
338+
//Address: nil,
339+
Delta: stxn.EvalDelta.GlobalDelta,
340+
OnCompletion: stxn.Txn.OnCompletion,
341+
ApprovalProgram: stxn.Txn.ApprovalProgram,
342+
ClearStateProgram: stxn.Txn.ClearStateProgram,
343+
LocalStateSchema: stxn.Txn.LocalStateSchema,
344+
GlobalStateSchema: stxn.Txn.GlobalStateSchema,
345+
}
346+
if stxn.Txn.ApplicationID == 0 {
347+
// app creation
348+
agd.Creator = stxn.Txn.Sender[:]
349+
}
350+
//fmt.Printf("agset %d %s\n", appid, agd.String())
351+
accounting.AppGlobalDeltas = append(
352+
accounting.AppGlobalDeltas,
353+
agd,
354+
)
355+
}
356+
for accountIndex, ldelts := range stxn.EvalDelta.LocalDeltas {
357+
var addr []byte
358+
if accountIndex == 0 {
359+
addr = stxn.Txn.Sender[:]
360+
} else {
361+
addr = stxn.Txn.Accounts[accountIndex-1][:]
362+
}
363+
accounting.AppLocalDeltas = append(
364+
accounting.AppLocalDeltas,
365+
idb.AppDelta{
366+
AppIndex: int64(appid),
367+
Round: round,
368+
Intra: intra,
369+
Address: addr,
370+
AddrIndex: accountIndex,
371+
Delta: ldelts,
372+
OnCompletion: stxn.Txn.OnCompletion,
373+
},
374+
)
375+
}
376+
// if there's no other content change, but a state change of opt-in/close-out/clear-state, record that
377+
if len(stxn.EvalDelta.LocalDeltas) == 0 && (stxn.Txn.OnCompletion == atypes.OptInOC || stxn.Txn.OnCompletion == atypes.CloseOutOC || stxn.Txn.OnCompletion == atypes.ClearStateOC) {
378+
accounting.AppLocalDeltas = append(
379+
accounting.AppLocalDeltas,
380+
idb.AppDelta{
381+
AppIndex: int64(appid),
382+
Address: stxn.Txn.Sender[:],
383+
Round: round,
384+
Intra: intra,
385+
OnCompletion: stxn.Txn.OnCompletion,
386+
},
387+
)
388+
}
336389
} else {
337390
return fmt.Errorf("txn r=%d i=%d UNKNOWN TYPE %#v\n", round, intra, stxn.Txn.Type)
338391
}

accounting/rewind.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ func assetUpdate(account *models.Account, assetid uint64, add, sub uint64) {
2121
ah.Amount += add
2222
ah.Amount -= sub
2323
assets[i] = ah
24+
// found and updated asset, done
2425
return
2526
}
2627
}
28+
// add asset to list
2729
assets = append(assets, models.AssetHolding{
2830
Amount: add - sub,
2931
AssetId: assetid,
@@ -71,8 +73,13 @@ func AccountAtRound(account models.Account, round uint64, db idb.IndexerDb) (acc
7173
acct.AmountWithoutPendingRewards -= uint64(stxn.ReceiverRewards)
7274
}
7375
if addr == stxn.Txn.CloseRemainderTo {
76+
// unwind receiving a close-to
7477
acct.AmountWithoutPendingRewards -= uint64(stxn.ClosingAmount)
7578
acct.AmountWithoutPendingRewards -= uint64(stxn.CloseRewards)
79+
} else if !stxn.Txn.CloseRemainderTo.IsZero() {
80+
// unwind sending a close-to
81+
acct.AmountWithoutPendingRewards += uint64(stxn.ClosingAmount)
82+
acct.AmountWithoutPendingRewards += uint64(stxn.CloseRewards)
7683
}
7784
case atypes.KeyRegistrationTx:
7885
// TODO: keyreg does not rewind. workaround: query for txns on an account with typeenum=2 to find previous values it was set to.

api/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ indexer.oas3.yml: .3tmp.json
2323
curl -s -X POST "https://converter.swagger.io/api/convert" -H "accept: application/json" -H "Content-Type: application/json" -d @./indexer.oas2.json -o .3tmp.json
2424

2525
oapi-codegen: .PHONY
26-
GO111MODULE=on go get -u "github.com/algorand/oapi-codegen/...@v1.3.5-algorand4"
26+
GO111MODULE=on go get -u "github.com/algorand/oapi-codegen/...@v1.3.5-algorand5"
2727

2828
.PHONY:

api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The API is defined using [OpenAPI v2](https://swagger.io/specification/v2/) in *
77
## Updating REST API
88
You need to have our fork of **oapi-codegen** installed:
99
```
10-
GO111MODULE=on go get -u github.com/algorand/oapi-codegen/...@v1.3.5-algorand2
10+
GO111MODULE=on go get -u github.com/algorand/oapi-codegen/...@v1.3.5-algorand5
1111
```
1212

1313
1. Document your changes by editing **indexer.oas2.yml**

0 commit comments

Comments
 (0)