diff --git a/Makefile b/Makefile index d17855e6dc..03795f171e 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,10 @@ ARCH := $(shell ./scripts/archtype.sh) OS_TYPE := $(shell ./scripts/ostype.sh) S3_RELEASE_BUCKET = $$S3_RELEASE_BUCKET +GOLANG_VERSIONS := $(shell ./scripts/get_golang_version.sh all) +GOLANG_VERSION_BUILD := $(firstword $(GOLANG_VERSIONS)) +GOLANG_VERSION_SUPPORT := $(lastword $(GOLANG_VERSIONS)) + # If build number already set, use it - to ensure same build number across multiple platforms being built BUILDNUMBER ?= $(shell ./scripts/compute_build_number.sh) FULLBUILDNUMBER ?= $(shell ./scripts/compute_build_number.sh -f) @@ -101,6 +105,12 @@ fix: build lint: deps $(GOPATH1)/bin/golangci-lint run -c .golangci.yml +tidy: + export PATH=$(GOPATH1)/bin:$(PATH) && \ + go install golang.org/dl/go$(GOLANG_VERSION_BUILD)@latest && \ + go$(GOLANG_VERSION_BUILD) download && \ + go$(GOLANG_VERSION_BUILD) mod tidy -compat=$(GOLANG_VERSION_SUPPORT) + check_shell: find . -type f -name "*.sh" -exec shellcheck {} + diff --git a/agreement/abstractions.go b/agreement/abstractions.go index f5d09dc1ef..44aafa4fd8 100644 --- a/agreement/abstractions.go +++ b/agreement/abstractions.go @@ -133,14 +133,14 @@ type LedgerReader interface { // protocol may lose liveness. LookupAgreement(basics.Round, basics.Address) (basics.OnlineAccountData, error) - // Circulation returns the total amount of money in circulation at the - // conclusion of a given round. + // Circulation returns the total amount of online money in circulation at the + // conclusion of a given round rnd that is eligible for voting at voteRnd. // // This method returns an error if the given Round has not yet been // confirmed. It may also return an error if the given Round is // unavailable by the storage device. In that case, the agreement // protocol may lose liveness. - Circulation(basics.Round) (basics.MicroAlgos, error) + Circulation(rnd basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) // LookupDigest returns the Digest of the entry that was agreed on in a // given round. diff --git a/agreement/agreementtest/simulate_test.go b/agreement/agreementtest/simulate_test.go index 6d8b2b43b6..0516592072 100644 --- a/agreement/agreementtest/simulate_test.go +++ b/agreement/agreementtest/simulate_test.go @@ -215,7 +215,7 @@ func (l *testLedger) LookupAgreement(r basics.Round, a basics.Address) (basics.O return l.state[a].OnlineAccountData(), nil } -func (l *testLedger) Circulation(r basics.Round) (basics.MicroAlgos, error) { +func (l *testLedger) Circulation(r basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { l.mu.Lock() defer l.mu.Unlock() diff --git a/agreement/common_test.go b/agreement/common_test.go index 361ab2e2ad..8f2ad8c4f0 100644 --- a/agreement/common_test.go +++ b/agreement/common_test.go @@ -335,7 +335,7 @@ func (l *testLedger) LookupAgreement(r basics.Round, a basics.Address) (basics.O return l.state[a].OnlineAccountData(), nil } -func (l *testLedger) Circulation(r basics.Round) (basics.MicroAlgos, error) { +func (l *testLedger) Circulation(r basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { l.mu.Lock() defer l.mu.Unlock() diff --git a/agreement/demux_test.go b/agreement/demux_test.go index 692d2cc5f9..027dbc9e13 100644 --- a/agreement/demux_test.go +++ b/agreement/demux_test.go @@ -495,7 +495,7 @@ func (t *demuxTester) LookupAgreement(basics.Round, basics.Address) (basics.Onli } // implement Ledger -func (t *demuxTester) Circulation(basics.Round) (basics.MicroAlgos, error) { +func (t *demuxTester) Circulation(basics.Round, basics.Round) (basics.MicroAlgos, error) { // we don't care about this function in this test. return basics.MicroAlgos{}, nil } diff --git a/agreement/fuzzer/ledger_test.go b/agreement/fuzzer/ledger_test.go index c0ffb8b531..a62caee4d9 100644 --- a/agreement/fuzzer/ledger_test.go +++ b/agreement/fuzzer/ledger_test.go @@ -236,7 +236,7 @@ func (l *testLedger) LookupAgreement(r basics.Round, a basics.Address) (basics.O return l.state[a].OnlineAccountData(), nil } -func (l *testLedger) Circulation(r basics.Round) (basics.MicroAlgos, error) { +func (l *testLedger) Circulation(r basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { l.mu.Lock() defer l.mu.Unlock() diff --git a/agreement/selector.go b/agreement/selector.go index 505d54188a..ba90be3b89 100644 --- a/agreement/selector.go +++ b/agreement/selector.go @@ -70,7 +70,7 @@ func membership(l LedgerReader, addr basics.Address, r basics.Round, p period, s return } - total, err := l.Circulation(balanceRound) + total, err := l.Circulation(balanceRound, r) if err != nil { err = fmt.Errorf("Service.initializeVote (r=%d): Failed to obtain total circulation in round %d: %v", r, balanceRound, err) return diff --git a/catchup/service_test.go b/catchup/service_test.go index 4d1bafb285..217c23bf77 100644 --- a/catchup/service_test.go +++ b/catchup/service_test.go @@ -796,7 +796,7 @@ func (m *mockedLedger) Block(r basics.Round) (bookkeeping.Block, error) { func (m *mockedLedger) Lookup(basics.Round, basics.Address) (basics.AccountData, error) { return basics.AccountData{}, errors.New("not needed for mockedLedger") } -func (m *mockedLedger) Circulation(basics.Round) (basics.MicroAlgos, error) { +func (m *mockedLedger) Circulation(basics.Round, basics.Round) (basics.MicroAlgos, error) { return basics.MicroAlgos{}, errors.New("not needed for mockedLedger") } func (m *mockedLedger) ConsensusVersion(basics.Round) (protocol.ConsensusVersion, error) { diff --git a/config/consensus.go b/config/consensus.go index 6a131c8e38..185e55ab95 100644 --- a/config/consensus.go +++ b/config/consensus.go @@ -507,6 +507,11 @@ type ConsensusParams struct { // EnableBoxRefNameError specifies that box ref names should be validated early EnableBoxRefNameError bool + + // ExcludeExpiredCirculation excludes expired stake from the total online stake + // used by agreement for Circulation, and updates the calculation of StateProofOnlineTotalWeight used + // by state proofs to use the same method (rather than excluding stake from the top N stakeholders as before). + ExcludeExpiredCirculation bool } // PaysetCommitType enumerates possible ways for the block header to commit to @@ -1281,6 +1286,8 @@ func initConsensusProtocols() { vFuture.StateProofUseTrackerVerification = true vFuture.EnableCatchpointsWithSPContexts = true + vFuture.ExcludeExpiredCirculation = true + Consensus[protocol.ConsensusFuture] = vFuture // vAlphaX versions are an separate series of consensus parameters and versions for alphanet diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json index b5c2376125..0adcc18c8b 100644 --- a/daemon/algod/api/algod.oas2.json +++ b/daemon/algod/api/algod.oas2.json @@ -1564,7 +1564,7 @@ ], "responses": { "200": { - "$ref": "#/responses/TransactionGroupLedgerStateDeltaForRoundResponse" + "$ref": "#/responses/TransactionGroupLedgerStateDeltasForRoundResponse" }, "401": { "description": "Invalid API Token", @@ -4040,12 +4040,20 @@ "$ref": "#/definitions/LedgerStateDelta" } }, - "TransactionGroupLedgerStateDeltaForRoundResponse": { + "TransactionGroupLedgerStateDeltasForRoundResponse": { "description": "Response containing all ledger state deltas for transaction groups, with their associated Ids, in a single round.", "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/LedgerStateDeltaForTransactionGroup" + "type": "object", + "required": [ + "deltas" + ], + "properties": { + "deltas": { + "type": "array", + "items": { + "$ref": "#/definitions/LedgerStateDeltaForTransactionGroup" + } + } } } }, diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml index 3903fb4db3..1acacc4daa 100644 --- a/daemon/algod/api/algod.oas3.yml +++ b/daemon/algod/api/algod.oas3.yml @@ -857,14 +857,22 @@ }, "description": "Supply represents the current supply of MicroAlgos in the system." }, - "TransactionGroupLedgerStateDeltaForRoundResponse": { + "TransactionGroupLedgerStateDeltasForRoundResponse": { "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + "properties": { + "deltas": { + "items": { + "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + }, + "type": "array" + } }, - "type": "array" + "required": [ + "deltas" + ], + "type": "object" } } }, @@ -4143,18 +4151,34 @@ "content": { "application/json": { "schema": { - "items": { - "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + "properties": { + "deltas": { + "items": { + "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + }, + "type": "array" + } }, - "type": "array" + "required": [ + "deltas" + ], + "type": "object" } }, "application/msgpack": { "schema": { - "items": { - "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + "properties": { + "deltas": { + "items": { + "$ref": "#/components/schemas/LedgerStateDeltaForTransactionGroup" + }, + "type": "array" + } }, - "type": "array" + "required": [ + "deltas" + ], + "type": "object" } } }, diff --git a/daemon/algod/api/server/v2/generated/data/routes.go b/daemon/algod/api/server/v2/generated/data/routes.go index 8c925b6d0c..03aa23d8c8 100644 --- a/daemon/algod/api/server/v2/generated/data/routes.go +++ b/daemon/algod/api/server/v2/generated/data/routes.go @@ -172,122 +172,122 @@ var swaggerSpec = []string{ "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", - "BRzLAAA=", + "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", + "AAD//yvhnHBdywAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/experimental/routes.go b/daemon/algod/api/server/v2/generated/experimental/routes.go index df54602af8..0d4e810054 100644 --- a/daemon/algod/api/server/v2/generated/experimental/routes.go +++ b/daemon/algod/api/server/v2/generated/experimental/routes.go @@ -76,174 +76,174 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL var swaggerSpec = []string{ "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/model/types.go b/daemon/algod/api/server/v2/generated/model/types.go index b133369a7b..50fe884e3c 100644 --- a/daemon/algod/api/server/v2/generated/model/types.go +++ b/daemon/algod/api/server/v2/generated/model/types.go @@ -1088,8 +1088,10 @@ type SupplyResponse struct { TotalMoney uint64 `json:"total-money"` } -// TransactionGroupLedgerStateDeltaForRoundResponse defines model for TransactionGroupLedgerStateDeltaForRoundResponse. -type TransactionGroupLedgerStateDeltaForRoundResponse = []LedgerStateDeltaForTransactionGroup +// TransactionGroupLedgerStateDeltasForRoundResponse defines model for TransactionGroupLedgerStateDeltasForRoundResponse. +type TransactionGroupLedgerStateDeltasForRoundResponse struct { + Deltas []LedgerStateDeltaForTransactionGroup `json:"deltas"` +} // TransactionParametersResponse TransactionParams contains the parameters that help a client construct // a new transaction. diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go index 7cff7a4400..e4ec6dd160 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/private/routes.go @@ -188,122 +188,123 @@ var swaggerSpec = []string{ "oUtRLV3gmB0HOWylrC1EVrw3RFSK0RueoFU5xnFdsLB/oGHkF6BGh+qapK3GcEXr+dybnDFXod+5iIk+", "6pWaTgZVTIPUdaNiWuS0X5mM4L4tASvATzPxSN8Fos4IG318hdtiqNds7h9jI2+GjkHZnzgIZWs+DkWz", "Gf02396BlGEHIhJKCQrvhNAupOxXsQhflLlLQ22VhqJvOrddfxk4fu8GFTTBc8YhKQSHbfQRNePwA36M", - "Hie8lwY6o4Qw1Lcr9Lfg74DVnmcMNd4Wv7jb3RMa8bPd3AU5ileM8OyNkaSjjrg8j7ji3HOR7vlV0/p5", - "OpOEKiVShjLOWaam9pw47517W9LG3ts6CPYOjk533I7PKXyJiDZVyEtCSZoztLgKrrSsUv2BU7TpBEuN", - "BAt55XXYyvfSN4mbFSNWPzfUB04xUKy29EQDHBYQMWt8C+CNfapaLkHpjm6wAPjAXSvGScWZxrkKQ+2J", - "JfcSJEbsHNmWBd2ShaEJLcjvIAWZV7otLeNrKKVZnjsHmJmGiMUHTjXJwSj8PzB+scHhvJPcnzgO+krI", - "yxoL8ct5CRwUU0k8qOk7+xXjTd3yVy72FF+v28/WZWLGb55MbdHk07zI/n/3//Pk/Wny3zT5/Th58b9m", - "Hz89vX7wsPfj4+uvvvr/7Z+eXH/14D//I7ZTHvbYWx0H+dkrp0mevUJ1ofGZ9GD/bPbygvEkSmRh9EOH", - "tsh9fJfqCOhB25ikV/CB6w03hLSmOcsMb7kJOXQviN5ZtKejQzWtjegYj/xaDxTCb8FlSITJdFjjjYWg", - "fhxg/FUcOvHcQzc8L4uK2630wrN99OHjscRiWr98tElRTgg+i1tRH0zo/nz87Plk2jxnq79PphP39WOE", - "klm2iT1azGAT063cAcGDcU+Rkm4V6Dj3QNijoWc2FiIctgCjlKsVKz8/p1CazeMczofSOxvNhp9xG+Nu", - "zg+6BLfO0yAWnx9uLQEyKPUqliyhJWdhq2Y3ATphGqUUa+BTwo7gqGsjyYy654LgcqALfLSPyqMYo8zU", - "58ASmqeKAOvhQkYZImL0gyKP49bX04m7/NWdazNu4Bhc3Tlr/5//Wwty77tvLsjMMUx1z76ftUMHLx4j", - "mrB71NMK4DHczKaIsULeB/6Bv4IF48x8P/nAM6rpbE4VS9WsUiC/pjnlKRwtBTnx74ReUU0/8J6kNZjF", - "KXihRcpqnrOUXIb6REOeNjNHf4QPH97TfCk+fPjYi2XoS/9uqih/sRMkRhAWlU5cXoFEwhWVMV+Rqt+V", - "48g2cciuWa2QLSprUPR5C9z4cZ5Hy1J135f2l1+WuVl+QIbKvZ40W0aUFtLLIkZAsdDg/r4R7mKQ9Mqb", - "RSoFivxa0PI94/ojST5Ux8dPgLQeXP7qrnxDk9sSRhtHBt+/dm0iuHCrFcJGS5qUdBlzSX348F4DLXH3", - "UV4u0ESR5wS7tR56+kB2HKpZgMfH8AZYOA5+tIaLO7e9fA6p+BLwE24htjHiRuMov+l+BU8/b7xdneej", - "vV2q9CoxZzu6KmVI3O9MnVpmaYQsH72g2BK1VZeFZw4kXUF66dKjQFHq7bTV3QfIOEHTsw6mbOIc+3AL", - "UzegQX8OpCoz6kRxyrfdN/QKtPZhuO/gErYXosn8cMij+fYbbjV0UJFSA+nSEGt4bN0Y3c13UVio2Jel", - "fwqNb+I8WZzUdOH7DB9kK/LewSGOEUXrjfEQIqiMIMIS/wAKbrBQM96tSD+2PKNlzO3NF0mi43k/cU0a", - "5ckFTIWrQaO5/V4AZuESV4rMqZHbhUsgZd8pB1ysUnQJAxJy6FMZ+Rq45YfBQfbde9GbTiy6F1rvvomC", - "bBsnZs1RSgHzxZAKKjOdMDk/k3XbOccC5oV0CJvnKCbV8YSW6VDZ8m3ZRHdDoMUJGCRvBA4PRhsjoWSz", - "osrntsIUYP4sj5IB/sB397uyrZwFEV5Bnq86l4rnud1z2tMuXc4Vn2jFZ1cJVcsRmVKMhI9B5bHtEBwF", - "oAxyWNqF28aeUJocAM0GGTh+XCxyxoEksWCxwAwaXDNuDjDy8UNCrAGdjB4hRsYB2OiOxoHJGxGeTb48", - "BEjuchhQPzY6soO/If7cyoZPG5FHlIaFswGnVOo5AHURhvX91YlzxWEI41Ni2Nya5obNOY2vGaSX9APF", - "1k6KDxcQ8WBInN3hv7AXy0FrslfRTVYTykwe6LhAtwPiudgk9r1lVOKdb+aG3qMR5fj6M3YwbXqVe4rM", - "xQaDbPBqsRHMe2AZhsODEWj4G6aQXrHf0G1ugdk17W5pKkaFCknGmfNqchkSJ8ZMPSDBDJHL/SBjyo0A", - "6Bg7mvTDTvndq6S2xZP+Zd7catMmE5h/rBM7/kNHKLpLA/jrW2HqHCdvuxJL1E7RjhVpp3cJRMgY0Rs2", - "0XfS9F1BCnJApSBpCVHJZczxaXQbwBvn3HcLjBeYRIby7YMgAEnCkikNjRHdhzl8CfMkxdx1QiyGV6dL", - "uTDreydEfU1ZNyJ2bC3zs68AI3gXTCqdoAciugTT6FuFSvW3pmlcVmqHONlMryyL8wac9hK2ScbyKk6v", - "bt7vX5lp39QsUVVz5LeM23iTOWYmjgY+7pjaxsbuXPBru+DX9M7WO+40mKZmYmnIpT3Hn+RcdDjvLnYQ", - "IcAYcfR3bRClOxhk8GC1zx0DuSnw8R/tsr72DlPmx94bdOOfzQ7dUXak6FoCg8HOVTB0ExmxhOkgsW//", - "JenAGaBlybJNxxZqRx3UmOlBBg+fDq2DBdxdN9geDAR2z9hjFgmqnfmuEfBtiuZW4pmjUZi5aOenCxlC", - "OBVTvsBAH1H1Y7d9uLoAmn8P259NW1zO5Ho6uZ3pNIZrN+IeXL+ttzeKZ3TNW1NayxNyIMppWUqxpnni", - "DMxDpCnF2pEmNvf26M/M6uJmzItvTl+/deBfTydpDlQmtagwuCpsV/5pVmWT7A0cEJ/A3Oh8Xma3omSw", - "+XVmsNAofbUClwk6kEZ7KSsbh0NwFJ2RehGPENprcna+EbvEHT4SKGsXSWO+sx6StleErinLvd3MQzsQ", - "zYOLG5f3NMoVwgFu7V0JnGTJnbKb3umOn46GuvbwpHCuHbmqC5uOXRHBuy50DFnels7rXlBMOGmtIn3m", - "xKsCLQmJylkat7HyuTLEwa3vzDQm2HhAGDUjVmzAFcsrFoxlmo1JKdMBMpgjikwVzWrT4G4uXKmdirPf", - "KiAsA67NJ4mnsnNQMTuJs7b3r1MjO/TncgNbC30z/G1kjDDZavfGQyB2Cxihp64H7qtaZfYLrS1S5ofA", - "JXGAwz+csXcl7nDWO/pw1GyDF1dtj1tYGafP/wxh2BTp+8vyeOXVZX0dmCNaZoepZCHF7xDX81A9jrwT", - "8ullGUa5/A7hO4WwuESLxdTWnaZaUDP74HYPSTehFaodpDBA9bjzgVsO81x6CzXldqtt1YtWrFucYMKo", - "0pkdvyEYB3MvEjenV3MaSwJqhAwD02njAG7Z0rUgvrPHvaofS9jZSeBLrtsy+wa8BNk84evnk7mhwGCn", - "HS0qNJIBUm0oE0yt/y9XIjJMxa8ot8VTTD97lFxvBdb4ZXpdCYkZHFTc7J9BygqaxyWHLO2beDO2ZLYu", - "SKUgKDzhBrI1lywVueId9RMgh5qzBTmeBtVv3G5kbM0Um+eALR7ZFnOqkJPXhqi6i1kecL1S2PzxiOar", - "imcSMr1SFrFKkFqoQ/Wmdl7NQV8BcHKM7R69IPfRbafYGh4YLLr7eXLy6AUaXe0fx7ELwNV12cVNMmQn", - "/3DsJE7H6Le0YxjG7UY9ij52t4XdhhnXjtNku445S9jS8br9Z6mgnC4hHilS7IHJ9sXdRENaBy88s1WJ", - "lJZiS5iOzw+aGv40EH1u2J8Fg6SiKJgunHNHicLQU1NVwk7qh7MljlxCYA+X/4g+0tK7iDpK5Oc1mtr7", - "LbZq9GS/oQW00Tol1KbtyFkTveDTlJMznxUIMyTXiZEtbsxcZuko5mAww4KUknGNikWlF8nfSLqikqaG", - "/R0NgZvMnz+NZIVuZyflhwH+2fEuQYFcx1EvB8jeyxCuL7nPBU8Kw1GyB81rj+BUDjpz4267Id/h7qHH", - "CmVmlGSQ3KoWudGAU9+K8PiOAW9JivV6DqLHg1f22SmzknHyoJXZoZ/evXZSRiFkLNVfc9ydxCFBSwZr", - "jN2Lb5IZ85Z7IfNRu3Ab6L+s58GLnIFY5s9yTBH4WkS0U5+pvLaku1j1iHVg6JiaD4YM5m6oKWlnhf78", - "fPRuoqDini5v2O47tswXjwf8o4uIL0wuuIGNL9+uZIBQgqz4UZLJ6u+Bj52Sr8VmLOF0TqEnnn8BFEVR", - "UrE8+7l5+dkpOiApT1dRn9ncdPylKY9WL87egdGsfSvKOeTR4ay8+YuXSyOS8z/F2HkKxke27dZBsMvt", - "LK4BvA2mB8pPaNDLdG4mCLHaflRXB23nS5ERnKdJEdcc1379jCDL+W8VKB17oIQfbOAY2kYNO7BJtgnw", - "DDXSI/KdrYC8AtLK/4OaoE/00H41XZW5oNkUE1BcfHP6mthZbR9b5Mcm+V6iItReRccmFmS/HBeC7Ov1", - "xJ9HjB9nd7y2WbXSSZ2TO/YA1bRosoazjp8AVaQQO0fkVVDL1L5VNUMYelgwWRitrh7NykdIE+Y/WtN0", - "hWpfi7UOk/z47PSeKlVQEbKu7FSnhMRzZ+B2CeptfvopEUY3v2LKFr6FNbTfvNYPwJ3Zwb+BbS9PVpxb", - "Sjk64JarE0AeinYPnL0ivSshClkH8QcK/ba4w6HJ+s+xVzRDVTfzf68UpH1BWVfs8QXNU8oFZynmh4pd", - "0a5C7hg/24hUWl1Drj/i7oRGDle03kAdiuewOFiBwDNCh7i+oT/4ajbVUof9U2Mp1hXVZAlaOc4G2dSX", - "zXC2RsYVuBSfWE854JNCtnyXyCGj7vCkdpscSEb49GZAefzWfHvjTAsYk37JOCoRDm1O8LPWQCzgqY3m", - "wTRZClBuPe33x+q96XOET3Ez2Hw88gU/cQzr+jPLtn7u/lCn3uvtvMym7UvT1uU3qn9uRTnbSU/L0k06", - "XFQlKg/oDR9EcMR7mXj3UYDcevxwtB3ktjNcBe9TQ2iwRmc3lHgP9wijLjDSKV5lhFZLUdiC2DCxaJYE", - "xiNgvGYcmnK0kQsijV4JuDF4Xgf6qVRSbUXAUTztAmiOHu4YQ1PauTduO1Q3u5NBCa7RzzG8jU1tlAHG", - "UTdoBDfKt3UVXEPdgTDxEstvO0T2K52gVOWEqAxfLXRqn8QYh2HcvrpS+wLoH4O+TGS7a0ntyTnkJhp6", - "iDqvsiXohGZZLOPq1/iV4FeSVSg5wAbSqs7MWZYkxbwr7UQ0fWpzE6WCq6rYMZdvcMvpgmJCEWoICxr5", - "HcaHLvMt/htLSzm8My7Q4+BQQx/V4epwHCg3t0fqSb2GphPFlsl4TOCdcnt0NFPfjNCb/ndK6blYtgH5", - "zOkndnG5cI9i/O0bc3GE2Rl6uVbt1VInT8DAPuFLQKLaWD/7bXMlvMp6yVfRoVSXmNttgBguFjfFy28g", - "vDdIukHt/Wo9lENBvulgTDrV7nWcpmQnCxp8cWQjhOzbIoQibp0digqyQUHmc6/3OMmwJ2freN7CAKE+", - "3KwP0Pc+lpWUlDn3e8Ms+ph1Ue/9dwhj4mGbDe4uwsWSD1rsvl8PxX37ZGz4vVtM6hLck/lSwpqJyju2", - "feSTVwntr63STHXkfXT9fcMrTvVlzaGDxtsLl9TfLtPp5N//bOPkCHAtt/8CptzepvfKVPWlXWueapqQ", - "Oh/0qPzQrVtxTALCWE48Jxu2CmXtKfPVZ6xjxIF+2a7phGUHXZjdqwSHsaPEjl28CNdw2qkm1RQesVIo", - "1qRlj1XnGhlieIEFtoK0Wf2xfHzPGlKNufibuAUJcEgSLTNZUO/z3+mnBtTpOhLTZZ3alWqqn4B/zx3f", - "ew0WvGi0ycuPxidWOq2j05BPYzLjJXBXcrP9zmN0tPliAalm6z2v7/6xAh687Jp6u4wtnR08xmN19DIm", - "bznc6tgAtOtx3E54giSKtwZn6O3NJWzvKdKihmg29am/am+StwMxgNwhMSQiVCz6wxqSnUOeqZoyEAs+", - "2sp2hyYD2mAhpuAt6Q3n8iRpLo7mfemOKeOVYEbNZboe9OoaA3GHHuj1C0kM6x+vsG6Hqosk+rwfoZZO", - "zvrZEa9c3hB8K1n7TnwGEVD+N/8w2s6Ss0sIS0Whp+qKysy3iJpevFUn2XEf9V7V+SIIXaAX9cysiY3t", - "v6OK5NvCCOg0F0aMSIbCyNvhqHUsxz1lg25s9nYMtDVwLUC6knoo/+ZCQaKFj6XdBccuVNjIohshQQ3m", - "uLTADWaeedek1sFcvxQzzVAXUBQukEgoqIFOBglwhufcheyX9rt/OORzve61MNX0ur9mgI+KZqqHxJDq", - "F8TdlvsfJN3E2MQ4t2WbVSwbDgfZ9oaUUmRVai/o8GDUBrnRuaZ2sJKonSbtr7KjIwSvOi9hO7NKkC+2", - "4HcwBNpKThb0IItCZ5Pv1PymYnAv7wS8L2m5mk5KIfJkwNlx1k/h06X4S5ZeQkbMTeGjBwcK15D7aGOv", - "vdlXq61PWVOWwCF7cETIKbfx2t6x3c4h3Zmc39O75t/grFlls2o5o9rRBx4PfMV8V/KW3MwPs5uHKTCs", - "7pZT2UH2JIjZDKQPkvQqUsbpaKxW3nc1d0vrNERloYjJJE3VmD1xMnWITFO4owmT6UsHeS6uEqSipM7/", - "FdM5TLs2k/QZT5tuBttzCOJtqHIX6JasaEZSISWkYY/4EwcLVCEkJLnA8JuYZ3ChjTxUYFwzJ7lYElEa", - "Ndem0fM+lGhVmWAu+8zW9kyso2YgkQEo96zWTWMb9+fZUXzm8MI2F6uIvQUR7bF8cPUaRygjqlF0qyDV", - "YI4g0P22ptNYcZ72urrlnYaKrWlRsDSO7j9XlMlgbMie0kOR9dXk6Coj+VeBA7iKumx3e0htGbn5WD9p", - "nTN55LEIABj2nLZgGOU/PRSMBZZlTGgEyWe11DptVc1lnbPv89lZGk+p1VpXQMzYlQT3Ss3Wj+sUvimp", - "XvlbzDTv65ZGTwGFT8hs+Q+qrCXEW2Rc8bqueCDKJIc1tBzK7ulclaagFFtDWPjOdiYZQIn2ya7UHPOU", - "hlyuI0q5tSeBr20MdqOylUWs3SmyR3CKinkbnthjosYeJQPRmmUVbeFP3aKU2FAVsQgb9rCO5BQHM4n4", - "4naxiL2xDUjz0XPJ46EN4cvN2iiCs2W18dQSYXOyVUmv+LASEbE71f7226+D4GBEdV5SD175st6VmyqQ", - "g5SxizB65f+iMocCX741THrixS3XNyJjWVMXU5EBmGrOM0bvQRMdFjQr6JZkbLEAaY35SlOeUZmFzRkn", - "KUhNmdFsturmYq2BVlYw3SvZGu6Kg3oGE5Nx0S5lAcm3TmW4hdSJnpuIxGmvWi2GKhz2diX+nIBujHSN", - "cVUDROAeQqNsbQ+Y4CggkYJewoHzKPY77J4G05M4258WOOuYKWK+1hvmVhvFuvthCJHbLahluNszFKZe", - "bN50SRvNgpZkf0F2afyH5uIcV1XRd9gDXugwDOoqetuNA+cLP476oUZKsJSPQ5TQWv4+H6RbYCNpBFvk", - "GIHWYBPh2oD69r4EDmb1svbbDpUA7bp3Mc+i4LbIX88tbHmTrdoXEI45C3JN88/v2sUEnKeID8jeDRuD", - "Q99giGSLSnWzlwmv6ai5Az/g3U3N36Ir+h9g9iiqlbqhnAhTi/U+mAdvFppbw8XCl/BaAydXOKaNY3v0", - "nMzdy+1SQspUVzS68tU1alcYFptyr0E2eo/vbd86fxb6FmS88JoGedNk6kcdf8kbCJsj+oWZysDJjVJ5", - "jPp6ZBHBX4xHhSnU9lwXl60AN1v5pPNyQ0i440C3IGT9wEC3fnK4scuzwVzm0qkU9Nc5+rZu4TZyUTdr", - "Gxul2UfurnTuY4Ir41UaTHeM7rQIwRInBEElvz76lUhYYA1DQR4+xAkePpy6pr8+bn82x/nhw6h09tni", - "Oi2O3Bhu3hjF/Dz00s++Zht4VNrZj4rl2T7CaD0RbqqA4iPYX1wigi9Sh/QXG2vSP6quFtwtAuQsYiJr", - "bU0eTBU8/h3x7td1i7zyRT9OWkmmt5gf0dsP2C/RCNTv6mgmFw1X64fu7tPiEuoMm03sU6X87fqdoDne", - "R1Zt5eYWEvkR+WZDizIHd1C+ujf/Kzz529Ps+Mmjv87/dvzsOIWnz14cH9MXT+mjF08eweO/PXt6DI8W", - "z1/MH2ePnz6eP3389PmzF+mTp4/mT5+/+Os9w4cMyBbQic/GM/m/WKw3OX17llwYYBuc0JJ9D67YsyFj", - "X3GQpngSoaAsn5z4n/63P2FHqSia4f2vE5fsY7LSulQns9nV1dVR2GW2xGCHRIsqXc38PL2ShKdvz2ov", - "kbUC4Y7ad7LeuudJ4RS/vfvm/IKcvj07CsrNn0yOj46PHmF18hI4LdnkZPIEf8LTs8J9nzlim5x8up5O", - "ZiugOcYGmj8K0JKl/pMEmm3d/9UVXS5BHrkyjOan9eOZFytmn1zQx/Wub7OwosnsUys2JtvTEysezD75", - "RH67W7cy5bmYoKDDSCh2NZvNMT/I2KaggsbDS0FlQ80+obg8+PvMJTSIf0S1xZ6HmQ8gi7dsYemT3hhY", - "Oz1SqtNVVc4+4X+QPq9diDHEwsVsHgBKmuZTwjShcyExg55OV4ZH+NRdTAUtJ0i1luDPMkPoptdLC4FP", - "0mmzlp+877uzcCDiR0KuYEi+ObStmRq+jBaoIJF2feu02jd3z/vj5MXHT4+mj46v/2LuFvfnsyfXI/1S", - "L+txyXl9cYxs+BHzXqEBEs/y4+PjW1SEP+UB+u0m1Q95IkXd7U4MuwzcVnUGIjUy9uTn6QwfKzF7PZ08", - "PXDFO21JrcdNkVKxX9OMeJc/zv3o8819xjHq1vB4Yu+w6+nk2edc/Rk3JE9zgi2DhIv9rf+JX3JxxX1L", - "I3BURUHl1h9j1WIKxG02Xmt0qTAOQ7I1RTmPC96qIjf5iLE/sbCLAX6jNL0Bvzk3vf7Nbz4Xv8FNugt+", - "0x7ojvnN4wPP/J9/xf/msH82Dntu2d2tOKwT+OyL8Jne8Bm6s2afWgKq+9wTUNu/N93DFutCZOBlULFY", - "2Fzzuz7PPtl/g4lgU4JkBXCbg9P9al/LzTAD5Lb/85an0R/76+gWeo39PPvULjTUQpBaVToTVzbtWfTK", - "wmz6NHepd9FcW6t+WhA/QPM0ifzoXlPnW7RRswwIxTRPotKNbm4612EitffEjNAUgV4yjhOgGRxnsTmm", - "aRD0ryAV3JZM7VyPDrI3IoP+9YgX4G8VyG1zAzoYJ9MWf3QEHsnofOvrps/Org8jfzTXW19TnzjqOqmt", - "v2dXlGlzibo3QojRfmcNNJ+5hECdX5s3+L0vmFgg+DGMdYn+OquLIkQ/dlXh2FenCg408q53/7kxi4Vm", - "JiSJ2sD0/qPZWUy566ilsZqczGYYd78SSs8m19NPHYtK+PFjvZk+T2K9qdcfr/8nAAD//60gT+eYywAA", + "Hie8lwY6o4Qw1Lcr9Lfg74DVnmcMNd4Wv7jb3RPadRGpb4W8Kx+kcyWNladHuPz2+rfdlDd1TNI8j/jy", + "3HuTLgNQ0/p9O5OEKiVShkLSWaam9qA59597nNJG/9s6ivYOzl533I7TKnzKiEZZyEtCSZozNNkKrrSs", + "Uv2BUzQKBUuNRBt57XfYTPjSN4nbJSNmQzfUB04x0qw2FUUjJBYQsYt8C+CthapaLkHpjnKxAPjAXSvG", + "ScWZxrkKc1wSe15KkBjyc2RbFnRLFoYmtCC/gxRkXum2uI3PqZRmee48aGYaIhYfONUkB6o0+YHxiw0O", + "573s/shy0FdCXtZYiN/uS+CgmEriUVHf2a8YsOqWv3LBq/j83X62PhczfvPmaos2o+ZJ9/+7/58n70+T", + "/6bJ78fJi/81+/jp6fWDh70fH19/9dX/b//05PqrB//5H7Gd8rDHHvs4yM9eOVX07BXqG43TpQf7ZzO4", + "F4wnUSILwyc6tEXu48NWR0AP2tYovYIPXG+4IaQ1zVlmeMtNyKF7w/TOoj0dHappbUTH+uTXeqAUfwsu", + "QyJMpsMabyxF9QMJ48/q0AvoXsrheVlU3G6ll77tqxEf0CUW0/rppM2qckLwXd2K+mhE9+fjZ88n0+Y9", + "XP19Mp24rx8jlMyyTezVYwabmHLmDggejHuKlHSrQMe5B8IejV2zwRThsAUYrV6tWPn5OYXSbB7ncD4W", + "3xl5NvyM2yB5c37Qp7h1rgqx+PxwawmQQalXsWwLLUENWzW7CdCJ8yilWAOfEnYER10jS2b0RRdFlwNd", + "4Kt/1D7FGG2oPgeW0DxVBFgPFzLKkhGjHxR5HLe+nk7c5a/uXB1yA8fg6s5ZOxD931qQe999c0FmjmGq", + "e/YBrh06eDIZUaXdq6BWBJDhZjbHjBXyPvAP/BUsGGfm+8kHnlFNZ3OqWKpmlQL5Nc0pT+FoKciJf2j0", + "imr6gfckrcE0UMETL1JW85yl5DJUSBrytKk9+iN8+PCe5kvx4cPHXjBEX31wU0X5i50gMYKwqHTiEhMk", + "Eq6ojDmbVP0wHUe2mUd2zWqFbFFZi6RPfODGj/M8Wpaq+0C1v/yyzM3yAzJU7vml2TKitJBeFjECioUG", + "9/eNcBeDpFferlIpUOTXgpbvGdcfSfKhOj5+AqT1YvNXd+UbmtyWMNq6MviAtmtUwYVbtRI2WtKkpMuY", + "T+vDh/caaIm7j/JygTaOPCfYrfVS1EfC41DNAjw+hjfAwnHwqzdc3Lnt5ZNQxZeAn3ALsY0RNxpP+033", + "K3g7euPt6rw/7e1SpVeJOdvRVSlD4n5n6tw0SyNk+fAHxZaorbo0PnMg6QrSS5dfBYpSb6et7j7Cxgma", + "nnUwZTPv2JdfmPsBPQJzIFWZUSeKU77tPsJXoLWP430Hl7C9EE3qiENe3bcfgauhg4qUGkiXhljDY+vG", + "6G6+C+NCxb4s/VtqfFTnyeKkpgvfZ/ggW5H3Dg5xjChaj5SHEEFlBBGW+AdQcIOFmvFuRfqx5RktY25v", + "vkgWHs/7iWvSKE8u4ipcDVrd7fcCMI2XuFJkTo3cLlwGKvvQOeBilaJLGJCQQ6fMyOfELUcODrLv3ove", + "dGLRvdB6900UZNs4MWuOUgqYL4ZUUJnpxNn5mazfz3kmMLGkQ9g8RzGpDki0TIfKlnPMZsobAi1OwCB5", + "I3B4MNoYCSWbFVU+ORbmEPNneZQM8Ac+3N+VruUsCBELEoXVyVg8z+2e05526ZK2+EwtPj1LqFqOSLVi", + "JHyMSo9th+AoAGWQw9Iu3Db2hNIkEWg2yMDx42KRMw4kiUWbBWbQ4Jpxc4CRjx8SYi3wZPQIMTIOwEZ/", + "Ng5M3ojwbPLlIUBylwSB+rHREx78DfH3Wjb+2og8ojQsnA14tVLPAagLUazvr06gLA5DGJ8Sw+bWNDds", + "zml8zSC9rCEotnZyhLiIigdD4uwOB4i9WA5ak72KbrKaUGbyQMcFuh0Qz8UmsQ82oxLvfDM39B4NScfn", + "o7GDafOz3FNkLjYYpYNXiw2B3gPLMBwejEDD3zCF9Ir9hm5zC8yuaXdLUzEqVEgyzpxXk8uQODFm6gEJ", + "Zohc7gcpV24EQMfY0eQvdsrvXiW1LZ70L/PmVps2qcT8a5/Y8R86QtFdGsBf3wpTJ0l525VYonaKdrBJ", + "Oz9MIELGiN6wib6Tpu8KUpADKgVJS4hKLmOeU6PbAN44575bYLzALDSUbx8EEUwSlkxpaIzoPk7iS5gn", + "KSa/E2IxvDpdyoVZ3zsh6mvKuhGxY2uZn30FGAK8YFLpBD0Q0SWYRt8qVKq/NU3jslI7RsqmimVZnDfg", + "tJewTTKWV3F6dfN+/8pM+6ZmiaqaI79l3AaszDG1cTRycsfUNrh254Jf2wW/pne23nGnwTQ1E0tDLu05", + "/iTnosN5d7GDCAHGiKO/a4Mo3cEggxevfe4YyE2Bj/9ol/W1d5gyP/beqB3/7nbojrIjRdcSGAx2roKh", + "m8iIJUwHmYH7T1EHzgAtS5ZtOrZQO+qgxkwPMnj4fGodLODuusH2YCCwe8Zew0hQ7dR5jYBvczy3Mtcc", + "jcLMRTvBXcgQwqmY8hUK+oiqX8vtw9UF0Px72P5s2uJyJtfTye1MpzFcuxH34Pptvb1RPKNr3prSWp6Q", + "A1FOy1KKNc0TZ2AeIk0p1o40sbm3R39mVhc3Y158c/r6rQP/ejpJc6AyqUWFwVVhu/JPsyqbpW/ggPgM", + "6Ebn8zK7FSWDza9Ti4VG6asVuFTSgTTay3nZOByCo+iM1It4hNBek7Pzjdgl7vCRQFm7SBrznfWQtL0i", + "dE1Z7u1mHtqBaB5c3LjEqVGuEA5wa+9K4CRL7pTd9E53/HQ01LWHJ4Vz7Uh2Xdh87ooI3nWhY8zztnRe", + "94JixkprFekzJ14VaElIVM7SuI2Vz5UhDm59Z6YxwcYDwqgZsWIDrlhesWAs02xMTpoOkMEcUWSqaFqc", + "Bndz4Wr1VJz9VgFhGXBtPkk8lZ2DiulNnLW9f50a2aE/lxvYWuib4W8jY4TZWrs3HgKxW8AIPXU9cF/V", + "KrNfaG2RMj8ELokDHP7hjL0rcYez3tGHo2YbvLhqe9zC0jp9/mcIw+ZY31/XxyuvLm3swBzROj1MJQsp", + "foe4nofqceShkc9PyzDK5XcIHzqE1SlaLKa27jTlhprZB7d7SLoJrVDtIIUBqsedD9xymCjTW6gpt1tt", + "y2a0Yt3iBBNGlc7s+A3BOJh7kbg5vZrTWBZRI2QYmE4bB3DLlq4F8Z097lX92sLOTgJfct2W2UfkJcjm", + "DWA/Ic0NBQY77WhRoZEMkGpDmWBq/X+5EpFhKn5Fua2+YvrZo+R6K7DGL9PrSkhMAaHiZv8MUlbQPC45", + "ZGnfxJuxJbOFRSoFQeUKN5At2mSpyFX/qN8QOdScLcjxNCif43YjY2um2DwHbPHItphThZy8NkTVXczy", + "gOuVwuaPRzRfVTyTkOmVsohVgtRCHao3tfNqDvoKgJNjbPfoBbmPbjvF1vDAYNHdz5OTRy/Q6Gr/OI5d", + "AK4wzC5ukiE7+YdjJ3E6Rr+lHcMwbjfqUfS1vK0MN8y4dpwm23XMWcKWjtftP0sF5XQJ8UiRYg9Mti/u", + "JhrSOnjhmS1rpLQUW8J0fH7Q1PCngehzw/4sGCQVRcF04Zw7ShSGnpqyFHZSP5ytkeQyCnu4/Ef0kZbe", + "RdRRIj+v0dTeb7FVoyf7DS2gjdYpoTbvR86a6AWf55yc+bRCmGK5zqxscWPmMktHMQeDGRaklIxrVCwq", + "vUj+RtIVlTQ17O9oCNxk/vxpJK10O70pPwzwz453CQrkOo56OUD2XoZwfcl9LnhSGI6SPWheewSnctCZ", + "G3fbDfkOdw89VigzoySD5Fa1yI0GnPpWhMd3DHhLUqzXcxA9Hryyz06ZlYyTB63MDv307rWTMgohY7kC", + "m+PuJA4JWjJYY+xefJPMmLfcC5mP2oXbQP9lPQ9e5AzEMn+WY4rA1yKinfpU57Ul3cWqR6wDQ8fUfDBk", + "MHdDTUk7rfTn56N3EwUV93R5w3bfsWW+eDzgH11EfGFywQ1sfPl2JQOEEqTVj5JMVn8PfOyUfC02Ywmn", + "cwo98fwLoCiKkorl2c/Ny89O1QJJebqK+szmpuMvTX21enH2Doym/VtRziGPDmflzV+8XBqRnP8pxs5T", + "MD6ybbeQgl1uZ3EN4G0wPVB+QoNepnMzQYjV9qO6Omg7X4qM4DxNjrnmuPYLcARp0n+rQOnYAyX8YAPH", + "0DZq2IHN0k2AZ6iRHpHvbAnlFZBWAiHUBH2miPar6arMBc2mmMHi4pvT18TOavvYKkE2S/gSFaH2Kjo2", + "sSB95rgQZF/wJ/48Yvw4u+O1zaqVTuqk3rEHqKZFk3acdfwEqCKF2Dkir4JiqPatqhnC0MOCycJodfVo", + "Vj5CmjD/0ZqmK1T7Wqx1mOTHp7f3VKmCkpJ1aag6pySeOwO3y3BvE9xPiTC6+RVTtnIurKH95rV+AO7M", + "Dv4NbHt5suLcUsrRAbdcnUHyULR74OwV6V0JUcg6iD9Q6LfVIQ7N9n+OvaIprrqlA3q1JO0Lyrrkj6+I", + "nlIuOEsxwVTsinYldsf42Ubk4uoacv0Rdyc0criiBQvqUDyHxcESBp4ROsT1Df3BV7Opljrsnxprua6o", + "JkvQynE2yKa+7oazNTKuwOUIxYLMAZ8UsuW7RA4ZdYcntdvkQDLCpzcDyuO35tsbZ1rAmPRLxlGJcGhz", + "gp+1BmIFUG00D6bJUoBy62m/P1bvTZ8jfIqbwebjka8YimNY159ZtvVz94c69V5v52U2bV+ati5BUv1z", + "K8rZTnpalm7S4aosUXlAb/gggiPey8S7jwLk1uOHo+0gt53hKnifGkKDNTq7ocR7uEcYdYWSTvUrI7Ra", + "isIWxIaJRbMkMB4B4zXj0NSzjVwQafRKwI3B8zrQT6WSaisCjuJpF0Bz9HDHGJrSzr1x26G66aEMSnCN", + "fo7hbWyKqwwwjrpBI7hRvq3L6BrqDoSJl1i/2yGyXyoFpSonRGX4aqFTPCXGOAzj9uWZ2hdA/xj0ZSLb", + "XUtqT84hN9HQQ9R5lS1BJzTLYilbv8avBL+SrELJATaQVnVqz7IkKeZdaSei6VObmygVXFXFjrl8g1tO", + "F1QjilBDWBHJ7zA+dJlv8d9YXsvhnXGBHgeHGvqojgOzL/VDJ2NSr6HpRLFlMh4TeKfcHh3N1Dcj9Kb/", + "nVJ6LpZtQD5z+omdybCCPYrxt2/MxRFmZ+gla7VXS508AQP7hK8hiWpj/ey3k/qLatrP3ooOpbpG3W4D", + "xHC1uSlefgPhvUHSDWrvV+uhHAryTQdj0ql2r+M0JTtZ0OCLIxshZN8WIRRx6+xQVJANCjKfe73HSYY9", + "OVvHEx8GCPXhZn2AvvexrKSkzLnfG2bRx6yLeu+/QxgTD9tscHcRLpZ80GL3/Xoo7tsnY8Pv3WpUl+Ce", + "zJcS1kxU3rHtI5+8Smh/bdV2qiPvo+vvG15xqi9rDh003l64qgB2mU4n//5nGydHgGu5/Rcw5fY2vVfn", + "qi/tWvNU04TUCaVHJZhu3YpjEhXGcuI52bBVaWtPnbA+Yx0jDvTrfk0nLDvowozlVZzYUWLHLl7Fazjt", + "VJNqCo9YKRRr8rrHynuNDDG8wApdQdqs/lg+vmcNqcZk/k3cggQ4JImWmSwoGPrv9FMD6nQdiemyTu1K", + "NdXP4L/nju+9BgteNNrs50fjEyud1tFpyKcxG/ISuKvZ2X7nMTrafLGAVLP1ntd3/1gBD152Tb1dxtbe", + "Dh7jsTp6GZO3HG51bADa9ThuJzxBEsVbgzP09uYStvcUaVFDNB371F+1N8nbgRhA7pAYEhEqFv1hDcnO", + "Ic9UTRmIBR9tZbtDkwFtsJJT8Jb0hnN5kjQXR/O+dMeU8VIyo+YyXQ96dY2BuEMP9PqVKIb1j1dY+EPV", + "VRZ93o9QSydn/eyIVy5vCL6VrH0nPoMIKP+bfxhtZ8nZJYS1ptBTdUVl5ltETS/eqpPsuI96r+p8FYUu", + "0It6ZtbExvbfUUXybWEEdJoLI0YkQ2Hk7XDUOpbjnrJBNzb9OwbaGrgWIF1NPpR/c6Eg0cLH0u6CYxcq", + "bGTRjZCgBnNcWuAGM8+8a1LrYK5fiplmqAsoChdIJBTUQCeDBDjDc+5C9kv73T8c8rle91qYanrdX3TA", + "R0Uz1UNiSPUL4m7L/Q+SbmJsYpzbus8qlg2Hg2x7Q0opsiq1F3R4MGqD3OhcUztYSdROk/ZX2dERgled", + "l7CdWSXIV2vwOxgCbSUnC3qQRaGzyXdqflMxuJd3At6XtFxNJ6UQeTLg7Djrp/DpUvwlSy8hI+am8NGD", + "A5VvyH20sdfe7KvV1qesKUvgkD04IuSU23ht79hu55DuTM7v6V3zb3DWrLJZtZxR7egDjwe+Yr4reUtu", + "5ofZzcMUGFZ3y6nsIHsSxGwG0gdJehWpA3U0Vivvu5q7tXkaorJQxGSSpuzMnjiZOkSmqfzRhMn0pYM8", + "F1cJUlFS5/+K6RymXZtJ+oynTTeD7TkE8TZUuQt0S1Y0I6mQEtKwR/yJgwWqEBKSXGD4TcwzuNBGHiow", + "rpmTXCyJKI2aa9PoeR9KtCxNMJd9Zmt7JtZRM5DIAJR7VuumsY378+yoXnN4ZZyLVcTegoj2WD64/I0j", + "lIOrVgRgjiDQ/bam01h1n/a6uvWhhqq1aVGwNI7uP1eUyWBsyJ7aRZH11eToSiv5V4EDuIq6bHd7SG0d", + "uvlYP2mdM3nksQgAGPactmAY5T89FIwF1nVMaATJZ7XUOm2V3WWds+/z2VkaT6nVWldAzNiVBPdKzRag", + "61TOKale+VvMNO/rlkZPAYVPyGz5D6qsJcRbZFz1u654IMokhzW0HMru6VyVpqAUW0NYOc92JhlAifbJ", + "rtQc85SGXK4jSrm1J4GvbQx2o7KVRazdKbJHcIqKeRue2GOixh4lA9GaZRVt4U/dohbZUBmyCBv2sI7k", + "FAczifjidrGIvbENSPPRc8njoQ3hy83aKIKzZbXx1BJhc7JVSa/4sBIRsTvV/vbbr4PgYER1XlIPXvmy", + "3pWbKpCDlLGLMHr1A6MyhwJf/zVMeuLFLdc3ImNZUxdTkQGYas4zRu9BEx0WNCvolmRssQBpjflKU55R", + "mYXNGScpSE2Z0Wy26uZirYFWVjDdK9ka7oqDegYTk3HRLmUBybdOZbiF1Imem4jEaa9aLYZKJPZ2Jf6c", + "gG6MdI1xVQNE4B5Co2xtD5jgKCCRgl7CgfMo9jvsngbTkzjbnxY465gpYr7WG+ZWG8W6+2EIkdstKIa4", + "2zMUpl5s3nRJG82ClmR/QXZp/Ifm4hxXltF32ANe6DAMCjN6240D5ws/jvqhRkqwlI9DlNBa/j4fpFtg", + "I2kEW+QYgdZgE+HagPr2vgQOZvWy9tsO1RDtuncxz6Lgtshfzy1seZOt2hcQjjkLck3zz+/axQScp4gP", + "yN4NG4ND32CIZItKdbOXCa/pqLkDP+DdTc3foiv6H2D2KKqVuqGcCFOL9T6YB28WmlvDxcKX8FoDJ1c4", + "po1je/SczN3L7VJCylRXNLry1TVqVxgWm3KvQTZ6j+9t3zp/FvoWZLzwmgZ502TqRx1/yRsImyP6hZnK", + "wMmNUnmM+npkEcFfjEeFKdT2XBeXrQA3W/mk83JDSLjjQLcgZP3AQLd+crixy7PBXObSqRT01zn6tm7h", + "NnJRN2sbG6XZR+6udO5jgivjVRpMd4zutAjBEicEQSW/PvqVSFhgDUNBHj7ECR4+nLqmvz5ufzbH+eHD", + "qHT22eI6LY7cGG7eGMX8PPTSz75mG3hU2tmPiuXZPsJoPRFuqoDiI9hfXCKCL1KH9Bcba9I/qq4W3C0C", + "5CxiImttTR5MFTz+HfHu13WLvPJFP05aSaa3mB/R2w/YL9EI1O/qaCYXDVfrh+7u0+IS6gybTexTpfzt", + "+p2gOd5HVm3l5hYS+RH5ZkOLMgd3UL66N/8rPPnb0+z4yaO/zv92/Ow4hafPXhwf0xdP6aMXTx7B4789", + "e3oMjxbPX8wfZ4+fPp4/ffz0+bMX6ZOnj+ZPn7/46z3DhwzIFtCJz8Yz+b9YrDc5fXuWXBhgG5zQkn0P", + "W1sX0JCxrzhIUzyJUFCWT078T//bn7CjVBTN8P7XiUv2MVlpXaqT2ezq6uoo7DJbYrBDokWVrmZ+nl5J", + "wtO3Z7WXyFqBcEftO1lv3fOkcIrf3n1zfkFO354dBfXqTybHR8dHj7C8eQmclmxyMnmCP+HpWeG+zxyx", + "TU4+XU8nsxXQHGMDzR8FaMlS/0kCzbbu/+qKLpcgj1wZRvPT+vHMixWzTy7o43rXt1lY0WT2qRUbk+3p", + "iRUPZp98Ir/drVuZ8lxMUNBhJBS7ms3mmB9kbFNQQePhpaCyoWafUFwe/H3mEhrEP6LaYs/DzAeQxVu2", + "sPRJbwysnR4p1emqKmef8D9In9cuxBhi4WI2DwAlTfMpYZrQuZCYQU+nK8MjfOoupoKWE6RaS/BnmSF0", + "0+ulhcAn6bRZy0/e991ZOBDxIyFXMCTfHNrWTA1fRgtUkEi7vnVa7Zu75/1x8uLjp0fTR8fXfzF3i/vz", + "2ZPrkX6pl/W45Ly+OEY2/Ih5r9AAiWf58fHxLSrCn/IA/XaT6oc8kaLudieGXQZuqzoDkRoZe/LzdIaP", + "lZi9nk6eHrjinbak1uOmSKnYr2lGvMsf5370+eY+4xh1a3g8sXfY9XTy7HOu/owbkqc5wZZBwsX+1v/E", + "L7m44r6lETiqoqBy64+xajEF4jYbrzW6VBiHIdmaopzHBW9VkZt8xNifWNjFAL9Rmt6A35ybXv/mN5+L", + "3+Am3QW/aQ90x/zm8YFn/s+/4n9z2D8bhz237O5WHNYJfPZF+Exv+AzdWbNPLQHVfe4JqO3fm+5hi3Uh", + "MvAyqFgsbK75XZ9nn+y/wUSwKUGyArjNwel+ta/lZpgBctv/ecvT6I/9dXQLvcZ+nn1qFxpqIUitKp2J", + "K5v2LHplYTZ9mrvUu2iurVU/LYgfoHmaRH50r6nzLdqoWQaEYponUelGNzed6zCR2ntiRmiKQC8ZxwnQ", + "DI6z2BzTNAj6V5AKbkumdq5HB9kbkUH/esQL8LcK5La5AR2Mk2mLPzoCj2R0vvV102dn14eRP5rrra+p", + "Txx1ndTW37MryrS5RN0bIcRov7MGms9cQqDOr80b/N4XTCwQ/BjGukR/ndVFEaIfu6pw7KtTBQcaede7", + "/9yYxUIzE5JEbWB6/9HsLKbcddTSWE1OZjOMu18JpWeT6+mnjkUl/Pix3kyfJ7He1OuP1/8TAAD///aV", + "b43ZywAA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go index 56670010cb..6c99f788e9 100644 --- a/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/nonparticipating/public/routes.go @@ -702,252 +702,253 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", + "HOZ0AQA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go index 62afbd9f1c..15b8e7e02d 100644 --- a/daemon/algod/api/server/v2/generated/participating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go @@ -216,125 +216,125 @@ var swaggerSpec = []string{ "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", - "AP//ScSRWrDVAAA=", + "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", + "wpHC9Yfr/wkAAP//n/TLvvHVAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/generated/participating/public/routes.go b/daemon/algod/api/server/v2/generated/participating/public/routes.go index 92327891a4..14745a0baf 100644 --- a/daemon/algod/api/server/v2/generated/participating/public/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/public/routes.go @@ -235,133 +235,134 @@ var swaggerSpec = []string{ "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", + "AAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index 971a24b7c1..a8699c37c0 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -1745,7 +1745,12 @@ func (v2 *Handlers) GetTransactionGroupLedgerStateDeltasForRound(ctx echo.Contex if err != nil { return notFound(ctx, err, errFailedRetrievingStateDelta, v2.Log) } - data, err := encode(handle, deltas) + response := struct { + Deltas []eval.TxnGroupDeltaWithIds + }{ + Deltas: deltas, + } + data, err := encode(handle, response) if err != nil { return internalError(ctx, err, errFailedToEncodeResponse, v2.Log) } diff --git a/daemon/algod/api/server/v2/test/handlers_test.go b/daemon/algod/api/server/v2/test/handlers_test.go index ed9b8d83bc..e30169b4ad 100644 --- a/daemon/algod/api/server/v2/test/handlers_test.go +++ b/daemon/algod/api/server/v2/test/handlers_test.go @@ -2114,12 +2114,12 @@ func TestDeltasForTxnGroup(t *testing.T) { ) require.NoError(t, err) - var roundResponse model.TransactionGroupLedgerStateDeltaForRoundResponse + var roundResponse model.TransactionGroupLedgerStateDeltasForRoundResponse err = json.Unmarshal(rec.Body.Bytes(), &roundResponse) require.NoError(t, err) - require.Equal(t, 1, len(roundResponse)) - require.Equal(t, []string{txn1.ID().String()}, roundResponse[0].Ids) - hdr, ok := roundResponse[0].Delta["Hdr"].(map[string]interface{}) + require.Equal(t, 1, len(roundResponse.Deltas)) + require.Equal(t, []string{txn1.ID().String()}, roundResponse.Deltas[0].Ids) + hdr, ok := roundResponse.Deltas[0].Delta["Hdr"].(map[string]interface{}) require.True(t, ok) require.Equal(t, delta1.Hdr.Round, basics.Round(hdr["rnd"].(float64))) diff --git a/data/datatest/impls.go b/data/datatest/impls.go index 960b12e374..fefcb054da 100644 --- a/data/datatest/impls.go +++ b/data/datatest/impls.go @@ -107,8 +107,8 @@ func (i ledgerImpl) LookupAgreement(r basics.Round, addr basics.Address) (basics } // Circulation implements Ledger.Circulation. -func (i ledgerImpl) Circulation(r basics.Round) (basics.MicroAlgos, error) { - return i.l.Circulation(r) +func (i ledgerImpl) Circulation(r basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { + return i.l.Circulation(r, voteRnd) } // Wait implements Ledger.Wait. diff --git a/data/ledger.go b/data/ledger.go index 04e5320614..27949168fe 100644 --- a/data/ledger.go +++ b/data/ledger.go @@ -51,16 +51,17 @@ type Ledger struct { lastRoundSeed atomic.Value } -// roundCirculationPair used to hold a pair of matching round number and the amount of online money -type roundCirculationPair struct { +// roundCirculationItem used to hold matching round number, vote round and the amount of online money +type roundCirculationItem struct { round basics.Round + voteRound basics.Round onlineMoney basics.MicroAlgos } // roundCirculation is the cache for the circulating coins type roundCirculation struct { // elements holds several round-onlineMoney pairs - elements [2]roundCirculationPair + elements [2]roundCirculationItem } // roundSeedPair is the cache for a single seed at a given round @@ -174,28 +175,29 @@ func (l *Ledger) NextRound() basics.Round { } // Circulation implements agreement.Ledger.Circulation. -func (l *Ledger) Circulation(r basics.Round) (basics.MicroAlgos, error) { +func (l *Ledger) Circulation(r basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { circulation, cached := l.lastRoundCirculation.Load().(roundCirculation) if cached && r != basics.Round(0) { for _, element := range circulation.elements { - if element.round == r { + if element.round == r && element.voteRound == voteRnd { return element.onlineMoney, nil } } } - totals, err := l.OnlineTotals(r) + totals, err := l.OnlineCirculation(r, voteRnd) if err != nil { return basics.MicroAlgos{}, err } - if !cached || r > circulation.elements[1].round { + if !cached || r > circulation.elements[1].round || voteRnd > circulation.elements[1].voteRound { l.lastRoundCirculation.Store( roundCirculation{ - elements: [2]roundCirculationPair{ + elements: [2]roundCirculationItem{ circulation.elements[1], { round: r, + voteRound: voteRnd, onlineMoney: totals}, }, }) diff --git a/data/ledger_test.go b/data/ledger_test.go index 540dfea1d3..20a0828397 100644 --- a/data/ledger_test.go +++ b/data/ledger_test.go @@ -120,7 +120,8 @@ func testGenerateInitState(tb testing.TB, proto protocol.ConsensusVersion) (gene func TestLedgerCirculation(t *testing.T) { partitiontest.PartitionTest(t) - genesisInitState, keys := testGenerateInitState(t, protocol.ConsensusCurrentVersion) + proto := protocol.ConsensusCurrentVersion + genesisInitState, keys := testGenerateInitState(t, proto) const inMem = true cfg := config.GetDefaultLocal() @@ -171,6 +172,8 @@ func TestLedgerCirculation(t *testing.T) { srcAccountKey := keys[sourceAccount] require.NotNil(t, srcAccountKey) + params := config.Consensus[proto] + for rnd := basics.Round(1); rnd < basics.Round(600); rnd++ { blk.BlockHeader.Round++ blk.BlockHeader.TimeStamp += int64(crypto.RandUint64() % 100 * 1000) @@ -191,6 +194,8 @@ func TestLedgerCirculation(t *testing.T) { require.NoError(t, l.AddBlock(blk, agreement.Certificate{})) l.WaitForCommit(rnd) + var voteRoundOffset = basics.Round(2 * params.SeedRefreshInterval * params.SeedLookback) + // test most recent round if rnd < basics.Round(500) { data, validThrough, _, err = realLedger.LookupAccount(rnd, destAccount) @@ -202,11 +207,11 @@ func TestLedgerCirculation(t *testing.T) { require.Equal(t, rnd, validThrough) require.Equal(t, baseDestValue+uint64(rnd), data.MicroAlgos.Raw) - roundCirculation, err := realLedger.OnlineTotals(rnd) + roundCirculation, err := realLedger.OnlineCirculation(rnd, rnd+voteRoundOffset) require.NoError(t, err) require.Equal(t, baseCirculation-uint64(rnd)*(10001), roundCirculation.Raw) - roundCirculation, err = l.OnlineTotals(rnd) + roundCirculation, err = l.OnlineCirculation(rnd, rnd+voteRoundOffset) require.NoError(t, err) require.Equal(t, baseCirculation-uint64(rnd)*(10001), roundCirculation.Raw) } else if rnd < basics.Round(510) { @@ -220,11 +225,11 @@ func TestLedgerCirculation(t *testing.T) { require.Equal(t, rnd-1, validThrough) require.Equal(t, baseDestValue+uint64(rnd)-1, data.MicroAlgos.Raw) - roundCirculation, err := realLedger.OnlineTotals(rnd - 1) + roundCirculation, err := realLedger.OnlineCirculation(rnd-1, rnd-1+voteRoundOffset) require.NoError(t, err) require.Equal(t, baseCirculation-uint64(rnd-1)*(10001), roundCirculation.Raw) - roundCirculation, err = l.OnlineTotals(rnd - 1) + roundCirculation, err = l.OnlineCirculation(rnd-1, rnd-1+voteRoundOffset) require.NoError(t, err) require.Equal(t, baseCirculation-uint64(rnd-1)*(10001), roundCirculation.Raw) } else if rnd < basics.Round(520) { @@ -236,17 +241,17 @@ func TestLedgerCirculation(t *testing.T) { require.Error(t, err) require.Equal(t, uint64(0), data.MicroAlgos.Raw) - _, err = realLedger.OnlineTotals(rnd + 1) + _, err = realLedger.OnlineCirculation(rnd+1, rnd+1+voteRoundOffset) require.Error(t, err) - _, err = l.OnlineTotals(rnd + 1) + _, err = l.OnlineCirculation(rnd+1, rnd+1+voteRoundOffset) require.Error(t, err) } else if rnd < basics.Round(520) { // test expired round ( expected error ) - _, err = realLedger.OnlineTotals(rnd - 500) + _, err = realLedger.OnlineCirculation(rnd-500, rnd-500+voteRoundOffset) require.Error(t, err) - _, err = l.OnlineTotals(rnd - 500) + _, err = l.OnlineCirculation(rnd-500, rnd-500+voteRoundOffset) require.Error(t, err) } } diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go index 7aa1ac48f8..65f9f1dfb4 100644 --- a/data/transactions/logic/assembler.go +++ b/data/transactions/logic/assembler.go @@ -2193,6 +2193,9 @@ func pragma(ops *OpStream, tokens []string) error { if len(tokens) < 3 { return ops.error("no version value") } + if len(tokens) > 3 { + return ops.errorf("unexpected extra tokens: %s", strings.Join(tokens[3:], " ")) + } value := tokens[2] var ver uint64 if ops.pending.Len() > 0 { @@ -2222,6 +2225,9 @@ func pragma(ops *OpStream, tokens []string) error { if len(tokens) < 3 { return ops.error("no typetrack value") } + if len(tokens) > 3 { + return ops.errorf("unexpected extra tokens: %s", strings.Join(tokens[3:], " ")) + } value := tokens[2] on, err := strconv.ParseBool(value) if err != nil { diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go index dbc665e26e..dc970ef64f 100644 --- a/data/transactions/logic/assembler_test.go +++ b/data/transactions/logic/assembler_test.go @@ -2325,6 +2325,26 @@ func TestPragmas(t *testing.T) { ops = testProg(t, " #pragma version 5 ", assemblerNoVersion) require.Equal(t, uint64(5), ops.Version) + + testProg(t, "#pragma version 5 blah", assemblerNoVersion, + Expect{1, "unexpected extra tokens: blah"}) + + testProg(t, "#pragma typetrack", assemblerNoVersion, + Expect{1, "no typetrack value"}) + + testProg(t, "#pragma typetrack blah", assemblerNoVersion, + Expect{1, `bad #pragma typetrack: "blah"`}) + + testProg(t, "#pragma typetrack false blah", assemblerNoVersion, + Expect{1, "unexpected extra tokens: blah"}) + + // Currently pragmas don't treat semicolons as newlines. It would probably + // be nice to fix this. + testProg(t, "#pragma version 5; int 1", assemblerNoVersion, + Expect{1, "unexpected extra tokens: ; int 1"}) + + testProg(t, "#pragma typetrack false; int 1", assemblerNoVersion, + Expect{1, "unexpected extra tokens: ; int 1"}) } func TestAssemblePragmaVersion(t *testing.T) { diff --git a/data/txntest/txn.go b/data/txntest/txn.go index 2ad4bf27f3..5815aacc60 100644 --- a/data/txntest/txn.go +++ b/data/txntest/txn.go @@ -182,8 +182,7 @@ func assemble(source interface{}) []byte { } ops, err := logic.AssembleString(program) if err != nil { - fmt.Printf("Bad program %v", ops.Errors) - panic(ops.Errors) + panic(fmt.Sprintf("Bad program %v", ops.Errors)) } return ops.Program case []byte: diff --git a/ledger/acctonline.go b/ledger/acctonline.go index adb7c6693c..1a3544ba12 100644 --- a/ledger/acctonline.go +++ b/ledger/acctonline.go @@ -34,6 +34,7 @@ import ( "github.com/algorand/go-algorand/ledger/ledgercore" "github.com/algorand/go-algorand/ledger/store/trackerdb" "github.com/algorand/go-algorand/logging" + "github.com/algorand/go-algorand/protocol" "github.com/algorand/go-algorand/util/metrics" ) @@ -533,41 +534,64 @@ func (ao *onlineAccounts) postCommit(ctx context.Context, dcc *deferredCommitCon func (ao *onlineAccounts) postCommitUnlocked(ctx context.Context, dcc *deferredCommitContext) { } -// onlineTotals return the total online balance for the given round. -func (ao *onlineAccounts) onlineTotals(rnd basics.Round) (basics.MicroAlgos, error) { - ao.accountsMu.RLock() - defer ao.accountsMu.RUnlock() - return ao.onlineTotalsImpl(rnd) +// onlineCirculation return the total online balance for the given round, for use by agreement. +func (ao *onlineAccounts) onlineCirculation(rnd basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { + // Get cached total stake for rnd + totalStake, proto, err := ao.onlineTotals(rnd) + if err != nil { + return basics.MicroAlgos{}, err + } + + // Check if we need to subtract expired stake + if params := config.Consensus[proto]; params.ExcludeExpiredCirculation { + // Handle case when the balanceRound() used by agreement is 0, resulting in rnd=0. + // Agreement will ask us for the circulation at round 0 for the first 320 blocks. + // In this case, we don't subtract expired stake, since we are still using genesis balances. + // Agreement will later ask us for the balance of round 1 when the voteRnd is 321. + if rnd == 0 { + return totalStake, nil + } + expiredStake, err := ao.ExpiredOnlineCirculation(rnd, voteRnd) + if err != nil { + return basics.MicroAlgos{}, err + } + ot := basics.OverflowTracker{} + totalStake = ot.SubA(totalStake, expiredStake) + if ot.Overflowed { + return basics.MicroAlgos{}, fmt.Errorf("onlineTotals: overflow subtracting %v from %v", expiredStake, totalStake) + } + } + return totalStake, nil } // onlineTotalsEx return the total online balance for the given round for extended rounds range // by looking into DB func (ao *onlineAccounts) onlineTotalsEx(rnd basics.Round) (basics.MicroAlgos, error) { - ao.accountsMu.RLock() - totalsOnline, err := ao.onlineTotalsImpl(rnd) - ao.accountsMu.RUnlock() + totalsOnline, _, err := ao.onlineTotals(rnd) if err == nil { return totalsOnline, nil } var roundOffsetError *RoundOffsetError if !errors.As(err, &roundOffsetError) { - ao.log.Errorf("onlineTotalsImpl error: %v", err) + ao.log.Errorf("onlineTotals error: %v", err) } totalsOnline, err = ao.accountsq.LookupOnlineTotalsHistory(rnd) return totalsOnline, err } -// onlineTotalsImpl returns the online totals of all accounts at the end of round rnd. -func (ao *onlineAccounts) onlineTotalsImpl(rnd basics.Round) (basics.MicroAlgos, error) { +// onlineTotals returns the online totals of all accounts at the end of round rnd. +func (ao *onlineAccounts) onlineTotals(rnd basics.Round) (basics.MicroAlgos, protocol.ConsensusVersion, error) { + ao.accountsMu.RLock() + defer ao.accountsMu.RUnlock() offset, err := ao.roundParamsOffset(rnd) if err != nil { - return basics.MicroAlgos{}, err + return basics.MicroAlgos{}, "", err } onlineRoundParams := ao.onlineRoundParamsData[offset] - return basics.MicroAlgos{Raw: onlineRoundParams.OnlineSupply}, nil + return basics.MicroAlgos{Raw: onlineRoundParams.OnlineSupply}, onlineRoundParams.CurrentProtocol, nil } // LookupOnlineAccountData returns the online account data for a given address at a given round. @@ -815,6 +839,7 @@ func (ao *onlineAccounts) TopOnlineAccounts(rnd basics.Round, voteRnd basics.Rou if !(d.VoteFirstValid <= voteRnd && voteRnd <= d.VoteLastValid) { modifiedAccounts[addr] = nil invalidOnlineAccounts[addr] = accountDataToOnline(addr, &d, genesisProto) + continue } @@ -928,6 +953,21 @@ func (ao *onlineAccounts) TopOnlineAccounts(rnd basics.Round, voteRnd basics.Rou if err != nil { return nil, basics.MicroAlgos{}, err } + + // If set, return total online stake minus all future expired stake by voteRnd + if params.ExcludeExpiredCirculation { + expiredStake, err := ao.ExpiredOnlineCirculation(rnd, voteRnd) + if err != nil { + return nil, basics.MicroAlgos{}, err + } + ot := basics.OverflowTracker{} + onlineStake := ot.SubA(totalOnlineStake, expiredStake) + if ot.Overflowed { + return nil, basics.MicroAlgos{}, fmt.Errorf("TopOnlineAccounts: overflow subtracting ExpiredOnlineCirculation: %d - %d", totalOnlineStake, expiredStake) + } + return topOnlineAccounts, onlineStake, nil + } + ot := basics.OverflowTracker{} for _, oa := range invalidOnlineAccounts { totalOnlineStake = ot.SubA(totalOnlineStake, oa.MicroAlgos) @@ -947,5 +987,113 @@ func (ao *onlineAccounts) TopOnlineAccounts(rnd basics.Round, voteRnd basics.Rou } } +func (ao *onlineAccounts) onlineAcctsExpiredByRound(rnd, voteRnd basics.Round) (map[basics.Address]*ledgercore.OnlineAccountData, error) { + needUnlock := false + defer func() { + if needUnlock { + ao.accountsMu.RUnlock() + } + }() + + var expiredAccounts map[basics.Address]*ledgercore.OnlineAccountData + ao.accountsMu.RLock() + needUnlock = true + for { + currentDbRound := ao.cachedDBRoundOnline + currentDeltaLen := len(ao.deltas) + offset, err := ao.roundOffset(rnd) + if err != nil { + var roundOffsetError *RoundOffsetError + if !errors.As(err, &roundOffsetError) { + return nil, err + } + // roundOffsetError was returned, so the round number cannot be found in deltas, it is in history. + // This means offset will be 0 and ao.deltas[:offset] will be an empty slice. + } + paramsOffset, err := ao.roundParamsOffset(rnd) + if err != nil { + return nil, err + } + + rewardsParams := config.Consensus[ao.onlineRoundParamsData[paramsOffset].CurrentProtocol] + rewardsLevel := ao.onlineRoundParamsData[paramsOffset].RewardsLevel + + // Step 1: get all online accounts from DB for rnd + // Not unlocking ao.accountsMu yet, to stay consistent with Step 2 + var dbRound basics.Round + err = ao.dbs.Snapshot(func(ctx context.Context, tx trackerdb.SnapshotScope) (err error) { + ar, err := tx.MakeAccountsReader() + if err != nil { + return err + } + expiredAccounts, err = ar.ExpiredOnlineAccountsForRound(rnd, voteRnd, rewardsParams, rewardsLevel) + if err != nil { + return err + } + dbRound, err = ar.AccountsRound() + return err + }) + if err != nil { + return nil, err + } + + // If dbRound has advanced beyond the last read of ao.cachedDBRoundOnline, postCommmit has + // occurred since then, so wait until deltas is consistent with dbRound and try again. + if dbRound > currentDbRound { + // database round doesn't match the last au.dbRound we sampled. + for currentDbRound >= ao.cachedDBRoundOnline && currentDeltaLen == len(ao.deltas) { + ao.accountsReadCond.Wait() + } + continue // retry (restart for loop) + } + if dbRound < currentDbRound { + ao.log.Errorf("onlineAccounts.ValidOnlineCirculation: database round %d is behind in-memory round %d", dbRound, currentDbRound) + return nil, &StaleDatabaseRoundError{databaseRound: dbRound, memoryRound: currentDbRound} + } + + // Step 2: Apply pending changes for each block in deltas + // Iterate through per-round deltas up to offset: target round `rnd` is ao.deltas[offset-1]. + for o := uint64(0); o < offset; o++ { + for i := 0; i < ao.deltas[o].Len(); i++ { + addr, d := ao.deltas[o].GetByIdx(i) + // Each round's deltas can insert, update, or delete values in the onlineAccts map. + // Note, VoteFirstValid is not checked here on purpose since the current implementation does not allow + // setting VoteFirstValid into future. + if d.Status == basics.Online && d.VoteLastValid != 0 && voteRnd > d.VoteLastValid { + // Online expired: insert or overwrite the old data in expiredAccounts. + oadata := d.OnlineAccountData(rewardsParams, rewardsLevel) + expiredAccounts[addr] = &oadata + } else { + // addr went offline not expired, so do not report as an expired ONLINE account. + delete(expiredAccounts, addr) + } + } + } + break // successfully retrieved onlineAccts from DB & deltas + } + ao.accountsMu.RUnlock() + needUnlock = false + + return expiredAccounts, nil +} + +// ExpiredOnlineCirculation returns the total online stake for accounts with participation keys registered +// at round `rnd` that are expired by round `voteRnd`. +func (ao *onlineAccounts) ExpiredOnlineCirculation(rnd, voteRnd basics.Round) (basics.MicroAlgos, error) { + expiredAccounts, err := ao.onlineAcctsExpiredByRound(rnd, voteRnd) + if err != nil { + return basics.MicroAlgos{}, err + } + ot := basics.OverflowTracker{} + expiredStake := basics.MicroAlgos{} + for _, d := range expiredAccounts { + expiredStake = ot.AddA(expiredStake, d.MicroAlgosWithRewards) + if ot.Overflowed { + return basics.MicroAlgos{}, fmt.Errorf("ExpiredOnlineCirculation: overflow totaling expired stake") + } + } + return expiredStake, nil +} + var ledgerAccountsonlinetopCount = metrics.NewCounter("ledger_accountsonlinetop_count", "calls") var ledgerAccountsonlinetopMicros = metrics.NewCounter("ledger_accountsonlinetop_micros", "µs spent") diff --git a/ledger/acctonline_expired_test.go b/ledger/acctonline_expired_test.go new file mode 100644 index 0000000000..0645d0dd7f --- /dev/null +++ b/ledger/acctonline_expired_test.go @@ -0,0 +1,689 @@ +// Copyright (C) 2019-2023 Algorand, Inc. +// This file is part of go-algorand +// +// go-algorand 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. +// +// go-algorand 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 go-algorand. If not, see . + +package ledger + +import ( + "encoding/binary" + "math/rand" + "os" + "strconv" + "testing" + + "github.com/algorand/go-algorand/config" + "github.com/algorand/go-algorand/crypto" + "github.com/algorand/go-algorand/data/basics" + "github.com/algorand/go-algorand/data/bookkeeping" + "github.com/algorand/go-algorand/data/txntest" + ledgertesting "github.com/algorand/go-algorand/ledger/testing" + "github.com/algorand/go-algorand/protocol" + "github.com/algorand/go-algorand/test/partitiontest" + "github.com/stretchr/testify/require" +) + +// onlineAcctModel provides a simple interface for tracking accounts +// as they come online, go offline, and change their amount of stake. +// It is implemented by a real ledger (doubleLedgerAcctModel) for testing +// against a reference implementation (mapOnlineAcctModel). +type onlineAcctModel interface { + currentRound() basics.Round + nextRound() + advanceToRound(rnd basics.Round) + goOnline(addr basics.Address, firstvalid, lastvalid basics.Round) + goOffline(addr basics.Address) + updateStake(addr basics.Address, stake basics.MicroAlgos) + teardown() + + LookupAgreement(rnd basics.Round, addr basics.Address) onlineAcctModelAcct + OnlineCirculation(rnd basics.Round, voteRnd basics.Round) basics.MicroAlgos + ExpiredOnlineCirculation(rnd, voteRnd basics.Round) basics.MicroAlgos +} + +// mapOnlineAcctModel provides a reference implementation for tracking online accounts used +// for testing TopOnlineAccounts, ExpiredOnlineCirculation, and onlineAcctsExpiredByRound. +// It is an oracle that the doubleLedgerAcctModel is compared against. +type mapOnlineAcctModel struct { + t *testing.T + cur basics.Round + accts map[basics.Address]map[basics.Round]onlineAcctModelAcct + expiring map[basics.Round]map[basics.Address]struct{} +} + +type onlineAcctModelAcct struct { + Status basics.Status + VoteFirstValid, VoteLastValid basics.Round + Stake basics.MicroAlgos +} + +func newMapOnlineAcctModel(t *testing.T) *mapOnlineAcctModel { + return &mapOnlineAcctModel{ + t: t, + accts: make(map[basics.Address]map[basics.Round]onlineAcctModelAcct), + expiring: make(map[basics.Round]map[basics.Address]struct{}), + } +} + +func (m *mapOnlineAcctModel) teardown() {} +func (m *mapOnlineAcctModel) currentRound() basics.Round { return m.cur } +func (m *mapOnlineAcctModel) nextRound() { m.cur++ } +func (m *mapOnlineAcctModel) advanceToRound(rnd basics.Round) { + if rnd == m.cur { + return + } + require.Greater(m.t, rnd, m.cur, "cannot advance to previous round") + m.cur = rnd +} + +func (m *mapOnlineAcctModel) lookupAcctAsOf(rnd basics.Round, addr basics.Address) onlineAcctModelAcct { + require.LessOrEqual(m.t, rnd, m.cur, "cannot lookup acct for future round") + acctRounds, ok := m.accts[addr] + if !ok { + return onlineAcctModelAcct{} + } + // find the acct record for the most recent round <= rnd + for r := rnd; r >= 0; r-- { + if acct, ok := acctRounds[r]; ok { + return acct + } + } + // not found + return onlineAcctModelAcct{} +} + +func (m *mapOnlineAcctModel) LookupAgreement(rnd basics.Round, addr basics.Address) onlineAcctModelAcct { + return m.lookupAcctAsOf(rnd, addr) +} + +// look up all online accounts as of the given round +func (m *mapOnlineAcctModel) allOnlineAsOf(rnd basics.Round) map[basics.Address]onlineAcctModelAcct { + require.LessOrEqual(m.t, rnd, m.cur, "cannot lookup acct for future round") + accts := make(map[basics.Address]onlineAcctModelAcct) + for addr, acctRounds := range m.accts { + // find the acct record for the most recent round <= rnd + for r := rnd; r >= 0; r-- { + if acct, ok := acctRounds[r]; ok { + if acct.Status == basics.Online { + accts[addr] = acct + } + // found the most recent round <= rnd, so stop looking + // we will break even if the acct is offline + break + } + } + } + return accts +} + +func (m *mapOnlineAcctModel) OnlineCirculation(rnd basics.Round, voteRnd basics.Round) basics.MicroAlgos { + accts := m.allOnlineAsOf(rnd) + return m.sumAcctStake(accts) +} + +func (m *mapOnlineAcctModel) ExpiredOnlineCirculation(rnd, voteRnd basics.Round) basics.MicroAlgos { + accts := m.onlineAcctsExpiredByRound(rnd, voteRnd) + return m.sumAcctStake(accts) +} + +func (m *mapOnlineAcctModel) sumAcctStake(accts map[basics.Address]onlineAcctModelAcct) basics.MicroAlgos { + algops := MicroAlgoOperations{a: require.New(m.t)} + var ret basics.MicroAlgos + for _, acct := range accts { + ret = algops.Add(ret, acct.Stake) + } + return ret +} + +func (m *mapOnlineAcctModel) setAcct(rnd basics.Round, addr basics.Address, acct onlineAcctModelAcct) { + require.Equal(m.t, rnd, m.cur, "cannot set acct for round other than current round") + + acctRounds, ok := m.accts[addr] + if !ok { + acctRounds = make(map[basics.Round]onlineAcctModelAcct) + } + acctRounds[rnd] = acct + m.accts[addr] = acctRounds +} + +func (m *mapOnlineAcctModel) goOnline(addr basics.Address, firstvalid, lastvalid basics.Round) { + rnd := m.cur + oldAcct := m.lookupAcctAsOf(rnd, addr) + + // if is already online, remove old lastvalid round from expiring map + if oldAcct.Status == basics.Online { + require.Contains(m.t, m.expiring, oldAcct.VoteLastValid, "round should be in expiring map") + require.Contains(m.t, m.expiring[oldAcct.VoteLastValid], addr, "address should be in expiring map") + delete(m.expiring[oldAcct.VoteLastValid], addr) + } + + // create new acct record + newAcct := onlineAcctModelAcct{ + Status: basics.Online, + VoteFirstValid: firstvalid, + VoteLastValid: lastvalid, + Stake: oldAcct.Stake, + } + m.setAcct(rnd, addr, newAcct) + + // remember when this account will expire + expiring, ok := m.expiring[lastvalid] + if !ok { + expiring = make(map[basics.Address]struct{}) + } + expiring[addr] = struct{}{} + m.expiring[lastvalid] = expiring + +} + +func (m *mapOnlineAcctModel) goOffline(addr basics.Address) { + rnd := m.cur + oldAcct := m.lookupAcctAsOf(rnd, addr) + + // must already be online: remove old lastvalid round from expiring map + require.Equal(m.t, basics.Online, oldAcct.Status, "cannot go offline if not online") + require.Contains(m.t, m.expiring, oldAcct.VoteLastValid, "round should be in expiring map") + require.Contains(m.t, m.expiring[oldAcct.VoteLastValid], addr, "address should be in expiring map") + delete(m.expiring[oldAcct.VoteLastValid], addr) + + newAcct := onlineAcctModelAcct{ + Status: basics.Offline, + VoteFirstValid: 0, + VoteLastValid: 0, + Stake: oldAcct.Stake, + } + m.setAcct(rnd, addr, newAcct) +} + +func (m *mapOnlineAcctModel) updateStake(addr basics.Address, stake basics.MicroAlgos) { + rnd := m.cur + acct := m.lookupAcctAsOf(rnd, addr) + acct.Stake = stake + m.setAcct(rnd, addr, acct) +} + +func (m *mapOnlineAcctModel) onlineAcctsExpiredByRound(rnd, voteRnd basics.Round) map[basics.Address]onlineAcctModelAcct { + require.LessOrEqual(m.t, rnd, m.cur, "cannot lookup expired accts for future round") + + // get all online addresses as of rnd + ret := make(map[basics.Address]onlineAcctModelAcct) + for addr, acct := range m.allOnlineAsOf(rnd) { + require.NotZero(m.t, acct.VoteLastValid, "offline acct returned by allOnlineAsOf") + // will this acct be expired by voteRnd? + if voteRnd > acct.VoteLastValid { + ret[addr] = acct + } + } + return ret +} + +// doubleLedgerAcctModel implements an onlineAcctModel using DoubleLedger, which starts up two +// Ledger instances, a generator and a validator. +type doubleLedgerAcctModel struct { + t testing.TB + params *config.ConsensusParams + dl *DoubleLedger + ops *MicroAlgoOperations + genAddrs []basics.Address + genBalances bookkeeping.GenesisBalances + genSecrets []*crypto.SignatureSecrets + // new accounts made by goOnline, balance value tracks uncommitted balance changes before dl.endBlock() + accts map[basics.Address]basics.MicroAlgos +} + +func newDoubleLedgerAcctModel(t testing.TB, proto protocol.ConsensusVersion, inMem bool) *doubleLedgerAcctModel { + // set 1 Algo for rewards pool size -- rewards math not supported by newMapOnlineAcctModel + genesisOpt := ledgertesting.TestGenesisRewardsPoolSize(basics.MicroAlgos{Raw: 1_000_000}) + genBalances, genAddrs, genSecrets := ledgertesting.NewTestGenesis(genesisOpt) + cfg := config.GetDefaultLocal() + opts := []simpleLedgerOption{simpleLedgerNotArchival()} + if !inMem { + opts = append(opts, simpleLedgerOnDisk()) + } + dl := NewDoubleLedger(t, genBalances, proto, cfg, opts...) + dl.beginBlock() + params := config.Consensus[proto] + return &doubleLedgerAcctModel{ + t: t, + params: ¶ms, + ops: &MicroAlgoOperations{a: require.New(t)}, + dl: &dl, + genAddrs: genAddrs, + genBalances: genBalances, + genSecrets: genSecrets, + accts: make(map[basics.Address]basics.MicroAlgos), + } +} + +func (m *doubleLedgerAcctModel) teardown() { m.dl.Close() } + +func (m *doubleLedgerAcctModel) nextRound() { + m.dl.endBlock() + m.dl.beginBlock() +} + +func (m *doubleLedgerAcctModel) currentRound() basics.Round { + genRound := m.dl.generator.Latest() + valRound := m.dl.validator.Latest() + require.Equal(m.t, genRound, valRound) + return genRound + 1 +} + +func (m *doubleLedgerAcctModel) advanceToRound(rnd basics.Round) { + if rnd == m.currentRound() { + return + } + require.Greater(m.t, rnd, m.currentRound(), "cannot advance to previous round") + for m.currentRound() < rnd { + m.nextRound() + } + require.Equal(m.t, rnd, m.currentRound()) +} + +const doubleLedgerAcctModelAcctInitialBalance = 1_234_567 + +func (m *doubleLedgerAcctModel) goOnline(addr basics.Address, firstvalid, lastvalid basics.Round) { + if _, ok := m.accts[addr]; !ok { + // not yet in the ledger: send 1 algo from a genesis account + m.dl.txn(&txntest.Txn{ + Type: protocol.PaymentTx, + Sender: m.genAddrs[0], + Receiver: addr, + Amount: doubleLedgerAcctModelAcctInitialBalance, + }) + m.accts[addr] = basics.MicroAlgos{Raw: doubleLedgerAcctModelAcctInitialBalance} + } + + require.NotZero(m.t, addr, "cannot go online with zero address") + + minFee := m.params.MinTxnFee // subtract minFee from account balance + m.dl.txn(&txntest.Txn{ + Type: protocol.KeyRegistrationTx, + Sender: addr, + VoteFirst: firstvalid, + VoteLast: lastvalid, + Fee: minFee, + + Nonparticipation: false, // XXX test nonparticipating accounts + + // meaningless non-zero voting data + VotePK: crypto.OneTimeSignatureVerifier(addr), + SelectionPK: crypto.VRFVerifier(addr), + VoteKeyDilution: 1024, + }) + m.accts[addr] = m.ops.Sub(m.accts[addr], basics.MicroAlgos{Raw: minFee}) +} + +func (m *doubleLedgerAcctModel) goOffline(addr basics.Address) { + require.Contains(m.t, m.accts, addr, "cannot go offline with unknown address") + + minFee := m.params.MinTxnFee // subtract minFee from account balance + m.dl.txn(&txntest.Txn{ + Type: protocol.KeyRegistrationTx, + Sender: addr, + Fee: minFee, + + // not necessary to specify + VoteFirst: 0, + VoteLast: 0, + VotePK: crypto.OneTimeSignatureVerifier{}, + SelectionPK: crypto.VRFVerifier{}, + VoteKeyDilution: 0, + }) + m.accts[addr] = m.ops.Sub(m.accts[addr], basics.MicroAlgos{Raw: minFee}) +} + +func (m *doubleLedgerAcctModel) updateStake(addr basics.Address, amount basics.MicroAlgos) { + curStake := m.accts[addr] + require.GreaterOrEqual(m.t, amount.Raw, curStake.Raw, "currently cannot decrease stake") + if amount == curStake { + return + } + if amount.Raw > curStake.Raw { + sendAmt := m.ops.Sub(amount, curStake) + // send more algo from a genesis account + m.dl.txn(&txntest.Txn{ + Type: protocol.PaymentTx, + Sender: m.genAddrs[0], + Receiver: addr, + Amount: sendAmt.Raw, + Fee: m.params.MinTxnFee, + }) + m.accts[addr] = amount + m.t.Logf("updateStake addr %s sent %d, bal %d", addr, sendAmt, amount) + } +} + +// OnlineCirculation returns the total online stake at rnd this model produced, while +// also asserting that the validator and generator Ledgers both agree, and that different +// Ledger/tracker methods used to retrieve and calculate the stake internally agree. +func (m *doubleLedgerAcctModel) OnlineCirculation(rnd basics.Round, voteRnd basics.Round) basics.MicroAlgos { + valTotal, err := m.dl.validator.OnlineTotalStake(rnd) + require.NoError(m.t, err) + genTotal, err := m.dl.generator.OnlineTotalStake(rnd) + require.NoError(m.t, err) + require.Equal(m.t, valTotal, genTotal) + + valStake, err := m.dl.validator.OnlineCirculation(rnd, voteRnd) + require.NoError(m.t, err) + genStake, err := m.dl.generator.OnlineCirculation(rnd, voteRnd) + require.NoError(m.t, err) + require.Equal(m.t, valStake, genStake) + + // If ExcludeExpiredCirculation is set, this means OnlineCirculation + // has already subtracted the expired stake. So to get the total, add + // it back in by querying ExpiredOnlineCirculation. + if m.params.ExcludeExpiredCirculation { + expiredStake := m.ExpiredOnlineCirculation(rnd, rnd+320) + valStake = m.ops.Add(valStake, expiredStake) + } + + // This should equal the value of onlineTotalsImpl(rnd) which provides + // the total online stake without subtracting expired stake. + require.Equal(m.t, valTotal, valStake) + + return valStake +} + +// OnlineTotalStake is a wrapper to access onlineAccounts.onlineTotalsImpl safely. +func (l *Ledger) OnlineTotalStake(rnd basics.Round) (basics.MicroAlgos, error) { + l.trackerMu.RLock() + defer l.trackerMu.RUnlock() + totalStake, _, err := l.acctsOnline.onlineTotals(rnd) + return totalStake, err +} + +// ExpiredOnlineCirculation is a wrapper to call onlineAccounts.ExpiredOnlineCirculation safely. +func (l *Ledger) ExpiredOnlineCirculation(rnd, voteRnd basics.Round) (basics.MicroAlgos, error) { + l.trackerMu.RLock() + defer l.trackerMu.RUnlock() + return l.acctsOnline.ExpiredOnlineCirculation(rnd, voteRnd) +} + +// ExpiredOnlineCirculation returns the total expired stake at rnd this model produced, while +// also asserting that the validator and generator Ledgers both agree. +func (m *doubleLedgerAcctModel) ExpiredOnlineCirculation(rnd, voteRnd basics.Round) basics.MicroAlgos { + valStake, err := m.dl.validator.ExpiredOnlineCirculation(rnd, voteRnd) + require.NoError(m.t, err) + genStake, err := m.dl.generator.ExpiredOnlineCirculation(rnd, voteRnd) + require.NoError(m.t, err) + require.Equal(m.t, valStake, genStake) + return valStake +} + +func (m *doubleLedgerAcctModel) LookupAgreement(rnd basics.Round, addr basics.Address) onlineAcctModelAcct { + valAcct, err := m.dl.validator.LookupAgreement(rnd, addr) + require.NoError(m.t, err) + genAcct, err := m.dl.generator.LookupAgreement(rnd, addr) + require.NoError(m.t, err) + require.Equal(m.t, valAcct, genAcct) + + status := basics.Offline + if valAcct.VoteLastValid > 0 || valAcct.VoteFirstValid > 0 { + status = basics.Online + } + return onlineAcctModelAcct{ + VoteFirstValid: valAcct.VoteFirstValid, + VoteLastValid: valAcct.VoteLastValid, + Status: status, + Stake: valAcct.MicroAlgosWithRewards, + } +} + +//nolint:paralleltest // don't want to parallelize this test +func TestOnlineAcctModelSimple(t *testing.T) { + partitiontest.PartitionTest(t) + + // first test using the in-memory model + t.Run("Map", func(t *testing.T) { + m := newMapOnlineAcctModel(t) + testOnlineAcctModelSimple(t, m) + }) + // test same scenario on double ledger + t.Run("DoubleLedger", func(t *testing.T) { + m := newDoubleLedgerAcctModel(t, protocol.ConsensusFuture, true) + defer m.teardown() + testOnlineAcctModelSimple(t, m) + }) +} + +func testOnlineAcctModelSimple(t *testing.T, m onlineAcctModel) { + // acct 1 has 10 algos expiring at round 2000 + m.goOnline(basics.Address{1}, 1, 2000) + m.updateStake(basics.Address{1}, basics.MicroAlgos{Raw: 10_000_000}) + // acct 2 has 11 algos expiring at round 999 + m.goOnline(basics.Address{2}, 1, 999) + m.updateStake(basics.Address{2}, basics.MicroAlgos{Raw: 11_000_000}) + + m.advanceToRound(500) + // acct 3 has 11.1 algos expiring at round 2500 + m.goOnline(basics.Address{3}, 500, 2500) + m.updateStake(basics.Address{3}, basics.MicroAlgos{Raw: 11_100_000}) + + m.advanceToRound(600) + // acct 4 has 11.11 algos expiring at round 900 + m.goOnline(basics.Address{4}, 600, 900) + m.updateStake(basics.Address{4}, basics.MicroAlgos{Raw: 11_110_000}) + + m.advanceToRound(1000) + // total stake is all 4 accounts + a := require.New(t) + onlineStake := m.OnlineCirculation(680, 1000) + a.Equal(basics.MicroAlgos{Raw: 43_210_000}, onlineStake) + + // expired stake is acct 2 + acct 4 + expiredStake := m.ExpiredOnlineCirculation(680, 1000) + a.Equal(basics.MicroAlgos{Raw: 22_110_000}, expiredStake) +} + +// An onlineScenario is a list of actions to take at each round, which are +// applied to the onlineAcctModel implementations (real and oracle) being tested. +type onlineScenario struct { + // roundActions is a list of actions to take in each round, must be in rnd order + roundActions []onlineScenarioRound +} + +type onlineScenarioRound struct { + rnd basics.Round + actions []onlineScenarioRoundAction +} + +// An onlineScenarioRoundAction is an action to take on an onlineAcctModel in a given round. +type onlineScenarioRoundAction interface { + apply(t *testing.T, m onlineAcctModel) +} + +type goOnlineWithStakeAction struct { + addr basics.Address + fv, lv basics.Round + stake uint64 +} + +func (a goOnlineWithStakeAction) apply(t *testing.T, m onlineAcctModel) { + m.goOnline(a.addr, a.fv, a.lv) + m.updateStake(a.addr, basics.MicroAlgos{Raw: a.stake}) +} + +type goOfflineAction struct{ addr basics.Address } + +func (a goOfflineAction) apply(t *testing.T, m onlineAcctModel) { m.goOffline(a.addr) } + +type updateStakeAction struct { + addr basics.Address + stake uint64 +} + +func (a updateStakeAction) apply(t *testing.T, m onlineAcctModel) { + m.updateStake(a.addr, basics.MicroAlgos{Raw: a.stake}) +} + +type checkOnlineStakeAction struct { + rnd, voteRnd basics.Round + online, expired uint64 +} + +func (a checkOnlineStakeAction) apply(t *testing.T, m onlineAcctModel) { + onlineStake := m.OnlineCirculation(a.rnd, a.voteRnd) + expiredStake := m.ExpiredOnlineCirculation(a.rnd, a.voteRnd) + require.Equal(t, basics.MicroAlgos{Raw: a.online}, onlineStake, "round %d, cur %d", a.rnd, m.currentRound()) + require.Equal(t, basics.MicroAlgos{Raw: a.expired}, expiredStake, "rnd %d voteRnd %d, cur %d", a.rnd, a.voteRnd, m.currentRound()) +} + +// simpleOnlineScenario is the same as the TestOnlineAcctModelSimple test +// but expressed as an onlineScenario +var simpleOnlineScenario = onlineScenario{ + roundActions: []onlineScenarioRound{ + {1, []onlineScenarioRoundAction{ + // acct 1 has 10 algos expiring at round 2000 + goOnlineWithStakeAction{basics.Address{1}, 1, 2000, 10_000_000}, + // acct 2 has 11 algos expiring at round 999 + goOnlineWithStakeAction{basics.Address{2}, 1, 999, 11_000_000}, + }}, + {500, []onlineScenarioRoundAction{ + // acct 3 has 11.1 algos expiring at round 2500 + goOnlineWithStakeAction{basics.Address{3}, 500, 2500, 11_100_000}, + }}, + {600, []onlineScenarioRoundAction{ + // acct 4 has 11.11 algos expiring at round 900 + goOnlineWithStakeAction{basics.Address{4}, 600, 900, 11_110_000}, + }}, + {681, []onlineScenarioRoundAction{ + // total stake is all 4 accounts + // expired stake is acct 2 + acct 4 + checkOnlineStakeAction{680, 1000, 43_210_000, 22_110_000}, + }}, + {1000, []onlineScenarioRoundAction{ + // check total & expired stake again at round 1000, should be the same + checkOnlineStakeAction{680, 1000, 43_210_000, 22_110_000}, + }}, + }, +} + +// a quick helper function for making it easier to identify whose balances are missing +func shift1AlgoBy(n uint64) uint64 { return 1_000_000 << n } + +// simpleOfflineOnlineScenario is like simpleOnlineScenario but with acct 2 +// going from online+expired to offline at round 999. +var simpleOfflineOnlineScenario = onlineScenario{ + roundActions: []onlineScenarioRound{ + {1, []onlineScenarioRoundAction{ + goOnlineWithStakeAction{basics.Address{1}, 1, 2000, shift1AlgoBy(1)}, + goOnlineWithStakeAction{basics.Address{2}, 1, 999, shift1AlgoBy(2)}, + }}, + {500, []onlineScenarioRoundAction{ + goOnlineWithStakeAction{basics.Address{3}, 500, 2500, shift1AlgoBy(3)}, + }}, + {600, []onlineScenarioRoundAction{ + goOnlineWithStakeAction{basics.Address{4}, 600, 900, shift1AlgoBy(4)}, // expired by 1000 + }}, + {679, []onlineScenarioRoundAction{ + goOnlineWithStakeAction{basics.Address{5}, 679, 999, shift1AlgoBy(5)}, // expired by 1000 + goOfflineAction{basics.Address{2}}, // was going to expire at 999 but now is offline + }}, + {680, []onlineScenarioRoundAction{ + goOnlineWithStakeAction{basics.Address{6}, 680, 999, shift1AlgoBy(6)}, // expired by 1000 + goOnlineWithStakeAction{basics.Address{7}, 680, 1000, shift1AlgoBy(7)}, + }}, + {1000, []onlineScenarioRoundAction{ + checkOnlineStakeAction{680, 1000, 250_000_000, 112_000_000}, + }}, + }, +} + +//nolint:paralleltest // don't want to parallelize this test +func TestOnlineAcctModelScenario(t *testing.T) { + partitiontest.PartitionTest(t) + + runScenario := func(t *testing.T, m onlineAcctModel, s onlineScenario) { + for _, ra := range s.roundActions { + m.advanceToRound(ra.rnd) + for _, action := range ra.actions { + action.apply(t, m) + } + } + } + + for _, tc := range []struct { + name string + scenario onlineScenario + }{ + {"Simple", simpleOnlineScenario}, + {"SimpleOffline", simpleOfflineOnlineScenario}, + } { + t.Run(tc.name, func(t *testing.T) { + // first test using the in-memory model + t.Run("Map", func(t *testing.T) { + m := newMapOnlineAcctModel(t) + runScenario(t, m, tc.scenario) + }) + // test same scenario on double ledger + t.Run("DoubleLedger", func(t *testing.T) { + m := newDoubleLedgerAcctModel(t, protocol.ConsensusFuture, true) + defer m.teardown() + runScenario(t, m, tc.scenario) + }) + }) + } +} + +func BenchmarkExpiredOnlineCirculation(b *testing.B) { + // set up totalAccounts online accounts in 10k batches + totalAccounts := 100_000 + const maxKeyregPerBlock = 10_000 + // if TOTAL_ACCOUNTS env var set, override totalAccounts + if n, err := strconv.Atoi(os.Getenv("TOTAL_ACCOUNTS")); err == nil { + b.Logf("using %d accounts", n) + if n%maxKeyregPerBlock != 0 { + b.Fatalf("TOTAL_ACCOUNTS %d must be a multiple of %d", n, maxKeyregPerBlock) + } + totalAccounts = n + } + + proto := protocol.ConsensusFuture + m := newDoubleLedgerAcctModel(b, proto, false) + defer m.teardown() + + addrFromUint64 := func(n uint64) basics.Address { + var addr basics.Address + binary.BigEndian.PutUint64(addr[:], n) + return addr + } + + var blockCounter, acctCounter uint64 + for i := 0; i < totalAccounts/maxKeyregPerBlock; i++ { + blockCounter++ + for j := 0; j < maxKeyregPerBlock; j++ { + acctCounter++ + // go online for a random number of rounds, from 400 to 1600 + validFor := 400 + uint64(rand.Intn(1200)) + m.goOnline(addrFromUint64(acctCounter), basics.Round(blockCounter), basics.Round(blockCounter+validFor)) + } + b.Log("built block", blockCounter, "accts", acctCounter) + m.nextRound() + } + // then advance ~1K rounds to exercise the exercise accounts going offline + m.advanceToRound(basics.Round(blockCounter + 1000)) + b.Log("advanced to round", m.currentRound()) + + b.ResetTimer() + for i := uint64(0); i < uint64(b.N); i++ { + // query expired circulation across the available range (last 320 rounds, from ~680 to ~1000) + startRnd := m.currentRound() - 320 + offset := basics.Round(i % 320) + _, err := m.dl.validator.ExpiredOnlineCirculation(startRnd+offset, startRnd+offset+320) + require.NoError(b, err) + //total, err := m.dl.validator.OnlineTotalStake(startRnd + offset) + //b.Log("expired circulation", startRnd+offset, startRnd+offset+320, "returned", expiredStake, "total", total) + } +} diff --git a/ledger/acctonline_test.go b/ledger/acctonline_test.go index 049a703d5a..803cf9f773 100644 --- a/ledger/acctonline_test.go +++ b/ledger/acctonline_test.go @@ -21,6 +21,7 @@ import ( "database/sql" "fmt" "sort" + "strconv" "testing" "time" @@ -781,7 +782,7 @@ func TestAcctOnlineRoundParamsCache(t *testing.T) { accts = append(accts, newAccts) if i > basics.Round(maxBalLookback) && i%10 == 0 { - onlineTotal, err := ao.onlineTotals(i - basics.Round(maxBalLookback)) + onlineTotal, err := ao.onlineCirculation(i-basics.Round(maxBalLookback), i) require.NoError(t, err) require.Equal(t, allTotals[i-basics.Round(maxBalLookback)].Online.Money, onlineTotal) expectedConsensusVersion := testProtocolVersion1 @@ -822,7 +823,7 @@ func TestAcctOnlineRoundParamsCache(t *testing.T) { require.Equal(t, ao.onlineRoundParamsData[:basics.Round(maxBalLookback)], dbOnlineRoundParams) for i := ml.Latest() - basics.Round(maxBalLookback); i < ml.Latest(); i++ { - onlineTotal, err := ao.onlineTotals(i) + onlineTotal, err := ao.onlineCirculation(i, i+basics.Round(maxBalLookback)) require.NoError(t, err) require.Equal(t, allTotals[i].Online.Money, onlineTotal) } @@ -1421,7 +1422,7 @@ func TestAcctOnlineTop(t *testing.T) { conf := config.GetDefaultLocal() au, oa := newAcctUpdates(t, ml, conf) defer oa.close() - initialOnlineTotals, err := oa.onlineTotals(0) + initialOnlineTotals, err := oa.onlineCirculation(0, basics.Round(oa.maxBalLookback())) a.NoError(err) top := compareOnlineTotals(a, oa, 0, 0, 5, initialOnlineTotals, initialOnlineTotals) compareTopAccounts(a, top, allAccts) @@ -1484,7 +1485,20 @@ func TestAcctOnlineTop(t *testing.T) { func TestAcctOnlineTopInBatches(t *testing.T) { partitiontest.PartitionTest(t) - a := require.New(t) + + intToAddress := func(n int) basics.Address { + var addr basics.Address + pos := 0 + for { + addr[pos] = byte(n % 10) + n /= 10 + if n == 0 { + break + } + pos++ + } + return addr + } const numAccts = 2048 allAccts := make([]basics.BalanceRecord, numAccts) @@ -1493,11 +1507,11 @@ func TestAcctOnlineTopInBatches(t *testing.T) { for i := 0; i < numAccts; i++ { allAccts[i] = basics.BalanceRecord{ - Addr: ledgertesting.RandomAddress(), + Addr: intToAddress(i + 1), AccountData: basics.AccountData{ MicroAlgos: basics.MicroAlgos{Raw: uint64(i + 1)}, Status: basics.Online, - VoteLastValid: 1000, + VoteLastValid: basics.Round(i + 1), VoteFirstValid: 0, RewardsBase: 0}, } @@ -1505,17 +1519,55 @@ func TestAcctOnlineTopInBatches(t *testing.T) { } addSinkAndPoolAccounts(genesisAccts) - ml := makeMockLedgerForTracker(t, true, 1, protocol.ConsensusCurrentVersion, genesisAccts) - defer ml.Close() + for _, proto := range []protocol.ConsensusVersion{protocol.ConsensusV36, protocol.ConsensusFuture} { + t.Run(string(proto), func(t *testing.T) { + a := require.New(t) + params := config.Consensus[proto] + ml := makeMockLedgerForTracker(t, true, 1, proto, genesisAccts) + defer ml.Close() - conf := config.GetDefaultLocal() - _, oa := newAcctUpdates(t, ml, conf) - defer oa.close() + conf := config.GetDefaultLocal() + au, oa := newAcctUpdates(t, ml, conf) + defer oa.close() - proto := config.Consensus[protocol.ConsensusCurrentVersion] - top, _, err := oa.TopOnlineAccounts(0, 0, 2048, &proto, 0) - a.NoError(err) - compareTopAccounts(a, top, allAccts) + top, totalOnlineStake, err := oa.TopOnlineAccounts(0, 0, numAccts, ¶ms, 0) + a.NoError(err) + compareTopAccounts(a, top, allAccts) + a.Equal(basics.MicroAlgos{Raw: 2048 * 2049 / 2}, totalOnlineStake) + + // add 300 blocks so the first 300 accounts expire + // at the last block put the 299th account offline to trigger TopOnlineAccounts behavior difference + _, totals, err := au.LatestTotals() + a.NoError(err) + acct299 := allAccts[298] + for i := 1; i <= 300; i++ { + var updates ledgercore.AccountDeltas + if i == 300 { + updates.Upsert(acct299.Addr, ledgercore.AccountData{ + AccountBaseData: ledgercore.AccountBaseData{Status: basics.Offline, MicroAlgos: acct299.MicroAlgos}, + VotingData: ledgercore.VotingData{}, + }) + } + newBlockWithUpdates(genesisAccts, updates, totals, t, ml, i, oa) + } + a.Equal(basics.Round(300), oa.latest()) + + // 299 accts expired at voteRnd = 300 + top, totalOnlineStake, err = oa.TopOnlineAccounts(0, 300, numAccts, ¶ms, 0) + a.NoError(err) + compareTopAccounts(a, top, allAccts) + a.Equal(basics.MicroAlgos{Raw: 2048*2049/2 - 299*300/2}, totalOnlineStake) + + // check the behavior difference between ConsensusV36 and ConsensusFuture + var correction uint64 + if proto == protocol.ConsensusV36 { + correction = acct299.MicroAlgos.Raw + } + _, totalOnlineStake, err = oa.TopOnlineAccounts(300, 300, numAccts, ¶ms, 0) + a.NoError(err) + a.Equal(basics.MicroAlgos{Raw: 2048*2049/2 - 299*300/2 - correction}, totalOnlineStake) + }) + } } func TestAcctOnlineTopBetweenCommitAndPostCommit(t *testing.T) { @@ -1763,7 +1815,8 @@ func TestAcctOnlineTop_ChangeOnlineStake(t *testing.T) { totals = newBlockWithUpdates(genesisAccts, updates, totals, t, ml, i, oa) } - initialOnlineStake, err := oa.onlineTotals(0) + params := config.Consensus[protocol.ConsensusCurrentVersion] + initialOnlineStake, err := oa.onlineCirculation(0, basics.Round(params.MaxBalLookback)) a.NoError(err) rnd15TotalOnlineStake := algops.Sub(initialOnlineStake, allAccts[15].MicroAlgos) // 15 is offline @@ -1808,9 +1861,318 @@ func compareOnlineTotals(a *require.Assertions, oa *onlineAccounts, rnd, voteRnd top, onlineTotalVoteRnd, err := oa.TopOnlineAccounts(rnd, voteRnd, n, &proto, 0) a.NoError(err) a.Equal(expectedForVoteRnd, onlineTotalVoteRnd) - onlineTotalsRnd, err := oa.onlineTotals(rnd) + onlineTotalsRnd, err := oa.onlineCirculation(rnd, voteRnd) a.NoError(err) a.Equal(expectedForRnd, onlineTotalsRnd) a.LessOrEqual(onlineTotalVoteRnd.Raw, onlineTotalsRnd.Raw) return top } + +// TestAcctOnline_ExpiredOnlineCirculation mutates online state in deltas and DB +// to ensure ExpiredOnlineCirculation returns expected online stake value +// The test exercises all possible combinations for offline, online and expired values for two accounts. +func TestAcctOnline_ExpiredOnlineCirculation(t *testing.T) { + partitiontest.PartitionTest(t) + a := require.New(t) + algops := MicroAlgoOperations{a: a} + + // powInt is a helper function to calculate powers of uint64 + powInt := func(x, y uint64) uint64 { + ret := uint64(1) + if x == 0 { + return ret + } + for i := uint64(0); i < y; i++ { + ret *= x + } + return ret + } + + // add some genesis online accounts with stake 1, 10, 20, 30... in order to see which account stake + // not included into results while debugging + const numAccts = 20 + allAccts := make([]basics.BalanceRecord, numAccts) + genesisAccts := []map[basics.Address]basics.AccountData{{}} + genesisAccts[0] = make(map[basics.Address]basics.AccountData, numAccts) + totalStake := basics.MicroAlgos{Raw: 0} + for i := 0; i < numAccts-1; i++ { + stake := i * 10 + if stake == 0 { + stake = 1 + } + allAccts[i] = basics.BalanceRecord{ + Addr: ledgertesting.RandomAddress(), + AccountData: basics.AccountData{ + MicroAlgos: basics.MicroAlgos{Raw: uint64(stake)}, + Status: basics.Online, + VoteLastValid: 10000, + VoteFirstValid: 0, + RewardsBase: 0}, + } + genesisAccts[0][allAccts[i].Addr] = allAccts[i].AccountData + totalStake = algops.Add(totalStake, allAccts[i].MicroAlgos) + } + + addSinkAndPoolAccounts(genesisAccts) + + proto := protocol.ConsensusFuture + params := config.Consensus[proto] + ml := makeMockLedgerForTracker(t, true, 1, proto, genesisAccts) + defer ml.Close() + + conf := config.GetDefaultLocal() + conf.MaxAcctLookback = 4 // technically the test work for any value of MaxAcctLookback but takes too long + // t.Logf("Running MaxAcctLookback=%d", conf.MaxAcctLookback) + au, oa := newAcctUpdates(t, ml, conf) + defer oa.close() + + // close commitSyncer goroutine to prevent possible race between commitSyncer and commitSync + ml.trackers.ctxCancel() + ml.trackers.ctxCancel = nil + <-ml.trackers.commitSyncerClosed + ml.trackers.commitSyncerClosed = nil + + // initial precondition checks on online stake + _, totals, err := au.LatestTotals() + a.NoError(err) + a.Equal(totalStake, totals.Online.Money) + initialOnlineStake, err := oa.onlineCirculation(0, basics.Round(oa.maxBalLookback())) + a.NoError(err) + a.Equal(totalStake, initialOnlineStake) + initialExpired, err := oa.ExpiredOnlineCirculation(0, 1000) + a.NoError(err) + a.Equal(basics.MicroAlgos{Raw: 0}, initialExpired) + + type dbState uint64 + const ( + dbOffline dbState = iota + dbOnline + dbOnlineExpired + ) + + type deltaState uint64 + const ( + deltaNoChange deltaState = iota + deltaOffpired // offline (addrA) or expired (addrB) + deltaOnline + ) + + type acctState uint64 + const ( + acctStateUnknown acctState = iota + acctStateOffline + acctStateOnline + acctStateExpired + ) + + // take two first accounts for the test - 0 and 1 - with stake 1 and 10 correspondingly + addrA := allAccts[0].Addr + stakeA := allAccts[0].MicroAlgos + statesA := map[acctState]ledgercore.AccountData{ + acctStateOffline: {AccountBaseData: ledgercore.AccountBaseData{Status: basics.Offline, MicroAlgos: stakeA}, VotingData: ledgercore.VotingData{}}, + acctStateOnline: {AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online, MicroAlgos: stakeA}, VotingData: ledgercore.VotingData(allAccts[0].OnlineAccountData().VotingData)}, + } + + addrB := allAccts[1].Addr + stakeB := allAccts[1].MicroAlgos + votingDataB := allAccts[1].OnlineAccountData().VotingData + statesB := map[acctState]ledgercore.AccountData{ + acctStateOffline: {AccountBaseData: ledgercore.AccountBaseData{Status: basics.Offline, MicroAlgos: stakeB}, VotingData: ledgercore.VotingData{}}, + acctStateOnline: {AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online, MicroAlgos: stakeB}, VotingData: ledgercore.VotingData(votingDataB)}, + } + expStatesB := func(state acctState, voteRnd basics.Round) ledgercore.AccountData { + vd := ledgercore.VotingData(votingDataB) + switch state { + case acctStateExpired: + vd.VoteLastValid = voteRnd - 1 + case acctStateOnline: + vd.VoteLastValid = voteRnd + 1 + default: + a.Fail("invalid acct state") + } + return ledgercore.AccountData{ + AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online, MicroAlgos: stakeB}, + VotingData: vd, + } + } + + // try all possible online/offline delta states for account A + // try all possible valid/expired VoteLastValid for account B + // - generate {offline, online, online-expired} db states (two rounds committed) for account A and B + // - generate all combinations of deltaState {not changed, offline/expired, online} of size conf.MaxAcctLookback arrays + // - test all combinations in 3^2 * 3^conf.MaxAcctLookback tests + rnd := basics.Round(1) + accounts := []map[basics.Address]basics.AccountData{genesisAccts[0]} // base state + dbStates := []dbState{dbOffline, dbOnline, dbOnlineExpired} + deltaStates := []deltaState{deltaNoChange, deltaOffpired, deltaOnline} + const dbRoundsToCommit = 2 + for dbCombo := uint64(0); dbCombo < powInt(uint64(len(dbStates)), dbRoundsToCommit); dbCombo++ { + for deltaCombo := uint64(0); deltaCombo < powInt(uint64(len(deltaStates)), conf.MaxAcctLookback); deltaCombo++ { + var stateA acctState + var stateB acctState + + ternDb := strconv.FormatUint(dbCombo, 3) + ternDb = fmt.Sprintf("%0*s", dbRoundsToCommit, ternDb) + + ternDelta := strconv.FormatUint(deltaCombo, 3) + ternDelta = fmt.Sprintf("%0*s", conf.MaxAcctLookback, ternDelta) + // uncomment for debugging + // t.Logf("db=%d|delta=%d <==> older->%s<-db top | first->%s<-last", dbCombo, deltaCombo, ternDb, ternDelta) + + targetVoteRnd := rnd + + basics.Round(conf.MaxAcctLookback) /* all deltas */ + + 2 /* db state committed */ + + basics.Round(params.MaxBalLookback) + + // mutate the committed state + // addrA, addrB: offline, online not expired, online expired + dbSeed := dbState(9999) // not initialized + for i := uint64(0); i < dbRoundsToCommit; i++ { + combo := ternDb[i] + d, err := strconv.Atoi(string(combo)) + a.NoError(err) + if i == dbRoundsToCommit-1 { + dbSeed = dbState(d) + } + + var updates ledgercore.AccountDeltas + switch dbState(d) { + case dbOffline: + updates.Upsert(addrA, statesA[acctStateOffline]) + updates.Upsert(addrB, statesB[acctStateOffline]) + case dbOnline: + updates.Upsert(addrA, statesA[acctStateOnline]) + updates.Upsert(addrB, statesB[acctStateOnline]) + case dbOnlineExpired: + state := statesA[acctStateOnline] + state.VoteLastValid = targetVoteRnd - 1 + updates.Upsert(addrA, state) + state = statesB[acctStateOnline] + state.VoteLastValid = targetVoteRnd - 1 + updates.Upsert(addrB, state) + default: + a.Fail("unknown db state") + } + base := accounts[rnd-1] + accounts = append(accounts, applyPartialDeltas(base, updates)) + totals = newBlock(t, ml, proto, params, rnd, base, updates, totals) + rnd++ + } + + // assert on expected online totals + switch dbSeed { + case dbOffline: + // both accounts are offline, decrease the original stake + a.Equal(initialOnlineStake.Raw-(stakeA.Raw+stakeB.Raw), totals.Online.Money.Raw) + case dbOnline, dbOnlineExpired: // being expired does not decrease the stake + a.Equal(initialOnlineStake, totals.Online.Money) + } + + // mutate in-memory state + for i := uint64(0); i < conf.MaxAcctLookback; i++ { + combo := ternDelta[i] + d, err := strconv.Atoi(string(combo)) + a.NoError(err) + + var updates ledgercore.AccountDeltas + switch deltaState(d) { + case deltaNoChange: + case deltaOffpired: + updates.Upsert(addrA, statesA[acctStateOffline]) + updates.Upsert(addrB, expStatesB(acctStateExpired, targetVoteRnd)) + stateA = acctStateOffline + stateB = acctStateExpired + case deltaOnline: + updates.Upsert(addrA, statesA[acctStateOnline]) + updates.Upsert(addrB, expStatesB(acctStateOnline, targetVoteRnd)) + stateA = acctStateOnline + stateB = acctStateOnline + + default: + a.Fail("unknown delta seed") + } + base := accounts[rnd-1] + accounts = append(accounts, applyPartialDeltas(base, updates)) + totals = newBlock(t, ml, proto, params, rnd, base, updates, totals) + rnd++ + } + + commitSync(t, oa, ml, basics.Round(rnd-1)) + a.Equal(int(conf.MaxAcctLookback), len(oa.deltas)) // ensure the only expected deltas are not flushed + + var expiredAccts map[basics.Address]*ledgercore.OnlineAccountData + err = ml.trackers.dbs.Snapshot(func(ctx context.Context, tx trackerdb.SnapshotScope) error { + reader, err := tx.MakeAccountsReader() + if err != nil { + return err + } + expiredAccts, err = reader.ExpiredOnlineAccountsForRound(rnd-1, targetVoteRnd, params, 0) + if err != nil { + return err + } + return nil + }) + a.NoError(err) + + if dbSeed == dbOffline || dbSeed == dbOnline { + a.Empty(expiredAccts) + } else { + a.Len(expiredAccts, 2) + for _, acct := range expiredAccts { + a.NotZero(acct.VoteLastValid) + } + } + + expectedExpiredStake := basics.MicroAlgos{} + // if both A and B were offline or online in DB then the expired stake is changed only if account is expired in deltas + // => check if B expired + // if both A and B were expired in DB then the expired stake is changed when any of them goes offline or online + // => check if A or B are offline or online + switch dbSeed { + case dbOffline, dbOnline: + if stateB == acctStateExpired { + expectedExpiredStake.Raw += stakeB.Raw + } + case dbOnlineExpired: + expectedExpiredStake.Raw += stakeA.Raw + expectedExpiredStake.Raw += stakeB.Raw + if stateA == acctStateOnline || stateA == acctStateOffline { + expectedExpiredStake.Raw -= stakeA.Raw + } + if stateB == acctStateOnline || stateB == acctStateOffline { + expectedExpiredStake.Raw -= stakeB.Raw + } + default: + a.Fail("unknown db seed") + } + a.Equal(targetVoteRnd, rnd+basics.Round(params.MaxBalLookback)) + _, err := oa.ExpiredOnlineCirculation(rnd, targetVoteRnd) + a.Error(err) + a.Contains(err.Error(), fmt.Sprintf("round %d too high", rnd)) + expiredStake, err := oa.ExpiredOnlineCirculation(rnd-1, targetVoteRnd) + a.NoError(err) + a.Equal(expectedExpiredStake, expiredStake) + + // restore the original state of accounts A and B + updates := ledgercore.AccountDeltas{} + base := accounts[rnd-1] + updates.Upsert(addrA, statesA[acctStateOnline]) + updates.Upsert(addrB, ledgercore.AccountData{ + AccountBaseData: ledgercore.AccountBaseData{Status: basics.Online, MicroAlgos: stakeB}, VotingData: ledgercore.VotingData(votingDataB), + }) + accounts = append(accounts, applyPartialDeltas(base, updates)) + totals = newBlock(t, ml, proto, params, rnd, base, updates, totals) + rnd++ + // add conf.MaxAcctLookback empty blocks to flush/restore the original state + for i := uint64(0); i < conf.MaxAcctLookback; i++ { + var updates ledgercore.AccountDeltas + base = accounts[rnd-1] + accounts = append(accounts, base) + totals = newBlock(t, ml, proto, params, rnd, base, updates, totals) + rnd++ + } + commitSync(t, oa, ml, basics.Round(rnd-1)) + a.Equal(int(conf.MaxAcctLookback), len(oa.deltas)) + } + } +} diff --git a/ledger/acctupdates.go b/ledger/acctupdates.go index 4e934bbf55..369f7db147 100644 --- a/ledger/acctupdates.go +++ b/ledger/acctupdates.go @@ -906,20 +906,6 @@ func (aul *accountUpdatesLedgerEvaluator) GetCreatorForRound(rnd basics.Round, c return aul.au.getCreatorForRound(rnd, cidx, ctype, false /* don't sync */) } -// onlineTotals returns the online totals of all accounts at the end of round rnd. -// used in tests only -func (au *accountUpdates) onlineTotals(rnd basics.Round) (basics.MicroAlgos, error) { - au.accountsMu.RLock() - defer au.accountsMu.RUnlock() - offset, err := au.roundOffset(rnd) - if err != nil { - return basics.MicroAlgos{}, err - } - - totals := au.roundTotals[offset] - return totals.Online.Money, nil -} - // latestTotalsImpl returns the totals of all accounts for the most recent round, as well as the round number func (au *accountUpdates) latestTotalsImpl() (basics.Round, ledgercore.AccountTotals, error) { offset := len(au.deltas) diff --git a/ledger/acctupdates_test.go b/ledger/acctupdates_test.go index 9049447775..0faaa4de69 100644 --- a/ledger/acctupdates_test.go +++ b/ledger/acctupdates_test.go @@ -21,8 +21,6 @@ import ( "context" "errors" "fmt" - "github.com/algorand/go-algorand/ledger/eval" - "github.com/algorand/go-deadlock" "os" "runtime" "strings" @@ -37,6 +35,7 @@ import ( "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/data/basics" "github.com/algorand/go-algorand/data/bookkeeping" + "github.com/algorand/go-algorand/ledger/eval" "github.com/algorand/go-algorand/ledger/ledgercore" "github.com/algorand/go-algorand/ledger/store/trackerdb" "github.com/algorand/go-algorand/ledger/store/trackerdb/sqlitedriver" @@ -45,6 +44,7 @@ import ( "github.com/algorand/go-algorand/protocol" "github.com/algorand/go-algorand/test/partitiontest" "github.com/algorand/go-algorand/util/db" + "github.com/algorand/go-deadlock" ) var testPoolAddr = basics.Address{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} @@ -67,6 +67,20 @@ type mockLedgerForTracker struct { trackers trackerRegistry } +// onlineTotals returns the online totals of all accounts at the end of round rnd. +// used in tests only +func (au *accountUpdates) onlineTotals(rnd basics.Round) (basics.MicroAlgos, error) { + au.accountsMu.RLock() + defer au.accountsMu.RUnlock() + offset, err := au.roundOffset(rnd) + if err != nil { + return basics.MicroAlgos{}, err + } + + totals := au.roundTotals[offset] + return totals.Online.Money, nil +} + func accumulateTotals(t testing.TB, consensusVersion protocol.ConsensusVersion, accts []map[basics.Address]ledgercore.AccountData, rewardLevel uint64) (totals ledgercore.AccountTotals) { var ot basics.OverflowTracker proto := config.Consensus[consensusVersion] @@ -325,7 +339,7 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base require.Equal(t, latestRnd, latest) // the log has "onlineAccounts failed to fetch online totals for rnd" warning that is expected - _, err := ao.onlineTotals(latest + 1) + _, err := ao.onlineCirculation(latest+1, latest+1+basics.Round(ao.maxBalLookback())) require.Error(t, err) var validThrough basics.Round @@ -334,7 +348,8 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base require.Equal(t, basics.Round(0), validThrough) if base > 0 && base >= basics.Round(ao.maxBalLookback()) { - _, err := ao.onlineTotals(base - basics.Round(ao.maxBalLookback())) + rnd := base - basics.Round(ao.maxBalLookback()) + _, err := ao.onlineCirculation(rnd, base) require.Error(t, err) _, validThrough, err = au.LookupWithoutRewards(base-1, ledgertesting.RandomAddress()) @@ -397,7 +412,7 @@ func checkAcctUpdates(t *testing.T, au *accountUpdates, ao *onlineAccounts, base bll := accts[rnd] require.Equal(t, all, bll) - totals, err := ao.onlineTotals(rnd) + totals, err := ao.onlineCirculation(rnd, rnd+basics.Round(ao.maxBalLookback())) require.NoError(t, err) require.Equal(t, totals.Raw, totalOnline) diff --git a/ledger/catchpointtracker_test.go b/ledger/catchpointtracker_test.go index a9d4eff35b..dcf6c68c64 100644 --- a/ledger/catchpointtracker_test.go +++ b/ledger/catchpointtracker_test.go @@ -1756,6 +1756,7 @@ func TestCatchpointFastUpdates(t *testing.T) { delta := ledgercore.MakeStateDelta(&blk.BlockHeader, 0, updates.Len(), 0) delta.Accts.MergeAccounts(updates) + delta.Totals = accumulateTotals(t, protocol.ConsensusCurrentVersion, []map[basics.Address]ledgercore.AccountData{totals}, rewardLevel) ml.addBlock(blockEntry{block: blk}, delta) accts = append(accts, newAccts) rewardsLevels = append(rewardsLevels, rewardLevel) diff --git a/ledger/double_test.go b/ledger/double_test.go index 1a894e6719..1c53e54b09 100644 --- a/ledger/double_test.go +++ b/ledger/double_test.go @@ -42,7 +42,7 @@ import ( // then temporarily placed in `generate` mode so that the entire block can be // generated in the copy second ledger, and compared. type DoubleLedger struct { - t *testing.T + t testing.TB generator *Ledger validator *Ledger @@ -56,9 +56,9 @@ func (dl DoubleLedger) Close() { } // NewDoubleLedger creates a new DoubleLedger with the supplied balances and consensus version. -func NewDoubleLedger(t *testing.T, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local) DoubleLedger { - g := newSimpleLedgerWithConsensusVersion(t, balances, cv, cfg) - v := newSimpleLedgerFull(t, balances, cv, g.GenesisHash(), cfg) +func NewDoubleLedger(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local, opts ...simpleLedgerOption) DoubleLedger { + g := newSimpleLedgerWithConsensusVersion(t, balances, cv, cfg, opts...) + v := newSimpleLedgerFull(t, balances, cv, g.GenesisHash(), cfg, opts...) return DoubleLedger{t, g, v, nil} } @@ -165,7 +165,7 @@ func (dl *DoubleLedger) reloadLedgers() { require.NoError(dl.t, dl.validator.reloadLedger()) } -func checkBlock(t *testing.T, checkLedger *Ledger, vb *ledgercore.ValidatedBlock) { +func checkBlock(t testing.TB, checkLedger *Ledger, vb *ledgercore.ValidatedBlock) { bl := vb.Block() msg := bl.MarshalMsg(nil) var reconstituted bookkeeping.Block diff --git a/ledger/ledger.go b/ledger/ledger.go index b29ec61a5a..65c7964e47 100644 --- a/ledger/ledger.go +++ b/ledger/ledger.go @@ -630,11 +630,12 @@ func (l *Ledger) LatestTotals() (basics.Round, ledgercore.AccountTotals, error) return l.accts.LatestTotals() } -// OnlineTotals returns the online totals of all accounts at the end of round rnd. -func (l *Ledger) OnlineTotals(rnd basics.Round) (basics.MicroAlgos, error) { +// OnlineCirculation returns the online totals of all accounts at the end of round rnd. +// It implements agreement's calls for Circulation(rnd) +func (l *Ledger) OnlineCirculation(rnd basics.Round, voteRnd basics.Round) (basics.MicroAlgos, error) { l.trackerMu.RLock() defer l.trackerMu.RUnlock() - return l.acctsOnline.onlineTotals(rnd) + return l.acctsOnline.onlineCirculation(rnd, voteRnd) } // CheckDup return whether a transaction is a duplicate one. diff --git a/ledger/ledger_test.go b/ledger/ledger_test.go index 9e89e82ce9..5b7ceb33c1 100644 --- a/ledger/ledger_test.go +++ b/ledger/ledger_test.go @@ -21,7 +21,6 @@ import ( "context" "errors" "fmt" - "github.com/algorand/go-algorand/ledger/eval" "math/rand" "os" "path/filepath" @@ -42,6 +41,7 @@ import ( "github.com/algorand/go-algorand/data/transactions" "github.com/algorand/go-algorand/data/transactions/logic" "github.com/algorand/go-algorand/data/transactions/verify" + "github.com/algorand/go-algorand/ledger/eval" "github.com/algorand/go-algorand/ledger/ledgercore" "github.com/algorand/go-algorand/ledger/store/trackerdb" ledgertesting "github.com/algorand/go-algorand/ledger/testing" @@ -2205,10 +2205,11 @@ func TestLedgerReloadShrinkDeltas(t *testing.T) { l.cfg = cfg l.reloadLedger() - _, err = l.OnlineTotals(basics.Round(proto.MaxBalLookback - shorterLookback)) + rnd := basics.Round(proto.MaxBalLookback - shorterLookback) + _, err = l.OnlineCirculation(rnd, rnd+basics.Round(proto.MaxBalLookback)) require.Error(t, err) for i := basics.Round(proto.MaxBalLookback - shorterLookback + 1); i <= l.Latest(); i++ { - online, err := l.OnlineTotals(i) + online, err := l.OnlineCirculation(i, i+basics.Round(proto.MaxBalLookback)) require.NoError(t, err) require.Equal(t, onlineTotals[i], online) } @@ -2631,10 +2632,11 @@ func TestLedgerMigrateV6ShrinkDeltas(t *testing.T) { l2.Close() }() - _, err = l2.OnlineTotals(basics.Round(proto.MaxBalLookback - shorterLookback)) + rnd := basics.Round(proto.MaxBalLookback - shorterLookback) + _, err = l2.OnlineCirculation(rnd, rnd+basics.Round(proto.MaxBalLookback)) require.Error(t, err) for i := l2.Latest() - basics.Round(proto.MaxBalLookback-1); i <= l2.Latest(); i++ { - online, err := l2.OnlineTotals(i) + online, err := l2.OnlineCirculation(i, i+basics.Round(proto.MaxBalLookback)) require.NoError(t, err) require.Equal(t, onlineTotals[i], online) } diff --git a/ledger/simple_test.go b/ledger/simple_test.go index 31601bd25c..1f4c612902 100644 --- a/ledger/simple_test.go +++ b/ledger/simple_test.go @@ -35,20 +35,40 @@ import ( "github.com/stretchr/testify/require" ) -func newSimpleLedgerWithConsensusVersion(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local) *Ledger { +type simpleLedgerCfg struct { + onDisk bool // default is in-memory + notArchival bool // default is archival +} + +type simpleLedgerOption func(*simpleLedgerCfg) + +func simpleLedgerOnDisk() simpleLedgerOption { + return func(cfg *simpleLedgerCfg) { cfg.onDisk = true } +} + +func simpleLedgerNotArchival() simpleLedgerOption { + return func(cfg *simpleLedgerCfg) { cfg.notArchival = true } +} + +func newSimpleLedgerWithConsensusVersion(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, cfg config.Local, opts ...simpleLedgerOption) *Ledger { var genHash crypto.Digest crypto.RandBytes(genHash[:]) - return newSimpleLedgerFull(t, balances, cv, genHash, cfg) + return newSimpleLedgerFull(t, balances, cv, genHash, cfg, opts...) } -func newSimpleLedgerFull(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, genHash crypto.Digest, cfg config.Local) *Ledger { +func newSimpleLedgerFull(t testing.TB, balances bookkeeping.GenesisBalances, cv protocol.ConsensusVersion, genHash crypto.Digest, cfg config.Local, opts ...simpleLedgerOption) *Ledger { + var slCfg simpleLedgerCfg + for _, opt := range opts { + opt(&slCfg) + } genBlock, err := bookkeeping.MakeGenesisBlock(cv, balances, "test", genHash) require.NoError(t, err) require.False(t, genBlock.FeeSink.IsZero()) require.False(t, genBlock.RewardsPool.IsZero()) dbName := fmt.Sprintf("%s.%d", t.Name(), crypto.RandUint64()) - cfg.Archival = true - l, err := OpenLedger(logging.Base(), dbName, true, ledgercore.InitState{ + dbName = strings.Replace(dbName, "/", "_", -1) + cfg.Archival = !slCfg.notArchival + l, err := OpenLedger(logging.Base(), dbName, !slCfg.onDisk, ledgercore.InitState{ Block: genBlock, Accounts: balances.Balances, GenesisHash: genHash, diff --git a/ledger/simulation/simulation_eval_test.go b/ledger/simulation/simulation_eval_test.go index 115f52d5d6..ee5c800f39 100644 --- a/ledger/simulation/simulation_eval_test.go +++ b/ledger/simulation/simulation_eval_test.go @@ -867,7 +867,7 @@ func TestAppCallWithExtraBudget(t *testing.T) { Sender: sender.Addr, ApplicationID: 0, ApprovalProgram: expensiveAppSource, - ClearStateProgram: `#pragma version 6; int 0`, + ClearStateProgram: "#pragma version 6\nint 0", }) // Expensive 700 repetition of int 1 and pop total cost 1404 expensiveTxn := env.TxnInfo.NewTxn(txntest.Txn{ @@ -938,7 +938,7 @@ func TestAppCallWithExtraBudgetOverBudget(t *testing.T) { Sender: sender.Addr, ApplicationID: 0, ApprovalProgram: expensiveAppSource, - ClearStateProgram: `#pragma version 6; int 0`, + ClearStateProgram: "#pragma version 6\nint 0", }) // Expensive 700 repetition of int 1 and pop total cost 1404 expensiveTxn := env.TxnInfo.NewTxn(txntest.Txn{ @@ -1015,7 +1015,7 @@ func TestAppCallWithExtraBudgetExceedsInternalLimit(t *testing.T) { Sender: sender.Addr, ApplicationID: 0, ApprovalProgram: expensiveAppSource, - ClearStateProgram: `#pragma version 6; int 0`, + ClearStateProgram: "#pragma version 6\nint 0", }) // Expensive 700 repetition of int 1 and pop total cost 1404 expensiveTxn := env.TxnInfo.NewTxn(txntest.Txn{ diff --git a/ledger/store/trackerdb/interface.go b/ledger/store/trackerdb/interface.go index f65dc8695e..9e9fbb1a10 100644 --- a/ledger/store/trackerdb/interface.go +++ b/ledger/store/trackerdb/interface.go @@ -113,6 +113,7 @@ type AccountsReaderExt interface { LookupOnlineAccountDataByAddress(addr basics.Address) (ref OnlineAccountRef, data []byte, err error) AccountsOnlineTop(rnd basics.Round, offset uint64, n uint64, proto config.ConsensusParams) (map[basics.Address]*ledgercore.OnlineAccount, error) AccountsOnlineRoundParams() (onlineRoundParamsData []ledgercore.OnlineRoundParamsData, endRound basics.Round, err error) + ExpiredOnlineAccountsForRound(rnd, voteRnd basics.Round, proto config.ConsensusParams, rewardsLevel uint64) (map[basics.Address]*ledgercore.OnlineAccountData, error) OnlineAccountsAll(maxAccounts uint64) ([]PersistedOnlineAccountData, error) LoadTxTail(ctx context.Context, dbRound basics.Round) (roundData []*TxTailRound, roundHash []crypto.Digest, baseRound basics.Round, err error) LoadAllFullAccounts(ctx context.Context, balancesTable string, resourcesTable string, acctCb func(basics.Address, basics.AccountData)) (count int, err error) diff --git a/ledger/store/trackerdb/sqlitedriver/accountsV2.go b/ledger/store/trackerdb/sqlitedriver/accountsV2.go index 3ffb069999..d6e7330903 100644 --- a/ledger/store/trackerdb/sqlitedriver/accountsV2.go +++ b/ledger/store/trackerdb/sqlitedriver/accountsV2.go @@ -297,6 +297,50 @@ func (r *accountsV2Reader) OnlineAccountsAll(maxAccounts uint64) ([]trackerdb.Pe return result, nil } +// ExpiredOnlineAccountsForRound returns all online accounts known at `rnd` that will be expired by `voteRnd`. +func (r *accountsV2Reader) ExpiredOnlineAccountsForRound(rnd, voteRnd basics.Round, proto config.ConsensusParams, rewardsLevel uint64) (map[basics.Address]*ledgercore.OnlineAccountData, error) { + // This relies on SQLite's handling of max(updround) and bare columns not in the GROUP BY. + // The values of votelastvalid, votefirstvalid, and data will all be from the same row as max(updround) + rows, err := r.q.Query(`SELECT address, data, max(updround) +FROM onlineaccounts +WHERE updround <= ? +GROUP BY address +HAVING votelastvalid < ? and votelastvalid > 0 +ORDER BY address`, rnd, voteRnd) + if err != nil { + return nil, err + } + defer rows.Close() + + ret := make(map[basics.Address]*ledgercore.OnlineAccountData) + for rows.Next() { + var addrbuf []byte + var buf []byte + var addr basics.Address + var baseData trackerdb.BaseOnlineAccountData + var updround sql.NullInt64 + err := rows.Scan(&addrbuf, &buf, &updround) + if err != nil { + return nil, err + } + if len(addrbuf) != len(addr) { + err = fmt.Errorf("account DB address length mismatch: %d != %d", len(addrbuf), len(addr)) + return nil, err + } + copy(addr[:], addrbuf) + err = protocol.Decode(buf, &baseData) + if err != nil { + return nil, err + } + oadata := baseData.GetOnlineAccountData(proto, rewardsLevel) + if _, ok := ret[addr]; ok { + return nil, fmt.Errorf("duplicate address in expired online accounts: %s", addr.String()) + } + ret[addr] = &oadata + } + return ret, nil +} + // TotalResources returns the total number of resources func (r *accountsV2Reader) TotalResources(ctx context.Context) (total uint64, err error) { err = r.q.QueryRowContext(ctx, "SELECT count(1) FROM resources").Scan(&total) diff --git a/ledger/store/trackerdb/sqlitedriver/schema.go b/ledger/store/trackerdb/sqlitedriver/schema.go index e99e9c68e2..47cb0180df 100644 --- a/ledger/store/trackerdb/sqlitedriver/schema.go +++ b/ledger/store/trackerdb/sqlitedriver/schema.go @@ -154,6 +154,10 @@ const createStateProofVerificationTableQuery = ` lastattestedround integer primary key NOT NULL, verificationcontext blob NOT NULL)` +const createVoteLastValidIndex = ` + CREATE INDEX IF NOT EXISTS onlineaccounts_votelastvalid_idx + ON onlineaccounts ( votelastvalid )` + var accountsResetExprs = []string{ `DROP TABLE IF EXISTS acctrounds`, `DROP TABLE IF EXISTS accounttotals`, @@ -927,3 +931,9 @@ func reencodeAccounts(ctx context.Context, tx *sql.Tx) (modifiedAccounts uint, e updateStmt.Close() return } + +func convertOnlineRoundParamsTail(ctx context.Context, tx *sql.Tx) error { + // create vote last index + _, err := tx.ExecContext(ctx, createVoteLastValidIndex) + return err +} diff --git a/ledger/store/trackerdb/sqlitedriver/trackerdbV2.go b/ledger/store/trackerdb/sqlitedriver/trackerdbV2.go index 1940e54a21..2c7a370f02 100644 --- a/ledger/store/trackerdb/sqlitedriver/trackerdbV2.go +++ b/ledger/store/trackerdb/sqlitedriver/trackerdbV2.go @@ -499,6 +499,11 @@ func (tu *trackerDBSchemaInitializer) upgradeDatabaseSchema9(ctx context.Context return fmt.Errorf("upgradeDatabaseSchema9 unable to replace kvstore nil entries with empty byte slices : %v", err) } + err = convertOnlineRoundParamsTail(ctx, tx) + if err != nil { + return fmt.Errorf("upgradeDatabaseSchema10 unable to convert onlineroundparamstail: %v", err) + } + // update version return tu.setVersion(ctx, tx, 10) } diff --git a/ledger/testing/testGenesis.go b/ledger/testing/testGenesis.go index 80d752c759..98a41d06d5 100644 --- a/ledger/testing/testGenesis.go +++ b/ledger/testing/testGenesis.go @@ -25,11 +25,29 @@ import ( "github.com/algorand/go-algorand/protocol" ) +// testGenesisCfg provides a configuration object for NewTestGenesis. +type testGenesisCfg struct { + rewardsPoolAmount basics.MicroAlgos +} + +// TestGenesisOption provides functional options for testGenesisCfg. +type TestGenesisOption func(*testGenesisCfg) + +// TestGenesisRewardsPoolSize configures the rewards pool size in the genesis block. +func TestGenesisRewardsPoolSize(amount basics.MicroAlgos) TestGenesisOption { + return func(cfg *testGenesisCfg) { cfg.rewardsPoolAmount = amount } +} + // NewTestGenesis creates a bunch of accounts, splits up 10B algos // between them and the rewardspool and feesink, and gives out the // addresses and secrets it creates to enable tests. For special // scenarios, manipulate these return values before using newTestLedger. -func NewTestGenesis() (bookkeeping.GenesisBalances, []basics.Address, []*crypto.SignatureSecrets) { +func NewTestGenesis(opts ...TestGenesisOption) (bookkeeping.GenesisBalances, []basics.Address, []*crypto.SignatureSecrets) { + var cfg testGenesisCfg + for _, opt := range opts { + opt(&cfg) + } + // irrelevant, but deterministic sink, err := basics.UnmarshalChecksumAddress("YTPRLJ2KK2JRFSZZNAF57F3K5Y2KCG36FZ5OSYLW776JJGAUW5JXJBBD7Q") if err != nil { @@ -66,8 +84,12 @@ func NewTestGenesis() (bookkeeping.GenesisBalances, []basics.Address, []*crypto. Status: basics.NotParticipating, } + poolBal := basics.MicroAlgos{Raw: amount} + if cfg.rewardsPoolAmount.Raw > 0 { + poolBal = cfg.rewardsPoolAmount + } accts[rewards] = basics.AccountData{ - MicroAlgos: basics.MicroAlgos{Raw: amount}, + MicroAlgos: poolBal, } genBalances := bookkeeping.MakeGenesisBalances(accts, sink, rewards) diff --git a/netdeploy/remote/deployedNetwork.go b/netdeploy/remote/deployedNetwork.go index a6b7be3f77..4bf3955142 100644 --- a/netdeploy/remote/deployedNetwork.go +++ b/netdeploy/remote/deployedNetwork.go @@ -757,7 +757,7 @@ func createSignedTx(src basics.Address, round basics.Round, params config.Consen return []transactions.SignedTxn{}, err } approval := ops.Program - ops, err = logic.AssembleString("#pragma version 2 int 1") + ops, err = logic.AssembleString("#pragma version 2\nint 1") if err != nil { panic(err) } diff --git a/netdeploy/remote/nodecfg/nodeConfigurator.go b/netdeploy/remote/nodecfg/nodeConfigurator.go index 4621373b25..c398e8c448 100644 --- a/netdeploy/remote/nodecfg/nodeConfigurator.go +++ b/netdeploy/remote/nodecfg/nodeConfigurator.go @@ -39,6 +39,7 @@ type nodeConfigurator struct { genesisData bookkeeping.Genesis bootstrappedBlockFile string bootstrappedTrackerFile string + bootstrappedTrackerDir string relayEndpoints []srvEntry metricsEndpoints []srvEntry } @@ -78,6 +79,12 @@ func (nc *nodeConfigurator) apply(rootConfigDir, rootNodeDir string) (err error) nc.bootstrappedTrackerFile = trackerFile } + trackerDir := filepath.Join(rootConfigDir, "genesisdata", "bootstrapped") + trackerDirExists := util.FileExists(trackerDir) + if trackerDirExists { + nc.bootstrappedTrackerDir = trackerDir + } + nc.genesisFile = filepath.Join(rootConfigDir, "genesisdata", config.GenesisJSONFile) nc.genesisData, err = bookkeeping.LoadGenesisFromFile(nc.genesisFile) nodeDirs, err := nc.prepareNodeDirs(nc.config.Nodes, rootConfigDir, rootNodeDir) @@ -150,20 +157,30 @@ func (nc *nodeConfigurator) prepareNodeDirs(configs []remote.NodeConfig, rootCon } // Copy the bootstrapped files into current ledger folder - if nc.bootstrappedBlockFile != "" && nc.bootstrappedTrackerFile != "" { + if nc.bootstrappedBlockFile != "" && + (nc.bootstrappedTrackerFile != "" || nc.bootstrappedTrackerDir != "") { fmt.Fprintf(os.Stdout, "... copying block database file to ledger folder ...\n") dest := filepath.Join(nodeDest, genesisDir, fmt.Sprintf("%s.block.sqlite", config.LedgerFilenamePrefix)) _, err = util.CopyFile(nc.bootstrappedBlockFile, dest) if err != nil { return nil, fmt.Errorf("failed to copy database file %s from %s to %s : %w", "bootstrapped.block.sqlite", filepath.Dir(nc.bootstrappedBlockFile), dest, err) } - fmt.Fprintf(os.Stdout, "... copying tracker database file to ledger folder ...\n") - dest = filepath.Join(nodeDest, genesisDir, fmt.Sprintf("%s.tracker.sqlite", config.LedgerFilenamePrefix)) - _, err = util.CopyFile(nc.bootstrappedTrackerFile, dest) - if err != nil { - return nil, fmt.Errorf("failed to copy database file %s from %s to %s : %w", "bootstrapped.tracker.sqlite", filepath.Dir(nc.bootstrappedBlockFile), dest, err) + if nc.bootstrappedTrackerFile != "" { + fmt.Fprintf(os.Stdout, "... copying tracker database file to ledger folder ...\n") + dest = filepath.Join(nodeDest, genesisDir, fmt.Sprintf("%s.tracker.sqlite", config.LedgerFilenamePrefix)) + _, err = util.CopyFile(nc.bootstrappedTrackerFile, dest) + if err != nil { + return nil, fmt.Errorf("failed to copy database file %s from %s to %s : %w", filepath.Base(nc.bootstrappedBlockFile), filepath.Dir(nc.bootstrappedBlockFile), dest, err) + } + } + if nc.bootstrappedTrackerDir != "" { + fmt.Fprintf(os.Stdout, "... copying tracker database directory to ledger folder ...\n") + dest = filepath.Join(nodeDest, genesisDir, config.LedgerFilenamePrefix) + err = util.CopyFolder(nc.bootstrappedTrackerDir, dest) + if err != nil { + return nil, fmt.Errorf("failed to copy database directory from %s to %s : %w", nc.bootstrappedTrackerDir, dest, err) + } } - } nodeDirs = append(nodeDirs, nodeDir{ diff --git a/scripts/get_golang_version.sh b/scripts/get_golang_version.sh index 4e3525a548..7036e716ae 100755 --- a/scripts/get_golang_version.sh +++ b/scripts/get_golang_version.sh @@ -4,7 +4,7 @@ # and parsed as an array to check against the system's golang version depending # upon the context in which the project is being built. # -# "dev" is to be used to satisfy the minium requirement we have to successfully +# "dev" is to be used to satisfy the minimum requirement we have to successfully # build the project. # # The default is to return the pinned version needed for our production builds. diff --git a/scripts/travis/codegen_verification.sh b/scripts/travis/codegen_verification.sh index 9ac11f1724..98efbe8777 100755 --- a/scripts/travis/codegen_verification.sh +++ b/scripts/travis/codegen_verification.sh @@ -61,5 +61,17 @@ else echo Enlistment is clean fi +echo Checking Tidiness... +make tidy +if [[ -n $(git status --porcelain) ]]; then + echo Dirty after go mod tidy - did you forget to run make tidy? + git status -s + git --no-pager diff + exit 1 +else + echo All tidy +fi + + # test binary compatibility "${SCRIPTPATH}/../../test/platform/test_linux_amd64_compatibility.sh" diff --git a/test/e2e-go/restAPI/restClient_test.go b/test/e2e-go/restAPI/restClient_test.go index 7dbc02e341..2ff0c08e52 100644 --- a/test/e2e-go/restAPI/restClient_test.go +++ b/test/e2e-go/restAPI/restClient_test.go @@ -1907,7 +1907,7 @@ int 1` ops, err := logic.AssembleString(prog) a.NoError(err) approval := ops.Program - ops, err = logic.AssembleString("#pragma version 8; int 1") + ops, err = logic.AssembleString("#pragma version 8\nint 1") a.NoError(err) clearState := ops.Program