Skip to content

Commit b78bcc5

Browse files
authored
Merge pull request #13 from AlgoNode/merge-with-upstream
Merge with upstream
2 parents dcb2caf + 74edb18 commit b78bcc5

Some content is hidden

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

64 files changed

+2892
-1576
lines changed

.circleci/config.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
version: 2.1
22

33
orbs:
4-
go: circleci/go@1.7.3
4+
go: circleci/go@1.12.0
55
slack: circleci/slack@4.7.1
66
codecov: codecov/codecov@3.2.4
77

88
parameters:
99
ubuntu_image:
1010
type: string
11-
default: "ubuntu-2204:2022.04.2"
11+
default: "ubuntu-2404:2024.05.1"
1212

1313
workflows:
1414
version: 2
@@ -18,7 +18,7 @@ workflows:
1818
name: test_with_go_<< matrix.go_version >>
1919
matrix: &go-version-matrix
2020
parameters:
21-
go_version: ["1.21.10"]
21+
go_version: ["1.23.3"]
2222

2323
circleci_build_and_test_nightly:
2424
triggers:
@@ -33,7 +33,7 @@ workflows:
3333
context: lamprey-secrets
3434
matrix: &go-version-matrix
3535
parameters:
36-
go_version: ["1.21.10"]
36+
go_version: ["1.23.3"]
3737
- indexer_vs_algod_nightly:
3838
name: nightly_test_indexer_vs_algod
3939
context: lamprey-secrets
@@ -135,7 +135,7 @@ commands:
135135
steps:
136136
- run:
137137
name: Install golangci-lint
138-
command: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.2
138+
command: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0
139139

140140
run_e2e_tests:
141141
steps:

.github/workflows/goreleaser.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ jobs:
1212
goreleaser:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@v3.5.3
15+
- uses: actions/checkout@v4
1616
with:
1717
fetch-depth: 0
1818
- run: git fetch --force --tags
1919

2020
- name: go dependency
21-
uses: actions/setup-go@v4.0.1
21+
uses: actions/setup-go@v5
2222
with:
2323
go-version-file: 'go.mod'
2424

.github/workflows/pr-type-category.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
name: Check PR Category and Type
1111
steps:
1212
- name: Checking for correct number of required github pr labels
13-
uses: mheap/github-action-required-labels@v2
13+
uses: mheap/github-action-required-labels@v5
1414
with:
1515
mode: exactly
1616
count: 1

.github/workflows/reviewdog.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ jobs:
77
runs-on: ubuntu-latest
88
steps:
99
- name: Check out code into the Go module directory
10-
uses: actions/checkout@v3.5.3
10+
uses: actions/checkout@v4
1111
with:
1212
fetch-depth: 0 # required for new-from-rev option in .golangci.yml
1313
- name: Install specific golang
14-
uses: actions/setup-go@v4.0.1
14+
uses: actions/setup-go@v5
1515
with:
16-
go-version: '1.21.10'
16+
go-version: '1.23.3'
1717
- name: reviewdog-golangci-lint
18-
uses: reviewdog/action-golangci-lint@v2.6.1
18+
uses: reviewdog/action-golangci-lint@v2.6.2
1919
with:
2020
go_version_file: go.mod
21-
golangci_lint_version: "v1.58.0"
21+
golangci_lint_version: "v1.62.0"
2222
golangci_lint_flags: "-c .golangci.yml --allow-parallel-runners"
2323
reporter: "github-pr-check"
2424
tool_name: "Lint Errors"
@@ -30,18 +30,18 @@ jobs:
3030
runs-on: ubuntu-latest
3131
steps:
3232
- name: Check out code into the Go module directory
33-
uses: actions/checkout@v3.5.3
33+
uses: actions/checkout@v4
3434
with:
3535
fetch-depth: 0 # required for new-from-rev option in .golangci.yml
3636
- name: Install specific golang
37-
uses: actions/setup-go@v4.0.1
37+
uses: actions/setup-go@v5
3838
with:
39-
go-version: '1.21.10'
39+
go-version: '1.23.3'
4040
- name: reviewdog-golangci-lint
41-
uses: reviewdog/action-golangci-lint@v2.6.1
41+
uses: reviewdog/action-golangci-lint@v2.6.2
4242
with:
4343
go_version_file: go.mod
44-
golangci_lint_version: "v1.58.0"
44+
golangci_lint_version: "v1.62.0"
4545
golangci_lint_flags: "-c .golangci-warnings.yml --allow-parallel-runners"
4646
reporter: "github-pr-check"
4747
tool_name: "Lint Warnings"

.golangci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
run:
22
timeout: 5m
3-
tests: false
3+
tests: true
44

55
linters:
66
disable-all: true
@@ -66,4 +66,4 @@ issues:
6666

6767
# revive: ignore some rules
6868
- "^unused-parameter: parameter"
69-
- "^package-comments: should have a package comment"
69+
- "^package-comments: should have a package comment"

CODEOWNERS

Lines changed: 0 additions & 2 deletions
This file was deleted.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ idb/postgres/internal/schema/setup_postgres_sql.go: idb/postgres/internal/schema
2020
cd idb/postgres/internal/schema && go generate
2121

2222
idb/mocks/IndexerDb.go: idb/idb.go
23-
go install github.com/vektra/mockery/v2@v2.20.0
23+
go install github.com/vektra/mockery/v2@v2.47.0
2424
cd idb && mockery --name=IndexerDb
2525

2626
# check that all packages (except tests) compile

accounting/rewind.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package accounting
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
models "github.com/algorand/indexer/v3/api/generated/v2"
8+
"github.com/algorand/indexer/v3/idb"
9+
"github.com/algorand/indexer/v3/types"
10+
11+
sdk "github.com/algorand/go-algorand-sdk/v2/types"
12+
)
13+
14+
// ConsistencyError is returned when the database returns inconsistent (stale) results.
15+
type ConsistencyError struct {
16+
msg string
17+
}
18+
19+
func (e ConsistencyError) Error() string {
20+
return e.msg
21+
}
22+
func assetUpdate(account *models.Account, assetid uint64, add, sub uint64) {
23+
if account.Assets == nil {
24+
account.Assets = new([]models.AssetHolding)
25+
}
26+
assets := *account.Assets
27+
for i, ah := range assets {
28+
if ah.AssetId == assetid {
29+
ah.Amount += add
30+
ah.Amount -= sub
31+
assets[i] = ah
32+
// found and updated asset, done
33+
return
34+
}
35+
}
36+
// add asset to list
37+
assets = append(assets, models.AssetHolding{
38+
Amount: add - sub,
39+
AssetId: assetid,
40+
//Creator: base32 addr string of asset creator, TODO
41+
//IsFrozen: leave nil? // TODO: on close record frozen state for rewind
42+
})
43+
*account.Assets = assets
44+
}
45+
46+
// SpecialAccountRewindError indicates that an attempt was made to rewind one of the special accounts.
47+
type SpecialAccountRewindError struct {
48+
account string
49+
}
50+
51+
// MakeSpecialAccountRewindError helper to initialize a SpecialAccountRewindError.
52+
func MakeSpecialAccountRewindError(account string) *SpecialAccountRewindError {
53+
return &SpecialAccountRewindError{account: account}
54+
}
55+
56+
// Error is part of the error interface.
57+
func (sare *SpecialAccountRewindError) Error() string {
58+
return fmt.Sprintf("unable to rewind the %s", sare.account)
59+
}
60+
61+
var specialAccounts *types.SpecialAddresses
62+
63+
// AccountAtRound queries the idb.IndexerDb object for transactions and rewinds most fields of the account back to
64+
// their values at the requested round.
65+
// `round` must be <= `account.Round`
66+
func AccountAtRound(ctx context.Context, account models.Account, round uint64, db idb.IndexerDb) (acct models.Account, err error) {
67+
// Make sure special accounts cache has been initialized.
68+
if specialAccounts == nil {
69+
var accounts types.SpecialAddresses
70+
accounts, err = db.GetSpecialAccounts(ctx)
71+
if err != nil {
72+
return models.Account{}, fmt.Errorf("unable to get special accounts: %v", err)
73+
}
74+
specialAccounts = &accounts
75+
}
76+
acct = account
77+
var addr sdk.Address
78+
addr, err = sdk.DecodeAddress(account.Address)
79+
if err != nil {
80+
return
81+
}
82+
// ensure that the don't attempt to rewind a special account.
83+
if specialAccounts.FeeSink == addr {
84+
err = MakeSpecialAccountRewindError("FeeSink")
85+
return
86+
}
87+
if specialAccounts.RewardsPool == addr {
88+
err = MakeSpecialAccountRewindError("RewardsPool")
89+
return
90+
}
91+
// Get transactions and rewind account.
92+
tf := idb.TransactionFilter{
93+
Address: addr[:],
94+
MinRound: round + 1,
95+
MaxRound: account.Round,
96+
}
97+
ctx2, cf := context.WithCancel(ctx)
98+
// In case of a panic before the next defer, call cf() here.
99+
defer cf()
100+
txns, r := db.Transactions(ctx2, tf)
101+
// In case of an error, make sure the context is cancelled, and the channel is cleaned up.
102+
defer func() {
103+
cf()
104+
for range txns {
105+
}
106+
}()
107+
if r < account.Round {
108+
err = ConsistencyError{fmt.Sprintf("queried round r: %d < account.Round: %d", r, account.Round)}
109+
return
110+
}
111+
txcount := 0
112+
for txnrow := range txns {
113+
if txnrow.Error != nil {
114+
err = txnrow.Error
115+
return
116+
}
117+
txcount++
118+
stxn := txnrow.Txn
119+
if stxn == nil {
120+
return models.Account{},
121+
fmt.Errorf("rewinding past inner transactions is not supported")
122+
}
123+
if addr == stxn.Txn.Sender {
124+
acct.AmountWithoutPendingRewards += uint64(stxn.Txn.Fee)
125+
acct.AmountWithoutPendingRewards -= uint64(stxn.SenderRewards)
126+
}
127+
switch stxn.Txn.Type {
128+
case sdk.PaymentTx:
129+
if addr == stxn.Txn.Sender {
130+
acct.AmountWithoutPendingRewards += uint64(stxn.Txn.Amount)
131+
}
132+
if addr == stxn.Txn.Receiver {
133+
acct.AmountWithoutPendingRewards -= uint64(stxn.Txn.Amount)
134+
acct.AmountWithoutPendingRewards -= uint64(stxn.ReceiverRewards)
135+
}
136+
if addr == stxn.Txn.CloseRemainderTo {
137+
// unwind receiving a close-to
138+
acct.AmountWithoutPendingRewards -= uint64(stxn.ClosingAmount)
139+
acct.AmountWithoutPendingRewards -= uint64(stxn.CloseRewards)
140+
} else if !stxn.Txn.CloseRemainderTo.IsZero() {
141+
// unwind sending a close-to
142+
acct.AmountWithoutPendingRewards += uint64(stxn.ClosingAmount)
143+
}
144+
case sdk.KeyRegistrationTx:
145+
// TODO: keyreg does not rewind. workaround: query for txns on an account with typeenum=2 to find previous values it was set to.
146+
case sdk.AssetConfigTx:
147+
if stxn.Txn.ConfigAsset == 0 {
148+
// create asset, unwind the application of the value
149+
assetUpdate(&acct, txnrow.AssetID, 0, stxn.Txn.AssetParams.Total)
150+
}
151+
case sdk.AssetTransferTx:
152+
if addr == stxn.Txn.AssetSender || addr == stxn.Txn.Sender {
153+
assetUpdate(&acct, uint64(stxn.Txn.XferAsset), stxn.Txn.AssetAmount+txnrow.Extra.AssetCloseAmount, 0)
154+
}
155+
if addr == stxn.Txn.AssetReceiver {
156+
assetUpdate(&acct, uint64(stxn.Txn.XferAsset), 0, stxn.Txn.AssetAmount)
157+
}
158+
if addr == stxn.Txn.AssetCloseTo {
159+
assetUpdate(&acct, uint64(stxn.Txn.XferAsset), 0, txnrow.Extra.AssetCloseAmount)
160+
}
161+
case sdk.AssetFreezeTx:
162+
default:
163+
err = fmt.Errorf("%s[%d,%d]: rewinding past txn type %s is not currently supported", account.Address, txnrow.Round, txnrow.Intra, stxn.Txn.Type)
164+
return
165+
}
166+
}
167+
acct.Round = round
168+
// Due to accounts being closed and re-opened, we cannot always rewind Rewards. So clear it out.
169+
acct.Rewards = 0
170+
// Computing pending rewards is not supported.
171+
acct.PendingRewards = 0
172+
acct.Amount = acct.AmountWithoutPendingRewards
173+
// MinBalance is not supported.
174+
acct.MinBalance = 0
175+
// TODO: Clear out the closed-at field as well. Like Rewards we cannot know this value for all accounts.
176+
//acct.ClosedAt = 0
177+
return
178+
}

api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ The API is defined using [OpenAPI v2](https://swagger.io/specification/v2/) in *
99
The Makefile will install our fork of **oapi-codegen**, use `make oapi-codegen` to install it directly.
1010

1111
1. Document your changes by editing **indexer.oas2.yml**
12-
2. Regenerate the endpoints by running **generate.sh**. The sources at **generated/** will be updated.
12+
2. Regenerate the endpoints by running **make generate** from the `api` directory. The sources at **generated/** will be updated.
1313
3. Update the implementation in **handlers.go**. It is sometimes useful to consult **generated/routes.go** to make sure the handler properly implements **ServerInterface**.
1414

1515
## What codegen tool is used?

api/app_boxes_fixtures_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import (
66
"fmt"
77
"testing"
88

9-
"github.com/algorand/indexer/v3/idb/postgres"
109
"github.com/stretchr/testify/require"
1110

1211
"github.com/algorand/avm-abi/apps"
12+
"github.com/algorand/indexer/v3/idb/postgres"
13+
"github.com/algorand/indexer/v3/util/test"
14+
1315
"github.com/algorand/go-algorand-sdk/v2/crypto"
1416
sdk "github.com/algorand/go-algorand-sdk/v2/types"
15-
"github.com/algorand/indexer/v3/util/test"
1617
)
1718

1819
func goalEncode(t *testing.T, s string) string {
@@ -23,7 +24,7 @@ func goalEncode(t *testing.T, s string) string {
2324
return string(b2)
2425
}
2526

26-
var goalEncodingExamples map[string]string = map[string]string{
27+
var goalEncodingExamples = map[string]string{
2728
"str": "str",
2829
"string": "string",
2930
"int": "42",

0 commit comments

Comments
 (0)