Repository: algorand/indexer
Pull request #544 (2021-06-16 18:12:35)

Import performance test runner
<!--
Thanks for submitting a pull request! We appreciate the time and effort you spent to get this far.

If you haven't already, please make sure that you've reviewed the CONTRIBUTING guide:
https://github.com/algorand/go-algorand/blob/master/CONTRIBUTING.md#code-guidelines
-->

## Summary

Adds a new subcommand to the block generator to run multiple scenarios and generate reports based on the results.

For testing postgres can be started in a local docker container with:
```
~$ docker run -it --rm --name some-postgres -e POSTGRES_PASSWORD=algorand -e POSTGRES_USER=algorand -e PGPASSWORD=algorand -e POSTGRES_DB=algorand -p 5432:5432 postgres
```

With all binaries built, the new command can be used from the `cmd/block-generator` directory with the following command:
```
~$ ./block-generator runner \
            -d 5m \
            -i ./../algorand-indexer/algorand-indexer \
            -c "host=localhost user=algorand password=algorand dbname=algorand port=5432 sslmode=disable" \
            -r results \
            -s scenarios
```

## Test Plan

Run the command and verify no errors, and that reports are generated.
```
~$ go build && rm -rf results && ./block-generator runner -d 5m -i ./../algorand-indexer/algorand-indexer -c "host=localhost user=algorand password=algorand dbname=algorand port=5432 sslmode=disable" -r results -s scenarios
Running test for configuration 'scenarios/config.asset.close.yml'
Running test for configuration 'scenarios/config.asset.destroy.yml'
Running test for configuration 'scenarios/config.asset.xfer.yml'
Running test for configuration 'scenarios/config.mixed.jumbo.yml'
Running test for configuration 'scenarios/config.mixed.yml'
Running test for configuration 'scenarios/config.payment.full.yml'
Running test for configuration 'scenarios/config.payment.jumbo.yml'
Running test for configuration 'scenarios/config.payment.small.yml'

~$ cat results/config.payment.jumbo.report 
test_duration_seconds: 300
transaction_count_pay:1999323
transaction_count_pay_create:40575
starting_block_import_duration_average_seconds:2.111194
final_import_duration_average_second:2.692307

~$ cat results/config.mixed.jumbo.report 
test_duration_seconds: 300
transaction_count_pay:294032
transaction_count_pay_create:5989
transaction_count_asset_close:34964
transaction_count_asset_create:712
transaction_count_asset_optin:71071
transaction_count_asset_xfer:593182
starting_block_import_duration_average_seconds:4.945975
final_import_duration_average_second:5.672932
```

codecov-commenter: # [Codecov](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#544](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (1ee8603) into [develop](https://codecov.io/gh/algorand/indexer/commit/83fddb8a073af88bfb663d67a996ed1d658ee161?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (83fddb8) will **decrease** coverage by `0.04%`.
> The diff coverage is `5.55%`.

[![Impacted file tree graph](https://codecov.io/gh/algorand/indexer/pull/544/graphs/tree.svg?width=650&height=150&src=pr&token=BSHI3PT6QP&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

```diff
@@             Coverage Diff             @@
##           develop     #544      +/-   ##
===========================================
- Coverage    34.25%   34.20%   -0.05%     
===========================================
  Files           24       24              
  Lines         4837     4841       +4     
===========================================
- Hits          1657     1656       -1     
- Misses        2944     2949       +5     
  Partials       236      236              
```


| [Impacted Files](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [cmd/block-generator/generator/server.go](https://codecov.io/gh/algorand/indexer/pull/544/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y21kL2Jsb2NrLWdlbmVyYXRvci9nZW5lcmF0b3Ivc2VydmVyLmdv) | `39.21% <0.00%> (-4.27%)` | :arrow_down: |
| [cmd/block-generator/generator/generate.go](https://codecov.io/gh/algorand/indexer/pull/544/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y21kL2Jsb2NrLWdlbmVyYXRvci9nZW5lcmF0b3IvZ2VuZXJhdGUuZ28=) | `74.49% <33.33%> (-0.09%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Last update [83fddb8...1ee8603](https://codecov.io/gh/algorand/indexer/pull/544?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Patch:
diff --git a/.version b/.version
index 197c4d5..437459c 100644
--- a/.version
+++ b/.version
@@ -1,1 +1,1 @@
-2.4.0
+2.5.0
diff --git a/README.md b/README.md
index 0503805..c2642ce 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,16 @@
 [![Build Status](https://travis-ci.com/algorand/indexer.svg?branch=master)](https://travis-ci.com/algorand/indexer)
 # Algorand Indexer
 
-The Indexer is a standalone service reads committed blocks from the Algorand blockchain and maintains a database of transactions and accounts that are searchable and indexed.
+The Indexer is a standalone service that reads committed blocks from the Algorand blockchain and maintains a database of transactions and accounts that are searchable and indexed.
 
 # Minimum Version Requirements
 
-* go 1.13
-* Postgres 11
+* [go 1.13](https://golang.org/dl/)
+* [Postgres 11](https://www.postgresql.org/download/)
 
 # Quickstart
 
-We prepared a docker compose file to bring up indexer and postgres preloaded with some data. From the root directory run:
+We prepared a docker compose file to bring up indexer and Postgres preloaded with some data. From the root directory run:
 ```
 ~$ docker-compose up
 ```
@@ -52,7 +52,7 @@ Once running, here are a few commands to try out:
 
 There are a number of technical features as well:
 - Abstracted database layer. We want to support many different backend databases.
-- Optimized postgres DB backend.
+- Optimized Postgres DB backend.
 - User defined API token.
 
 # Contributing
@@ -63,18 +63,18 @@ Contributions welcome! Please refer to our [CONTRIBUTING](https://github.com/alg
 
 # Usage
 
-The most common usage of the Indexer is expect to be getting validated blocks from a local `algod` Algorand node, adding them to a [PostgreSQL](https://www.postgresql.org/) database, and serving an API to make available a variety of prepared queries. Some users may wish to directly write SQL queries of the database.
+The most common usage of the Indexer is expecting to be getting validated blocks from a local `algod` Algorand node, adding them to a [PostgreSQL](https://www.postgresql.org/) database, and serving an API to make available a variety of prepared queries. Some users may wish to directly write SQL queries of the database.
 
-Indexer works by fetching blocks one at a time, processing the block data, and loading it into a traditional database. There is a database abstraction layer to support different database implementations. In normal operation the service will run as a daemon and always requires access to a database.
+Indexer works by fetching blocks one at a time, processing the block data, and loading it into a traditional database. There is a database abstraction layer to support different database implementations. In normal operation, the service will run as a daemon and always requires access to a database.
 
 As of April 2020, storing all the raw blocks is about 100 GB and the PostgreSQL database of transactions and accounts is about 1 GB. Much of that size difference is the Indexer ignoring cryptographic signature data; relying on `algod` to validate blocks. Dropping that, the Indexer can focus on the 'what happened' details of transactions and accounts.
 
 There are two primary modes of operation:
-* Database updater
-* Read only
+* [Database updater](#database-updater)
+* [Read only](#read-only)
 
 ### Database updater
-In this mode the database will be populated with data fetched from an [Algorand archival node](https://developer.algorand.org/docs/run-a-node/setup/types/#archival-mode). Because every block must be fetched to bootstrap the database, the initial import for a ledger with a long history will take a while. If the daemon is terminated, it will resume processing wherever it left off.
+In this mode, the database will be populated with data fetched from an [Algorand archival node](https://developer.algorand.org/docs/run-a-node/setup/types/#archival-mode). Because every block must be fetched to bootstrap the database, the initial import for a ledger with a long history will take a while. If the daemon is terminated, it will resume processing wherever it left off.
 
 You should use a process manager, like systemd, to ensure the daemon is always running. Indexer will continue to update the database as new blocks are created.
 
@@ -110,7 +110,7 @@ When `--token your-token` is provided, an authentication header is required. For
 
 ## Metrics
 
-The `/metrics` endpoint is configured with the `--metrics-mode` option and configures if and how [prometheus](https://prometheus.io/) formatted metrics are generated.
+The `/metrics` endpoint is configured with the `--metrics-mode` option and configures if and how [Prometheus](https://prometheus.io/) formatted metrics are generated.
 
 There are different settings:
 | Setting | Description |
@@ -137,7 +137,7 @@ Settings can be provided from the command line, a configuration file, or an envi
 | dev-mode                 |         | dev-mode                   | INDEXER_DEV_MODE                   |
 | metrics-mode             |         | metrics-mode               | INDEXER_METRICS_MODE               |
 
-## command line
+## Command line
 
 The command line arguments always take priority over the config file and environment variables.
 
@@ -146,7 +146,7 @@ The command line arguments always take priority over the config file and environ
 ```
 
 
-## configuration file
+## Configuration file
 Default values are placed in the configuration file. They can be overridden with environment variables and command line arguments.
 
 The configuration file must named **indexer**, **indexer.yml**, or **indexer.yaml**. It must also be in the correct location. Only one configuration file is loaded, the path is searched in the following order:
@@ -219,4 +219,3 @@ Indexer v1 was built into the algod v1 REST API. It has been removed with the al
 Indexer is built using an in-house task framework called [`mule`](https://pypi.org/project/mulecli/) (it has since been open-sourced).
 
 Please refer to the [build docs](mule/README.md) in the `mule/` directory.
-
diff --git a/accounting/accounting.go b/accounting/accounting.go
index bd96d81..c3040cd 100644
--- a/accounting/accounting.go
+++ b/accounting/accounting.go
@@ -394,6 +394,7 @@ func (accounting *State) AddTransaction(txnr *idb.TxnRow) (err error) {
 				ClearStateProgram: stxn.Txn.ClearStateProgram,
 				LocalStateSchema:  stxn.Txn.LocalStateSchema,
 				GlobalStateSchema: stxn.Txn.GlobalStateSchema,
+				ExtraProgramPages: stxn.Txn.ExtraProgramPages,
 			}
 			if stxn.Txn.ApplicationID == 0 {
 				// app creation
diff --git a/api/converter_utils.go b/api/converter_utils.go
index 89e4bbb..217bc5f 100644
--- a/api/converter_utils.go
+++ b/api/converter_utils.go
@@ -382,7 +382,8 @@ func txnRowToTransaction(row idb.TxnRow) (generated.Transaction, error) {
 				NumByteSlice: stxn.Txn.LocalStateSchema.NumByteSlice,
 				NumUint:      stxn.Txn.LocalStateSchema.NumUint,
 			},
-			OnCompletion: onCompletionToTransactionOnCompletion(stxn.Txn.OnCompletion),
+			OnCompletion:      onCompletionToTransactionOnCompletion(stxn.Txn.OnCompletion),
+			ExtraProgramPages: uint64PtrOrNil(uint64(stxn.Txn.ExtraProgramPages)),
 		}
 
 		application = &a
diff --git a/api/generate.sh b/api/generate.sh
index 7e60a77..86dae2a 100755
--- a/api/generate.sh
+++ b/api/generate.sh
@@ -14,5 +14,5 @@ echo "generating code."
 oapi-codegen -package generated -type-mappings integer=uint64 -generate types -o generated/v2/types.go -exclude-tags=common indexer.oas3.yml
 oapi-codegen -package generated -type-mappings integer=uint64 -generate server,spec -o generated/v2/routes.go -exclude-tags=common indexer.oas3.yml
 
-oapi-codegen -package generated -type-mappings integer=uint64 -generate types -o generated/common/types.go -include-tags=common indexer.oas3.yml
-oapi-codegen -package generated -type-mappings integer=uint64 -generate server,spec -o generated/common/routes.go -include-tags=common indexer.oas3.yml
+oapi-codegen -package common -type-mappings integer=uint64 -generate types -o generated/common/types.go -include-tags=common indexer.oas3.yml
+oapi-codegen -package common -type-mappings integer=uint64 -generate server,spec -o generated/common/routes.go -include-tags=common indexer.oas3.yml
diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go
index 2782443..9768ee6 100644
--- a/api/generated/common/routes.go
+++ b/api/generated/common/routes.go
@@ -71,146 +71,148 @@ func RegisterHandlers(router interface {
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
-	"7/9/AAAA//8a+VinDqUAAA==",
+	"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",
+	"uKYAAA==",
 }
 
 // GetSwagger returns the Swagger specification corresponding to the generated code
diff --git a/api/generated/common/types.go b/api/generated/common/types.go
index b2f3173..b1d81cd 100644
--- a/api/generated/common/types.go
+++ b/api/generated/common/types.go
@@ -24,6 +24,9 @@ type Account struct {
 	// Note the raw object uses `map[int] -> AppLocalState` for this type.
 	AppsLocalState *[]ApplicationLocalState `json:"apps-local-state,omitempty"`
 
+	// \[teap\] the sum of all extra application program pages for this account.
+	AppsTotalExtraPages *uint64 `json:"apps-total-extra-pages,omitempty"`
+
 	// Specifies maximums on the number of each type that may be stored.
 	AppsTotalSchema *ApplicationStateSchema `json:"apps-total-schema,omitempty"`
 
@@ -162,6 +165,9 @@ type ApplicationParams struct {
 	// The address that created this application. This is the address where the parameters and global state for this application can be found.
 	Creator *string `json:"creator,omitempty"`
 
+	// \[epp\] the amount of extra program pages available to this app.
+	ExtraProgramPages *uint64 `json:"extra-program-pages,omitempty"`
+
 	// Represents a key-value store for use in an application.
 	GlobalState *TealKeyValueStore `json:"global-state,omitempty"`
 
@@ -491,7 +497,7 @@ type Transaction struct {
 	// data/transactions/asset.go : AssetTransferTxnFields
 	AssetTransferTransaction *TransactionAssetTransfer `json:"asset-transfer-transaction,omitempty"`
 
-	// \[sgnr\] The address used to sign the transaction. This is used for rekeyed accounts to indicate that the sender address did not sign the transaction.
+	// \[sgnr\] this is included with signed transactions when the signing address does not equal the sender. The backend can use this to ensure that auth addr is equal to the accounts auth addr.
 	AuthAddr *string `json:"auth-addr,omitempty"`
 
 	// \[rc\] rewards applied to close-remainder-to account.
@@ -605,6 +611,9 @@ type TransactionApplication struct {
 	// \[apsu\] Logic executed for application transactions with on-completion set to "clear". It can read and write global state for the application, as well as account-specific local state. Clear state programs cannot reject the transaction.
 	ClearStateProgram *[]byte `json:"clear-state-program,omitempty"`
 
+	// \[epp\] specifies the additional app program len requested in pages.
+	ExtraProgramPages *uint64 `json:"extra-program-pages,omitempty"`
+
 	// \[apfa\] Lists the applications in addition to the application-id whose global states may be accessed by this application's approval-program and clear-state-program. The access is read-only.
 	ForeignApps *[]uint64 `json:"foreign-apps,omitempty"`
 
diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go
index 9fd8fca..b1602d5 100644
--- a/api/generated/v2/routes.go
+++ b/api/generated/v2/routes.go
@@ -1314,170 +1314,171 @@ func RegisterHandlers(router interface {
 // Base64 encoded, gzipped, json marshaled Swagger object
 var swaggerSpec = []string{
 
-	"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",
-	"AP//5mehGYn2AAA=",
+	"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",
 }
 
 // GetSwagger returns the Swagger specification corresponding to the generated code
diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go
index e11e9d7..d657bea 100644
--- a/api/generated/v2/types.go
+++ b/api/generated/v2/types.go
@@ -24,6 +24,9 @@ type Account struct {
 	// Note the raw object uses `map[int] -> AppLocalState` for this type.
 	AppsLocalState *[]ApplicationLocalState `json:"apps-local-state,omitempty"`
 
+	// \[teap\] the sum of all extra application program pages for this account.
+	AppsTotalExtraPages *uint64 `json:"apps-total-extra-pages,omitempty"`
+
 	// Specifies maximums on the number of each type that may be stored.
 	AppsTotalSchema *ApplicationStateSchema `json:"apps-total-schema,omitempty"`
 
@@ -162,6 +165,9 @@ type ApplicationParams struct {
 	// The address that created this application. This is the address where the parameters and global state for this application can be found.
 	Creator *string `json:"creator,omitempty"`
 
+	// \[epp\] the amount of extra program pages available to this app.
+	ExtraProgramPages *uint64 `json:"extra-program-pages,omitempty"`
+
 	// Represents a key-value store for use in an application.
 	GlobalState *TealKeyValueStore `json:"global-state,omitempty"`
 
@@ -491,7 +497,7 @@ type Transaction struct {
 	// data/transactions/asset.go : AssetTransferTxnFields
 	AssetTransferTransaction *TransactionAssetTransfer `json:"asset-transfer-transaction,omitempty"`
 
-	// \[sgnr\] The address used to sign the transaction. This is used for rekeyed accounts to indicate that the sender address did not sign the transaction.
+	// \[sgnr\] this is included with signed transactions when the signing address does not equal the sender. The backend can use this to ensure that auth addr is equal to the accounts auth addr.
 	AuthAddr *string `json:"auth-addr,omitempty"`
 
 	// \[rc\] rewards applied to close-remainder-to account.
@@ -605,6 +611,9 @@ type TransactionApplication struct {
 	// \[apsu\] Logic executed for application transactions with on-completion set to "clear". It can read and write global state for the application, as well as account-specific local state. Clear state programs cannot reject the transaction.
 	ClearStateProgram *[]byte `json:"clear-state-program,omitempty"`
 
+	// \[epp\] specifies the additional app program len requested in pages.
+	ExtraProgramPages *uint64 `json:"extra-program-pages,omitempty"`
+
 	// \[apfa\] Lists the applications in addition to the application-id whose global states may be accessed by this application's approval-program and clear-state-program. The access is read-only.
 	ForeignApps *[]uint64 `json:"foreign-apps,omitempty"`
 
diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json
index 217c71c..451d3da 100644
--- a/api/indexer.oas2.json
+++ b/api/indexer.oas2.json
@@ -656,6 +656,10 @@
           "description": "\\[tsch\\] stores the sum of all of the local schemas and global schemas in this account.\n\nNote: the raw account uses `StateSchema` for this type.",
           "$ref": "#/definitions/ApplicationStateSchema"
         },
+        "apps-total-extra-pages": {
+          "description": "\\[teap\\] the sum of all extra application program pages for this account.",
+          "type": "integer"
+        },
         "assets": {
           "description": "\\[asset\\] assets held by this account.\n\nNote the raw object uses `map[int] -\u003e AssetHolding` for this type.",
           "type": "array",
@@ -934,6 +938,10 @@
         "global-state": {
           "description": "[\\gs\\] global schema",
           "$ref": "#/definitions/TealKeyValueStore"
+        },
+        "extra-program-pages": {
+          "description": "\\[epp\\] the amount of extra program pages available to this app.",
+          "type": "integer"
         }
       }
     },
@@ -1625,6 +1633,10 @@
           "type": "string",
           "format": "byte",
           "x-algorand-format": "TEALProgram"
+        },
+        "extra-program-pages": {
+          "description": "\\[epp\\] specifies the additional app program len requested in pages.",
+          "type": "integer"
         }
       }
     },
diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml
index 1bfd744..65f1813 100644
--- a/api/indexer.oas3.yml
+++ b/api/indexer.oas3.yml
@@ -503,6 +503,10 @@
             },
             "type": "array"
           },
+          "apps-total-extra-pages": {
+            "description": "\\[teap\\] the sum of all extra application program pages for this account.",
+            "type": "integer"
+          },
           "apps-total-schema": {
             "$ref": "#/components/schemas/ApplicationStateSchema"
           },
@@ -730,6 +734,10 @@
             "type": "string",
             "x-algorand-format": "Address"
           },
+          "extra-program-pages": {
+            "description": "\\[epp\\] the amount of extra program pages available to this app.",
+            "type": "integer"
+          },
           "global-state": {
             "$ref": "#/components/schemas/TealKeyValueStore"
           },
@@ -1283,7 +1291,7 @@
             "$ref": "#/components/schemas/TransactionAssetTransfer"
           },
           "auth-addr": {
-            "description": "\\[sgnr\\] The address used to sign the transaction. This is used for rekeyed accounts to indicate that the sender address did not sign the transaction.",
+            "description": "\\[sgnr\\] this is included with signed transactions when the signing address does not equal the sender. The backend can use this to ensure that auth addr is equal to the accounts auth addr.",
             "type": "string",
             "x-algorand-format": "Address"
           },
@@ -1456,6 +1464,10 @@
             "type": "string",
             "x-algorand-format": "TEALProgram"
           },
+          "extra-program-pages": {
+            "description": "\\[epp\\] specifies the additional app program len requested in pages.",
+            "type": "integer"
+          },
           "foreign-apps": {
             "description": "\\[apfa\\] Lists the applications in addition to the application-id whose global states may be accessed by this application's approval-program and clear-state-program. The access is read-only.",
             "items": {
diff --git a/api/pointer_utils.go b/api/pointer_utils.go
index 51b047c..8b1ba4f 100644
--- a/api/pointer_utils.go
+++ b/api/pointer_utils.go
@@ -44,6 +44,13 @@ func uint64Ptr(x uint64) *uint64 {
 	return &x
 }
 
+func uint64PtrOrNil(x uint64) *uint64 {
+	if x == 0 {
+		return nil
+	}
+	return &x
+}
+
 func bytePtr(x []byte) *[]byte {
 	if len(x) == 0 {
 		return nil
diff --git a/cmd/block-generator/daemon.go b/cmd/block-generator/daemon.go
index 34450c3..f64721d 100644
--- a/cmd/block-generator/daemon.go
+++ b/cmd/block-generator/daemon.go
@@ -1,13 +1,13 @@
 package main
 
 import (
+	"fmt"
 	"math/rand"
 
-	"github.com/algorand/indexer/cmd/block-generator/generator"
 	"github.com/spf13/cobra"
-)
 
-const configFileName = "block_generator_config"
+	"github.com/algorand/indexer/cmd/block-generator/generator"
+)
 
 func init() {
 	rand.Seed(12345)
@@ -19,7 +19,9 @@ func init() {
 		Use:   "daemon",
 		Short: "Start the generator daemon in standalone mode.",
 		Run: func(cmd *cobra.Command, args []string) {
-			generator.StartServer(configFile, port)
+			addr := fmt.Sprintf(":%d", port)
+			srv := generator.MakeServer(configFile, addr)
+			srv.ListenAndServe()
 		},
 	}
 
diff --git a/cmd/block-generator/generator/generate.go b/cmd/block-generator/generator/generate.go
index 1e8120b..c9fed9a 100644
--- a/cmd/block-generator/generator/generate.go
+++ b/cmd/block-generator/generator/generate.go
@@ -19,24 +19,25 @@ import (
 
 var errOutOfRange = fmt.Errorf("selection is out of weighted range")
 
-type txTypeID string
+// TxTypeID is the transaction type.
+type TxTypeID string
 
 const (
-	genesis txTypeID = "genesis"
+	genesis TxTypeID = "genesis"
 
 	// Payment Tx IDs
-	paymentTx           txTypeID = "pay"
-	paymentAcctCreateTx txTypeID = "pay_create"
-	assetTx             txTypeID = "asset"
-	//keyRegistrationTx txTypeID = "keyreg"
-	//applicationCallTx txTypeID = "appl"
+	paymentTx           TxTypeID = "pay"
+	paymentAcctCreateTx TxTypeID = "pay_create"
+	assetTx             TxTypeID = "asset"
+	//keyRegistrationTx TxTypeID = "keyreg"
+	//applicationCallTx TxTypeID = "appl"
 
 	// Asset Tx IDs
-	assetCreate  txTypeID = "asset_create"
-	assetOptin   txTypeID = "asset_optin"
-	assetXfer    txTypeID = "asset_xfer"
-	assetClose   txTypeID = "asset_close"
-	assetDestroy txTypeID = "asset_destroy"
+	assetCreate  TxTypeID = "asset_create"
+	assetOptin   TxTypeID = "asset_optin"
+	assetXfer    TxTypeID = "asset_xfer"
+	assetClose   TxTypeID = "asset_close"
+	assetDestroy TxTypeID = "asset_destroy"
 
 	assetTotal = uint64(100000000000000000)
 )
@@ -105,7 +106,7 @@ func MakeGenerator(config GenerationConfig) (Generator, error) {
 		rewardsResidue:            0,
 		rewardsRate:               0,
 		rewardsRecalculationRound: 0,
-		reportData:                make(map[txTypeID]txData),
+		reportData:                make(map[TxTypeID]TxData),
 	}
 
 	gen.feeSink[31] = 1
@@ -195,7 +196,7 @@ type generator struct {
 	assetTxWeights     []float32
 
 	// Reporting information from transaction type to data
-	reportData map[txTypeID]txData
+	reportData Report
 }
 
 type assetData struct {
@@ -212,15 +213,19 @@ type assetHolding struct {
 	balance   uint64
 }
 
-type txData struct {
+// Report is the generation report.
+type Report map[TxTypeID]TxData
+
+// TxData is the generator report data.
+type TxData struct {
 	GenerationTimeMilli time.Duration `json:"generation_time_milli"`
 	GenerationCount     uint64        `json:"num_generated"`
 }
 
-func track(id txTypeID) (txTypeID, time.Time) {
+func track(id TxTypeID) (TxTypeID, time.Time) {
 	return id, time.Now()
 }
-func (g *generator) recordData(id txTypeID, start time.Time) {
+func (g *generator) recordData(id TxTypeID, start time.Time) {
 	data := g.reportData[id]
 	data.GenerationCount++
 	data.GenerationTimeMilli += time.Since(start)
@@ -341,7 +346,6 @@ func (g *generator) WriteBlock(output io.Writer, round uint64) {
 	g.timestamp += consensusTimeMilli
 	g.round++
 
-	fmt.Println(g.txnCounter)
 	output.Write(msgpack.Encode(cert))
 }
 
@@ -414,10 +418,10 @@ func (g *generator) generatePaymentTxn(sp sdk_types.SuggestedParams, round uint6
 	if err != nil {
 		return types.SignedTxnInBlock{}, err
 	}
-	return g.generatePaymentTxnInternal(selection.(txTypeID), sp, round, intra)
+	return g.generatePaymentTxnInternal(selection.(TxTypeID), sp, round, intra)
 }
 
-func (g *generator) generatePaymentTxnInternal(selection txTypeID, sp sdk_types.SuggestedParams, _ uint64 /*round*/, _ uint64 /*intra*/) (types.SignedTxnInBlock, error) {
+func (g *generator) generatePaymentTxnInternal(selection TxTypeID, sp sdk_types.SuggestedParams, _ uint64 /*round*/, _ uint64 /*intra*/) (types.SignedTxnInBlock, error) {
 	defer g.recordData(track(selection))
 
 	var receiveIndex uint64
@@ -460,11 +464,11 @@ func getAssetTxOptions() []interface{} {
 	return []interface{}{assetCreate, assetDestroy, assetOptin, assetXfer, assetClose}
 }
 
-func (g *generator) generateAssetTxnInternal(txType txTypeID, sp sdk_types.SuggestedParams, intra uint64) (actual txTypeID, txn types.Transaction) {
+func (g *generator) generateAssetTxnInternal(txType TxTypeID, sp sdk_types.SuggestedParams, intra uint64) (actual TxTypeID, txn types.Transaction) {
 	return g.generateAssetTxnInternalHint(txType, sp, intra, 0, nil)
 }
 
-func (g *generator) generateAssetTxnInternalHint(txType txTypeID, sp sdk_types.SuggestedParams, intra uint64, hintIndex uint64, hint *assetData) (actual txTypeID, txn types.Transaction) {
+func (g *generator) generateAssetTxnInternalHint(txType TxTypeID, sp sdk_types.SuggestedParams, intra uint64, hintIndex uint64, hint *assetData) (actual TxTypeID, txn types.Transaction) {
 	actual = txType
 	// If there are no assets the next operation needs to be a create.
 	if len(g.assets) == 0 {
@@ -628,7 +632,7 @@ func (g *generator) generateAssetTxn(sp sdk_types.SuggestedParams, _ uint64 /*ro
 		return types.SignedTxnInBlock{}, err
 	}
 
-	actual, txn := g.generateAssetTxnInternal(selection.(txTypeID), sp, intra)
+	actual, txn := g.generateAssetTxnInternal(selection.(TxTypeID), sp, intra)
 	defer g.recordData(actual, start)
 
 	if txn.Type == "" {
diff --git a/cmd/block-generator/generator/server.go b/cmd/block-generator/generator/server.go
index b961840..dd9a35d 100644
--- a/cmd/block-generator/generator/server.go
+++ b/cmd/block-generator/generator/server.go
@@ -30,25 +30,24 @@ func initializeConfigFile(configFile string) (config GenerationConfig, err error
 	return
 }
 
-// StartServer configures http handlers then runs ListanAndServe.
-func StartServer(configFile string, port uint64) {
+// MakeServer configures http handlers. Returns the http server.
+func MakeServer(configFile string, addr string) *http.Server {
 	config, err := initializeConfigFile(configFile)
 	util.MaybeFail(err, "problem loading config file. Use '--config' or create a config file.")
 
 	gen, err := MakeGenerator(config)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "Unable to create generator: %v", err)
-		os.Exit(1)
-	}
+	util.MaybeFail(err, "Failed to make generator with config file '%s'", configFile)
 
-	http.HandleFunc("/", help)
-	http.HandleFunc("/v2/blocks/", getBlockHandler(gen))
-	http.HandleFunc("/genesis", getGenesisHandler(gen))
-	http.HandleFunc("/report", getReportHandler(gen))
+	mux := http.NewServeMux()
+	mux.HandleFunc("/", help)
+	mux.HandleFunc("/v2/blocks/", getBlockHandler(gen))
+	mux.HandleFunc("/genesis", getGenesisHandler(gen))
+	mux.HandleFunc("/report", getReportHandler(gen))
 
-	portStr := fmt.Sprintf(":%d", port)
-	fmt.Printf("Starting server at %s\n", portStr)
-	http.ListenAndServe(portStr, nil)
+	return &http.Server{
+		Addr:    addr,
+		Handler: mux,
+	}
 }
 
 func help(w http.ResponseWriter, r *http.Request) {
diff --git a/cmd/block-generator/runner.go b/cmd/block-generator/runner.go
new file mode 100644
index 0000000..b95e5b1
--- /dev/null
+++ b/cmd/block-generator/runner.go
@@ -0,0 +1,40 @@
+package main
+
+import (
+	"fmt"
+	"math/rand"
+	"time"
+
+	"github.com/spf13/cobra"
+
+	"github.com/algorand/indexer/cmd/block-generator/runner"
+)
+
+func init() {
+	rand.Seed(12345)
+	var runnerArgs runner.Args
+
+	var runnerCmd = &cobra.Command{
+		Use:   "runner",
+		Short: "Run test suite and collect results.",
+		Run: func(cmd *cobra.Command, args []string) {
+			if err := runner.Run(runnerArgs); err != nil {
+				fmt.Println(err)
+			}
+		},
+	}
+
+	runnerCmd.Flags().StringVarP(&runnerArgs.Path, "scenario", "s", "", "Directory containing scenarios, or specific scenario file.")
+	runnerCmd.Flags().StringVarP(&runnerArgs.IndexerBinary, "indexer-binary", "i", "", "Path to indexer binary.")
+	runnerCmd.Flags().Uint64VarP(&runnerArgs.IndexerPort, "indexer-port", "p", 4010, "Port to start the server at. This is useful if you have a prometheus server for collecting additional data.")
+	runnerCmd.Flags().StringVarP(&runnerArgs.PostgresConnectionString, "postgres-connection-string", "c", "", "Postgres connection string.")
+	runnerCmd.Flags().DurationVarP(&runnerArgs.RunDuration, "test-duration", "d", 5*time.Minute, "Duration to use for each scenario.")
+	runnerCmd.Flags().StringVarP(&runnerArgs.ReportDirectory, "report-directory", "r", "", "Location to place test reports.")
+
+	runnerCmd.MarkFlagRequired("scenario")
+	runnerCmd.MarkFlagRequired("indexer-binary")
+	runnerCmd.MarkFlagRequired("postgres-connection-string")
+	runnerCmd.MarkFlagRequired("report-directory")
+
+	rootCmd.AddCommand(runnerCmd)
+}
diff --git a/cmd/block-generator/runner/metrics_collector.go b/cmd/block-generator/runner/metrics_collector.go
new file mode 100644
index 0000000..ccaf545
--- /dev/null
+++ b/cmd/block-generator/runner/metrics_collector.go
@@ -0,0 +1,69 @@
+package runner
+
+import (
+	"bufio"
+	"fmt"
+	"net/http"
+	"strings"
+	"time"
+)
+
+// MetricsCollector queries a /metrics endpoint for prometheus style metrics and saves metrics matching a pattern.
+type MetricsCollector struct {
+	// MetricsURL where metrics can be queried.
+	MetricsURL string
+	// Data is all of the results.
+	Data []Entry
+}
+
+// Entry is the raw data pulled from the endpoint along with a timestamp.
+type Entry struct {
+	Timestamp time.Time
+	Data      []string
+}
+
+// Collect fetches the metrics.
+func (r *MetricsCollector) Collect(prefix string) error {
+	metrics, err := r.getMetrics(prefix)
+	if err != nil {
+		return err
+	}
+
+	if len(metrics) > 0 {
+		entry := Entry{
+			Timestamp: time.Now(),
+			Data:      metrics,
+		}
+		r.Data = append(r.Data, entry)
+	}
+
+	return nil
+}
+
+func (r MetricsCollector) getMetrics(prefix string) (result []string, err error) {
+	resp, err := http.Get(r.MetricsURL)
+	if err != nil {
+		err = fmt.Errorf("unable to read metrics url '%s'", r.MetricsURL)
+		return
+	}
+	defer resp.Body.Close()
+
+	scanner := bufio.NewScanner(resp.Body)
+	for scanner.Scan() {
+		str := scanner.Text()
+
+		if strings.HasPrefix(str, "#") {
+			continue
+		}
+
+		if strings.HasPrefix(str, prefix) {
+			result = append(result, str)
+		}
+	}
+
+	if scanner.Err() != nil {
+		err = fmt.Errorf("problem reading metrics response: %w", scanner.Err())
+	}
+
+	return
+}
diff --git a/cmd/block-generator/runner/run.go b/cmd/block-generator/runner/run.go
new file mode 100644
index 0000000..05d65df
--- /dev/null
+++ b/cmd/block-generator/runner/run.go
@@ -0,0 +1,255 @@
+package runner
+
+import (
+	"bytes"
+	"context"
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	// Load the postgres sql.DB implementation
+	_ "github.com/lib/pq"
+
+	"github.com/algorand/indexer/cmd/block-generator/generator"
+	"github.com/algorand/indexer/util"
+)
+
+// Args are all the things needed to run a performance test.
+type Args struct {
+	// Path is a directory when passed to RunBatch, otherwise a file path.
+	Path                     string
+	IndexerBinary            string
+	IndexerPort              uint64
+	PostgresConnectionString string
+	RunDuration              time.Duration
+	ReportDirectory          string
+}
+
+// Run is a public helper to run the tests.
+// The test will run against the generator configuration file specified by 'args.Path'.
+// If 'args.Path' is a directory it should contain generator configuration files, a test will run using each file.
+func Run(args Args) error {
+	if _, err := os.Stat(args.ReportDirectory); !os.IsNotExist(err) {
+		return fmt.Errorf("report directory '%s' already exists", args.ReportDirectory)
+	}
+	os.Mkdir(args.ReportDirectory, os.ModeDir|os.ModePerm)
+
+	return filepath.Walk(args.Path, func(path string, info os.FileInfo, err error) error {
+		// Ignore the directory
+		if info.IsDir() {
+			return nil
+		}
+		runnerArgs := args
+		runnerArgs.Path = path
+		fmt.Printf("Running test for configuration '%s'\n", path)
+		return runnerArgs.run()
+	})
+}
+
+func (r *Args) run() error {
+	// Start services
+	algodNet := fmt.Sprintf("localhost:%d", 11112)
+	indexerNet := fmt.Sprintf("localhost:%d", r.IndexerPort)
+	generatorShutdownFunc := startGenerator(r.Path, algodNet)
+	indexerShutdownFunc, err := startIndexer(r.IndexerBinary, algodNet, indexerNet, r.PostgresConnectionString)
+	if err != nil {
+		return fmt.Errorf("failed to start indexer: %w", err)
+	}
+
+	// Run the test, collecting results.
+	if err := r.runTest(indexerNet, algodNet); err != nil {
+		return err
+	}
+
+	// Shutdown generator.
+	if err := generatorShutdownFunc(); err != nil {
+		return err
+	}
+
+	// Shutdown indexer
+	if err := indexerShutdownFunc(); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Helper to record the import rate.
+func recordDataToFile(entry Entry, key string, out *os.File) error {
+	sum := 0.0
+	count := 0.0
+
+	for _, metric := range entry.Data {
+		var err error
+		if strings.HasPrefix(metric, "indexer_daemon_import_time_sec_sum") {
+			val := strings.Split(metric, " ")[1]
+			sum, err = strconv.ParseFloat(val, 64)
+		} else if strings.HasPrefix(metric, "indexer_daemon_import_time_sec_count") {
+			val := strings.Split(metric, " ")[1]
+			count, err = strconv.ParseFloat(val, 64)
+		}
+		if err != nil {
+			return fmt.Errorf("unable to parse metric '%s': %w", metric, err)
+		}
+	}
+	rate := sum / count
+
+	msg := fmt.Sprintf("%s:%f\n", key, rate)
+	if _, err := out.WriteString(msg); err != nil {
+		return fmt.Errorf("unable to write metric '%s': %w", key, err)
+	}
+	return nil
+}
+
+// Run the test for 'RunDuration', collect metrics and write them to the 'ReportDirectory'
+func (r *Args) runTest(indexerURL string, generatorURL string) error {
+	collector := &MetricsCollector{MetricsURL: fmt.Sprintf("http://%s/metrics", indexerURL)}
+
+	baseName := filepath.Base(r.Path)
+	baseNameNoExt := strings.TrimSuffix(baseName, filepath.Ext(baseName))
+	reportPath := path.Join(r.ReportDirectory, fmt.Sprintf("%s.report", baseNameNoExt))
+
+	report, err := os.Create(reportPath)
+	if err != nil {
+		return fmt.Errorf("unable to create report: %w", err)
+	}
+	defer report.Close()
+
+	// Run for r.RunDuration
+	start := time.Now()
+	for time.Since(start) < r.RunDuration {
+		time.Sleep(r.RunDuration / 10)
+		if err := collector.Collect("indexer_daemon_import_time_sec"); err != nil {
+			return fmt.Errorf("problem collecting metrics: %w", err)
+		}
+	}
+	if err := collector.Collect("indexer_daemon_import_time_sec"); err != nil {
+		return fmt.Errorf("problem collecting metrics: %w", err)
+	}
+
+	// Collect results.
+	durationStr := fmt.Sprintf("test_duration_seconds:%d\ntest_duration_actual_seconds:%f\n",
+		uint64(r.RunDuration.Seconds()),
+		time.Since(start).Seconds())
+	if _, err := report.WriteString(durationStr); err != nil {
+		return fmt.Errorf("unable to write duration metric: %w", err)
+	}
+
+	resp, err := http.Get(fmt.Sprintf("http://%s/report", generatorURL))
+	if err != nil {
+		return fmt.Errorf("generator report query failed")
+	}
+	defer resp.Body.Close()
+	var generatorReport generator.Report
+	if err := json.NewDecoder(resp.Body).Decode(&generatorReport); err != nil {
+		return fmt.Errorf("problem decoding generator report: %w", err)
+	}
+	for metric, entry := range generatorReport {
+		// Skip this one
+		if metric == "genesis" {
+			continue
+		}
+		str := fmt.Sprintf("transaction_%s_total:%d\n", metric, entry.GenerationCount)
+		if _, err := report.WriteString(str); err != nil {
+			return fmt.Errorf("unable to write transaction_count metric: %w", err)
+		}
+	}
+
+	// Record a rate from one of the first data points.
+	if len(collector.Data) > 5 {
+		if err := recordDataToFile(collector.Data[2], "starting_block_import_duration_average_seconds", report); err != nil {
+			return err
+		}
+	}
+
+	// Also record the final one.
+	if err := recordDataToFile(collector.Data[len(collector.Data)-1], "final_import_duration_average_seconds", report); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// startGenerator starts the generator server.
+func startGenerator(configFile string, addr string) func() error {
+	// Start generator.
+	server := generator.MakeServer(configFile, addr)
+
+	// Start the server
+	go func() {
+		// always returns error. ErrServerClosed on graceful close
+		if err := server.ListenAndServe(); err != http.ErrServerClosed {
+			util.MaybeFail(err, "ListenAndServe() failure to start with config file '%s'", configFile)
+		}
+	}()
+
+	return func() error {
+		// Shutdown blocks until the server has stopped.
+		if err := server.Shutdown(context.Background()); err != nil {
+			return fmt.Errorf("failed during generator graceful shutdown: %w", err)
+		}
+		return nil
+	}
+}
+
+// startIndexer resets the postgres database and executes the indexer binary. It performs some simple verification to
+// ensure that the service has started properly.
+func startIndexer(indexerBinary string, algodNet string, indexerNet string, postgresConnectionString string) (func() error, error) {
+	{
+		db, err := sql.Open("postgres", postgresConnectionString)
+		if err != nil {
+			return nil, fmt.Errorf("postgres connection string did not work: %w", err)
+		}
+		if _, err := db.Exec(`DROP SCHEMA public CASCADE; CREATE SCHEMA public;`); err != nil {
+			return nil, fmt.Errorf("unable to reset postgres DB: %w", err)
+		}
+		if err := db.Close(); err != nil {
+			return nil, fmt.Errorf("unable to close database handle: %w", err)
+		}
+	}
+
+	cmd := exec.Command(
+		indexerBinary,
+		"daemon",
+		"--algod-net", algodNet,
+		"--algod-token", "secure-token-here",
+		"--metrics-mode", "VERBOSE",
+		"--postgres", postgresConnectionString,
+		"--server", indexerNet)
+
+	var stdout bytes.Buffer
+	var stderr bytes.Buffer
+	cmd.Stdout = &stdout
+	cmd.Stderr = &stderr
+
+	if err := cmd.Start(); err != nil {
+		return nil, fmt.Errorf("failure calling Start(): %w", err)
+	}
+
+	// Ensure that the health endpoint can be queried.
+	// The service should start very quickly because the DB is empty.
+	time.Sleep(5 * time.Second)
+	resp, err := http.Get(fmt.Sprintf("http://%s/health", indexerNet))
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "stdout:\n%s\n", stdout.String())
+		fmt.Fprintf(os.Stderr, "stderr:\n%s\n", stderr.String())
+		return nil, fmt.Errorf("the process failed to start properly, health endpoint query failed")
+	}
+	resp.Body.Close()
+
+	return func() error {
+		if err := cmd.Process.Kill(); err != nil {
+			return fmt.Errorf("failed to kill indexer process: %w", err)
+		}
+
+		return nil
+	}, nil
+}
diff --git a/cmd/validator/struct_processor.go b/cmd/validator/struct_processor.go
index a5c98d3..268785c 100644
--- a/cmd/validator/struct_processor.go
+++ b/cmd/validator/struct_processor.go
@@ -70,12 +70,12 @@ func equals(indexer, algod generated.Account) (differences []string) {
 	if algod.AmountWithoutPendingRewards != indexer.AmountWithoutPendingRewards {
 		differences = append(differences, "amount-without-pending-rewards")
 	}
-	/*
-		// Indexer doesn't support this yet.
-		if !appSchemaComparePtrEqual(algod.AppsTotalSchema, indexer.AppsTotalSchema) {
-			differences = append(differences, "apps-total-schema")
-		}
-	*/
+	if !appSchemaComparePtrEqual(algod.AppsTotalSchema, indexer.AppsTotalSchema) {
+		differences = append(differences, "apps-total-schema")
+	}
+	if !uint64PtrEqual(algod.AppsTotalExtraPages, indexer.AppsTotalExtraPages) {
+		differences = append(differences, "apps-total-extra-pages")
+	}
 	if !stringPtrEqual(algod.AuthAddr, indexer.AuthAddr) {
 		// Indexer doesn't remove the auth addr when it is removed.
 		if indexer.AuthAddr == nil || *indexer.AuthAddr != indexer.Address {
@@ -247,6 +247,9 @@ func equals(indexer, algod generated.Account) (differences []string) {
 			if !stateSchemePtrEqual(algodCreatedApp.Params.GlobalStateSchema, indexerCreatedApp.Params.GlobalStateSchema) {
 				differences = append(differences, fmt.Sprintf("created-app global-state-schema %d", algodCreatedApp.Id))
 			}
+			if !uint64PtrEqual(algodCreatedApp.Params.ExtraProgramPages, indexerCreatedApp.Params.ExtraProgramPages) {
+				differences = append(differences, fmt.Sprintf("created-app extra-pages %d", algodCreatedApp.Id))
+			}
 		}
 	}
 
diff --git a/go.mod b/go.mod
index d3edbcd..221e0c9 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module github.com/algorand/indexer
 go 1.13
 
 require (
-	github.com/algorand/go-algorand-sdk v1.7.0
+	github.com/algorand/go-algorand-sdk v1.9.1
 	github.com/algorand/go-codec/codec v1.1.7
 	github.com/algorand/oapi-codegen v1.3.5-algorand5
 	github.com/getkin/kin-openapi v0.19.0
diff --git a/go.sum b/go.sum
index d6e026b..358c611 100644
--- a/go.sum
+++ b/go.sum
@@ -62,6 +62,10 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/algorand/go-algorand-sdk v1.7.0 h1:eRg9UQy7FndRE5nTgniDpbyjTvP2FUKX4/0e8NdXn/E=
 github.com/algorand/go-algorand-sdk v1.7.0/go.mod h1:U12d8fTN/CyKPR1HObrt51ITxb6OgXxpGCH743Ds2GQ=
+github.com/algorand/go-algorand-sdk v1.9.0 h1:3xhFaScyMVy6D/XAWAuTnboNsnkgl9EqCZqgAnaOLm4=
+github.com/algorand/go-algorand-sdk v1.9.0/go.mod h1:U12d8fTN/CyKPR1HObrt51ITxb6OgXxpGCH743Ds2GQ=
+github.com/algorand/go-algorand-sdk v1.9.1 h1:v2UaVXeMOZxvWoNJp6+MUAjm8Gif+ultcxg1RBrj45s=
+github.com/algorand/go-algorand-sdk v1.9.1/go.mod h1:U12d8fTN/CyKPR1HObrt51ITxb6OgXxpGCH743Ds2GQ=
 github.com/algorand/go-codec v1.1.7 h1:6nvCh2nfgnfkaoVHKQyk2wxyl2GQBAlI7IkbqbB/e4s=
 github.com/algorand/go-codec v1.1.7/go.mod h1:pVLQYhIVCsx9D3iy4W4Qqi0SKhx6IVhMwOvj/agFL4g=
 github.com/algorand/go-codec/codec v1.1.7 h1:EFOyWf5duxbh2ru+AW1YDgmZ+MRVgqklELSqTArgp3M=
diff --git a/idb/idb.go b/idb/idb.go
index cb43435..4549923 100644
--- a/idb/idb.go
+++ b/idb/idb.go
@@ -405,6 +405,7 @@ type AppDelta struct {
 	ClearStateProgram []byte                `codec:"clearp"`
 	LocalStateSchema  sdk_types.StateSchema `codec:"lsch"`
 	GlobalStateSchema sdk_types.StateSchema `codec:"gsch"`
+	ExtraProgramPages uint32                `codec:"epp"`
 }
 
 // String is part of the Stringer interface.
@@ -434,6 +435,9 @@ func (ad AppDelta) String() string {
 	if ad.LocalStateSchema.NumByteSlice != 0 || ad.LocalStateSchema.NumUint != 0 {
 		parts = append(parts, fmt.Sprintf("lss(b=%d, i=%d)", ad.LocalStateSchema.NumByteSlice, ad.LocalStateSchema.NumUint))
 	}
+	if ad.ExtraProgramPages != 0 {
+		parts = append(parts, fmt.Sprintf("epp=%d", ad.ExtraProgramPages))
+	}
 
 	return strings.Join(parts, " ")
 }
@@ -452,6 +456,7 @@ type AppReverseDelta struct {
 	ClearStateProgram []byte                 `codec:"clearp,omitempty"`
 	LocalStateSchema  sdk_types.StateSchema  `codec:"lsch,omitempty"`
 	GlobalStateSchema sdk_types.StateSchema  `codec:"gsch,omitempty"`
+	ExtraProgramPages uint32                 `codec:"epp,omitempty"`
 }
 
 // SetDelta adds delta values to the AppReverseDelta object.
diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go
index bebe523..d29c252 100644
--- a/idb/postgres/postgres.go
+++ b/idb/postgres/postgres.go
@@ -720,6 +720,7 @@ type AppParams struct {
 	ClearStateProgram []byte      `codec:"clearp"`
 	LocalStateSchema  StateSchema `codec:"lsch"`
 	GlobalStateSchema StateSchema `codec:"gsch"`
+	ExtraProgramPages uint32      `codec:"epp"`
 
 	GlobalState TealKeyValue `codec:"gs,allocbound=-"`
 }
@@ -1136,6 +1137,9 @@ ON CONFLICT (addr, assetid) DO UPDATE SET amount = account_asset.amount + EXCLUD
 					return fmt.Errorf("app delta apply err r=%d i=%d app=%d, %v", adelta.Round, adelta.Intra, adelta.AppIndex, err)
 				}
 			}
+			reverseDelta.ExtraProgramPages = state.ExtraProgramPages
+			state.ExtraProgramPages = adelta.ExtraProgramPages
+
 			reverseDeltas = append(reverseDeltas, []interface{}{encoding.EncodeJSON(reverseDelta), adelta.Round, adelta.Intra})
 			if adelta.OnCompletion == sdk_types.DeleteApplicationOC {
 				// clear content but leave row recording that it existed
@@ -2092,6 +2096,8 @@ func (db *IndexerDb) yieldAccountsThread(req *getAccountsRequest) {
 			*account.CreatedAssets = cal
 		}
 
+		var totalSchema models.ApplicationStateSchema
+
 		if len(appParamIndexes) > 0 {
 			// apps owned by this account
 			var appIds []uint64
@@ -2136,6 +2142,7 @@ func (db *IndexerDb) yieldAccountsThread(req *getAccountsRequest) {
 				break
 			}
 
+			var totalExtraPages uint64
 			aout := make([]models.Application, len(appIds))
 			outpos := 0
 			for i, appid := range appIds {
@@ -2160,6 +2167,11 @@ func (db *IndexerDb) yieldAccountsThread(req *getAccountsRequest) {
 						NumUint:      apps[i].LocalStateSchema.NumUint,
 					}
 				}
+				if aout[outpos].Deleted == nil || !*aout[outpos].Deleted {
+					totalSchema.NumByteSlice += apps[i].GlobalStateSchema.NumByteSlice
+					totalSchema.NumUint += apps[i].GlobalStateSchema.NumUint
+					totalExtraPages += uint64(apps[i].ExtraProgramPages)
+				}
 
 				outpos++
 			}
@@ -2167,6 +2179,10 @@ func (db *IndexerDb) yieldAccountsThread(req *getAccountsRequest) {
 				aout = aout[:outpos]
 			}
 			account.CreatedApps = &aout
+
+			if totalExtraPages != 0 {
+				account.AppsTotalExtraPages = &totalExtraPages
+			}
 		}
 
 		if len(localStateAppIds) > 0 {
@@ -2222,10 +2238,19 @@ func (db *IndexerDb) yieldAccountsThread(req *getAccountsRequest) {
 					NumUint:      ls[i].Schema.NumUint,
 				}
 				aout[i].KeyValue = ls[i].KeyValue.toModel()
+				if aout[i].Deleted == nil || !*aout[i].Deleted {
+					totalSchema.NumByteSlice += ls[i].Schema.NumByteSlice
+					totalSchema.NumUint += ls[i].Schema.NumUint
+				}
+
 			}
 			account.AppsLocalState = &aout
 		}
 
+		if totalSchema != (models.ApplicationStateSchema{}) {
+			account.AppsTotalSchema = &totalSchema
+		}
+
 		// Sometimes the migration state effects what data should be returned.
 		db.processAccount(&account)
 
@@ -2876,6 +2901,12 @@ func (db *IndexerDb) yieldApplicationsThread(ctx context.Context, rows *sql.Rows
 			NumByteSlice: ap.LocalStateSchema.NumByteSlice,
 			NumUint:      ap.LocalStateSchema.NumUint,
 		}
+
+		if ap.ExtraProgramPages != 0 {
+			rec.Application.Params.ExtraProgramPages = new(uint64)
+			*rec.Application.Params.ExtraProgramPages = uint64(ap.ExtraProgramPages)
+		}
+
 		out <- rec
 	}
 	if err := rows.Err(); err != nil {
diff --git a/types/protocols.json b/types/protocols.json
index bac3aba..729fc50 100644
--- a/types/protocols.json
+++ b/types/protocols.json
@@ -21,6 +21,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": true,
+    "EnableKeyregCoherencyCheck": true,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -30,24 +32,28 @@
     "LateCommitteeThreshold": 320,
     "LogicSigMaxCost": 20000,
     "LogicSigMaxSize": 1000,
-    "LogicSigVersion": 3,
+    "LogicSigVersion": 4,
     "MaxAppArgs": 16,
-    "MaxAppBytesValueLen": 64,
+    "MaxAppBytesValueLen": 128,
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
-    "MaxAppProgramLen": 1024,
+    "MaxAppProgramLen": 2048,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
-    "MaxAppTxnForeignApps": 2,
-    "MaxAppTxnForeignAssets": 2,
+    "MaxAppTxnForeignApps": 8,
+    "MaxAppTxnForeignAssets": 8,
     "MaxAppsCreated": 10,
     "MaxAppsOptedIn": 10,
     "MaxAssetDecimals": 19,
     "MaxAssetNameBytes": 32,
-    "MaxAssetURLBytes": 32,
+    "MaxAssetURLBytes": 96,
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 3,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -114,6 +120,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -129,7 +137,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -141,6 +152,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -207,6 +219,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -222,7 +236,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -234,6 +251,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -300,6 +318,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -315,7 +335,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -327,6 +350,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -393,6 +417,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -408,7 +434,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -420,6 +449,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -486,6 +516,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -501,7 +533,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -513,6 +548,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -579,6 +615,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -594,7 +632,10 @@
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -606,6 +647,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -672,6 +714,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -687,7 +731,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -699,6 +746,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -765,6 +813,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -780,7 +830,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -792,6 +845,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -858,6 +912,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -873,7 +929,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -885,6 +944,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -927,6 +987,103 @@
     "UpgradeThreshold": 9000,
     "UpgradeVoteRounds": 10000
   },
+  "https://github.com/algorandfoundation/specs/tree/65b4ab3266c52c56a0fa7d591754887d68faad0a": {
+    "AgreementFilterTimeout": 4000000000,
+    "AgreementFilterTimeoutPeriod0": 4000000000,
+    "AppFlatOptInMinBalance": 100000,
+    "AppFlatParamsMinBalance": 100000,
+    "Application": true,
+    "ApplyData": true,
+    "ApprovedUpgrades": {},
+    "Asset": true,
+    "CertCommitteeSize": 1500,
+    "CertCommitteeThreshold": 1112,
+    "CompactCertRounds": 0,
+    "CompactCertSecKQ": 0,
+    "CompactCertTopVoters": 0,
+    "CompactCertVotersLookback": 0,
+    "CompactCertWeightThreshold": 0,
+    "CredentialDomainSeparationEnabled": true,
+    "DefaultKeyDilution": 10000,
+    "DefaultUpgradeWaitRounds": 140000,
+    "DownCommitteeSize": 6000,
+    "DownCommitteeThreshold": 4560,
+    "EnableAssetCloseAmount": true,
+    "EnableFeePooling": true,
+    "EnableKeyregCoherencyCheck": true,
+    "FastPartitionRecovery": true,
+    "FastRecoveryLambda": 300000000000,
+    "FixTransactionLeases": true,
+    "ForceNonParticipatingFeeSink": true,
+    "InitialRewardsRateCalculation": true,
+    "LateCommitteeSize": 500,
+    "LateCommitteeThreshold": 320,
+    "LogicSigMaxCost": 20000,
+    "LogicSigMaxSize": 1000,
+    "LogicSigVersion": 4,
+    "MaxAppArgs": 16,
+    "MaxAppBytesValueLen": 128,
+    "MaxAppKeyLen": 64,
+    "MaxAppProgramCost": 700,
+    "MaxAppProgramLen": 2048,
+    "MaxAppSumKeyValueLens": 128,
+    "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
+    "MaxAppTxnAccounts": 4,
+    "MaxAppTxnForeignApps": 8,
+    "MaxAppTxnForeignAssets": 8,
+    "MaxAppsCreated": 10,
+    "MaxAppsOptedIn": 10,
+    "MaxAssetDecimals": 19,
+    "MaxAssetNameBytes": 32,
+    "MaxAssetURLBytes": 96,
+    "MaxAssetUnitNameBytes": 8,
+    "MaxAssetsPerAccount": 1000,
+    "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 3,
+    "MaxGlobalSchemaEntries": 64,
+    "MaxLocalSchemaEntries": 16,
+    "MaxTimestampIncrement": 25,
+    "MaxTxGroupSize": 16,
+    "MaxTxnBytesPerBlock": 1000000,
+    "MaxTxnLife": 1000,
+    "MaxTxnNoteBytes": 1024,
+    "MaxUpgradeWaitRounds": 150000,
+    "MaxVersionStringLen": 128,
+    "MaximumMinimumBalance": 100100000,
+    "MinBalance": 100000,
+    "MinTxnFee": 1000,
+    "MinUpgradeWaitRounds": 10000,
+    "NextCommitteeSize": 5000,
+    "NextCommitteeThreshold": 3838,
+    "NoEmptyLocalDeltas": true,
+    "NumProposers": 20,
+    "PaysetCommit": 2,
+    "PendingResidueRewards": true,
+    "RedoCommitteeSize": 2400,
+    "RedoCommitteeThreshold": 1768,
+    "RequireGenesisHash": true,
+    "RewardUnit": 1000000,
+    "RewardsInApplyData": true,
+    "RewardsRateRefreshInterval": 500000,
+    "SchemaBytesMinBalance": 25000,
+    "SchemaMinBalancePerEntry": 25000,
+    "SchemaUintMinBalance": 3500,
+    "SeedLookback": 2,
+    "SeedRefreshInterval": 80,
+    "SoftCommitteeSize": 2990,
+    "SoftCommitteeThreshold": 2267,
+    "SupportBecomeNonParticipatingTransactions": true,
+    "SupportGenesisHash": true,
+    "SupportRekeying": true,
+    "SupportSignedTxnInBlock": true,
+    "SupportTransactionLeases": true,
+    "SupportTxGroups": true,
+    "TxnCounter": true,
+    "UpgradeThreshold": 9000,
+    "UpgradeVoteRounds": 10000
+  },
   "https://github.com/algorandfoundation/specs/tree/6c6bd668be0ab14098e51b37e806c509f7b7e31f": {
     "AgreementFilterTimeout": 4000000000,
     "AgreementFilterTimeoutPeriod0": 4000000000,
@@ -951,6 +1108,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -966,7 +1125,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -978,6 +1140,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1044,6 +1207,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1059,7 +1224,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1071,6 +1239,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1137,6 +1306,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1152,7 +1323,10 @@
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1164,6 +1338,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1230,6 +1405,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1245,7 +1422,10 @@
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1257,6 +1437,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1306,7 +1487,9 @@
     "AppFlatParamsMinBalance": 100000,
     "Application": true,
     "ApplyData": true,
-    "ApprovedUpgrades": {},
+    "ApprovedUpgrades": {
+      "https://github.com/algorandfoundation/specs/tree/65b4ab3266c52c56a0fa7d591754887d68faad0a": 140000
+    },
     "Asset": true,
     "CertCommitteeSize": 1500,
     "CertCommitteeThreshold": 1112,
@@ -1321,6 +1504,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1336,7 +1521,10 @@
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1348,6 +1536,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1414,6 +1603,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1429,7 +1620,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1441,6 +1635,7 @@
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1507,6 +1702,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1522,7 +1719,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1534,6 +1734,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1600,6 +1801,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1615,7 +1818,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1627,6 +1833,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1693,6 +1900,8 @@
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1708,7 +1917,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1720,6 +1932,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1786,6 +1999,8 @@
     "DownCommitteeSize": 10000,
     "DownCommitteeThreshold": 7750,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1801,7 +2016,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1813,6 +2031,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1879,6 +2098,8 @@
     "DownCommitteeSize": 5000,
     "DownCommitteeThreshold": 3838,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1894,7 +2115,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1906,6 +2130,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1972,6 +2197,8 @@
     "DownCommitteeSize": 5000,
     "DownCommitteeThreshold": 3838,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1987,7 +2214,10 @@
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1999,6 +2229,7 @@
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
diff --git a/types/protocols_json.go b/types/protocols_json.go
index e136875..fe668d0 100644
--- a/types/protocols_json.go
+++ b/types/protocols_json.go
@@ -25,6 +25,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": true,
+    "EnableKeyregCoherencyCheck": true,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -34,24 +36,28 @@ const protocols_json = `{
     "LateCommitteeThreshold": 320,
     "LogicSigMaxCost": 20000,
     "LogicSigMaxSize": 1000,
-    "LogicSigVersion": 3,
+    "LogicSigVersion": 4,
     "MaxAppArgs": 16,
-    "MaxAppBytesValueLen": 64,
+    "MaxAppBytesValueLen": 128,
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
-    "MaxAppProgramLen": 1024,
+    "MaxAppProgramLen": 2048,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
-    "MaxAppTxnForeignApps": 2,
-    "MaxAppTxnForeignAssets": 2,
+    "MaxAppTxnForeignApps": 8,
+    "MaxAppTxnForeignAssets": 8,
     "MaxAppsCreated": 10,
     "MaxAppsOptedIn": 10,
     "MaxAssetDecimals": 19,
     "MaxAssetNameBytes": 32,
-    "MaxAssetURLBytes": 32,
+    "MaxAssetURLBytes": 96,
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 3,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -118,6 +124,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -133,7 +141,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -145,6 +156,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -211,6 +223,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -226,7 +240,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -238,6 +255,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -304,6 +322,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -319,7 +339,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -331,6 +354,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -397,6 +421,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -412,7 +438,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -424,6 +453,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -490,6 +520,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -505,7 +537,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -517,6 +552,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -583,6 +619,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -598,7 +636,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -610,6 +651,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -676,6 +718,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -691,7 +735,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -703,6 +750,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -769,6 +817,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -784,7 +834,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -796,6 +849,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -862,6 +916,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -877,7 +933,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -889,6 +948,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -931,6 +991,103 @@ const protocols_json = `{
     "UpgradeThreshold": 9000,
     "UpgradeVoteRounds": 10000
   },
+  "https://github.com/algorandfoundation/specs/tree/65b4ab3266c52c56a0fa7d591754887d68faad0a": {
+    "AgreementFilterTimeout": 4000000000,
+    "AgreementFilterTimeoutPeriod0": 4000000000,
+    "AppFlatOptInMinBalance": 100000,
+    "AppFlatParamsMinBalance": 100000,
+    "Application": true,
+    "ApplyData": true,
+    "ApprovedUpgrades": {},
+    "Asset": true,
+    "CertCommitteeSize": 1500,
+    "CertCommitteeThreshold": 1112,
+    "CompactCertRounds": 0,
+    "CompactCertSecKQ": 0,
+    "CompactCertTopVoters": 0,
+    "CompactCertVotersLookback": 0,
+    "CompactCertWeightThreshold": 0,
+    "CredentialDomainSeparationEnabled": true,
+    "DefaultKeyDilution": 10000,
+    "DefaultUpgradeWaitRounds": 140000,
+    "DownCommitteeSize": 6000,
+    "DownCommitteeThreshold": 4560,
+    "EnableAssetCloseAmount": true,
+    "EnableFeePooling": true,
+    "EnableKeyregCoherencyCheck": true,
+    "FastPartitionRecovery": true,
+    "FastRecoveryLambda": 300000000000,
+    "FixTransactionLeases": true,
+    "ForceNonParticipatingFeeSink": true,
+    "InitialRewardsRateCalculation": true,
+    "LateCommitteeSize": 500,
+    "LateCommitteeThreshold": 320,
+    "LogicSigMaxCost": 20000,
+    "LogicSigMaxSize": 1000,
+    "LogicSigVersion": 4,
+    "MaxAppArgs": 16,
+    "MaxAppBytesValueLen": 128,
+    "MaxAppKeyLen": 64,
+    "MaxAppProgramCost": 700,
+    "MaxAppProgramLen": 2048,
+    "MaxAppSumKeyValueLens": 128,
+    "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
+    "MaxAppTxnAccounts": 4,
+    "MaxAppTxnForeignApps": 8,
+    "MaxAppTxnForeignAssets": 8,
+    "MaxAppsCreated": 10,
+    "MaxAppsOptedIn": 10,
+    "MaxAssetDecimals": 19,
+    "MaxAssetNameBytes": 32,
+    "MaxAssetURLBytes": 96,
+    "MaxAssetUnitNameBytes": 8,
+    "MaxAssetsPerAccount": 1000,
+    "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 3,
+    "MaxGlobalSchemaEntries": 64,
+    "MaxLocalSchemaEntries": 16,
+    "MaxTimestampIncrement": 25,
+    "MaxTxGroupSize": 16,
+    "MaxTxnBytesPerBlock": 1000000,
+    "MaxTxnLife": 1000,
+    "MaxTxnNoteBytes": 1024,
+    "MaxUpgradeWaitRounds": 150000,
+    "MaxVersionStringLen": 128,
+    "MaximumMinimumBalance": 100100000,
+    "MinBalance": 100000,
+    "MinTxnFee": 1000,
+    "MinUpgradeWaitRounds": 10000,
+    "NextCommitteeSize": 5000,
+    "NextCommitteeThreshold": 3838,
+    "NoEmptyLocalDeltas": true,
+    "NumProposers": 20,
+    "PaysetCommit": 2,
+    "PendingResidueRewards": true,
+    "RedoCommitteeSize": 2400,
+    "RedoCommitteeThreshold": 1768,
+    "RequireGenesisHash": true,
+    "RewardUnit": 1000000,
+    "RewardsInApplyData": true,
+    "RewardsRateRefreshInterval": 500000,
+    "SchemaBytesMinBalance": 25000,
+    "SchemaMinBalancePerEntry": 25000,
+    "SchemaUintMinBalance": 3500,
+    "SeedLookback": 2,
+    "SeedRefreshInterval": 80,
+    "SoftCommitteeSize": 2990,
+    "SoftCommitteeThreshold": 2267,
+    "SupportBecomeNonParticipatingTransactions": true,
+    "SupportGenesisHash": true,
+    "SupportRekeying": true,
+    "SupportSignedTxnInBlock": true,
+    "SupportTransactionLeases": true,
+    "SupportTxGroups": true,
+    "TxnCounter": true,
+    "UpgradeThreshold": 9000,
+    "UpgradeVoteRounds": 10000
+  },
   "https://github.com/algorandfoundation/specs/tree/6c6bd668be0ab14098e51b37e806c509f7b7e31f": {
     "AgreementFilterTimeout": 4000000000,
     "AgreementFilterTimeoutPeriod0": 4000000000,
@@ -955,6 +1112,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -970,7 +1129,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -982,6 +1144,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1048,6 +1211,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1063,7 +1228,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1075,6 +1243,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1141,6 +1310,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1156,7 +1327,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1168,6 +1342,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1234,6 +1409,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1249,7 +1426,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1261,6 +1441,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1310,7 +1491,9 @@ const protocols_json = `{
     "AppFlatParamsMinBalance": 100000,
     "Application": true,
     "ApplyData": true,
-    "ApprovedUpgrades": {},
+    "ApprovedUpgrades": {
+      "https://github.com/algorandfoundation/specs/tree/65b4ab3266c52c56a0fa7d591754887d68faad0a": 140000
+    },
     "Asset": true,
     "CertCommitteeSize": 1500,
     "CertCommitteeThreshold": 1112,
@@ -1325,6 +1508,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": true,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1340,7 +1525,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 64,
     "MaxAppProgramCost": 700,
     "MaxAppProgramLen": 1024,
+    "MaxAppSumKeyValueLens": 128,
     "MaxAppTotalArgLen": 2048,
+    "MaxAppTotalProgramLen": 2048,
+    "MaxAppTotalTxnReferences": 8,
     "MaxAppTxnAccounts": 4,
     "MaxAppTxnForeignApps": 2,
     "MaxAppTxnForeignAssets": 2,
@@ -1352,6 +1540,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 64,
     "MaxLocalSchemaEntries": 16,
     "MaxTimestampIncrement": 25,
@@ -1418,6 +1607,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": true,
@@ -1433,7 +1624,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1445,6 +1639,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 8,
     "MaxAssetsPerAccount": 1000,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1511,6 +1706,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1526,7 +1723,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1538,6 +1738,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1604,6 +1805,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1619,7 +1822,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1631,6 +1837,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1697,6 +1904,8 @@ const protocols_json = `{
     "DownCommitteeSize": 6000,
     "DownCommitteeThreshold": 4560,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": true,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1712,7 +1921,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1724,6 +1936,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1790,6 +2003,8 @@ const protocols_json = `{
     "DownCommitteeSize": 10000,
     "DownCommitteeThreshold": 7750,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1805,7 +2020,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1817,6 +2035,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1883,6 +2102,8 @@ const protocols_json = `{
     "DownCommitteeSize": 5000,
     "DownCommitteeThreshold": 3838,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1898,7 +2119,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -1910,6 +2134,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
@@ -1976,6 +2201,8 @@ const protocols_json = `{
     "DownCommitteeSize": 5000,
     "DownCommitteeThreshold": 3838,
     "EnableAssetCloseAmount": false,
+    "EnableFeePooling": false,
+    "EnableKeyregCoherencyCheck": false,
     "FastPartitionRecovery": false,
     "FastRecoveryLambda": 300000000000,
     "FixTransactionLeases": false,
@@ -1991,7 +2218,10 @@ const protocols_json = `{
     "MaxAppKeyLen": 0,
     "MaxAppProgramCost": 0,
     "MaxAppProgramLen": 0,
+    "MaxAppSumKeyValueLens": 0,
     "MaxAppTotalArgLen": 0,
+    "MaxAppTotalProgramLen": 0,
+    "MaxAppTotalTxnReferences": 0,
     "MaxAppTxnAccounts": 0,
     "MaxAppTxnForeignApps": 0,
     "MaxAppTxnForeignAssets": 0,
@@ -2003,6 +2233,7 @@ const protocols_json = `{
     "MaxAssetUnitNameBytes": 0,
     "MaxAssetsPerAccount": 0,
     "MaxBalLookback": 320,
+    "MaxExtraAppProgramPages": 0,
     "MaxGlobalSchemaEntries": 0,
     "MaxLocalSchemaEntries": 0,
     "MaxTimestampIncrement": 25,
diff --git a/types/types.go b/types/types.go
index c6b24db..9e9d9c6 100644
--- a/types/types.go
+++ b/types/types.go
@@ -588,7 +588,7 @@ type ConsensusParams struct {
 	// DefaultKeyDilution specifies the granularity of top-level ephemeral
 	// keys. KeyDilution is the number of second-level keys in each batch,
 	// signed by a top-level "batch" key.  The default value can be
-	// overriden in the account state.
+	// overridden in the account state.
 	DefaultKeyDilution uint64
 
 	// MinBalance specifies the minimum balance that can appear in
@@ -602,6 +602,11 @@ type ConsensusParams struct {
 	// a way of making the spender subsidize the cost of storing this transaction.
 	MinTxnFee uint64
 
+	// EnableFeePooling specifies that the sum of the fees in a
+	// group must exceed one MinTxnFee per Txn, rather than check that
+	// each Txn has a MinFee.
+	EnableFeePooling bool
+
 	// RewardUnit specifies the number of MicroAlgos corresponding to one reward
 	// unit.
 	//
@@ -644,10 +649,6 @@ type ConsensusParams struct {
 	FastRecoveryLambda    time.Duration // time between fast recovery attempts
 	FastPartitionRecovery bool          // set when fast partition recovery is enabled
 
-	// commit to payset using a hash of entire payset,
-	// instead of txid merkle tree
-	PaysetCommitFlat bool
-
 	// how to commit to the payset: flat or merkle tree
 	PaysetCommit PaysetCommitType
 
@@ -718,10 +719,6 @@ type ConsensusParams struct {
 	// max decimal precision for assets
 	MaxAssetDecimals uint32
 
-	// whether to use the old buggy Credential.lowestOutput function
-	// TODO(upgrade): Please remove as soon as the upgrade goes through
-	UseBuggyProposalLowestOutput bool
-
 	// SupportRekeying indicates support for account rekeying (the RekeyTo and AuthAddr fields)
 	SupportRekeying bool
 
@@ -734,10 +731,19 @@ type ConsensusParams struct {
 	// max sum([len(arg) for arg in txn.ApplicationArgs])
 	MaxAppTotalArgLen int
 
-	// maximum length of application approval program or clear state
-	// program in bytes
+	// maximum byte len of application approval program or clear state
+	// When MaxExtraAppProgramPages > 0, this is the size of those pages.
+	// So two "extra pages" would mean 3*MaxAppProgramLen bytes are available.
 	MaxAppProgramLen int
 
+	// maximum total length of an application's programs (approval + clear state)
+	// When MaxExtraAppProgramPages > 0, this is the size of those pages.
+	// So two "extra pages" would mean 3*MaxAppTotalProgramLen bytes are available.
+	MaxAppTotalProgramLen int
+
+	// extra length for application program in pages. A page is MaxAppProgramLen bytes
+	MaxExtraAppProgramPages int
+
 	// maximum number of accounts in the ApplicationCall Accounts field.
 	// this determines, in part, the maximum number of balance records
 	// accessed by a single transaction
@@ -753,6 +759,10 @@ type ConsensusParams struct {
 	// be read in the transaction
 	MaxAppTxnForeignAssets int
 
+	// maximum number of "foreign references" (accounts, asa, app)
+	// that can be attached to a single app call.
+	MaxAppTotalTxnReferences int
+
 	// maximum cost of application approval program or clear state program
 	MaxAppProgramCost int
 
@@ -764,6 +774,9 @@ type ConsensusParams struct {
 	// local key/value store
 	MaxAppBytesValueLen int
 
+	// maximum sum of the lengths of the key and value of one app state entry
+	MaxAppSumKeyValueLens int
+
 	// maximum number of applications a single account can create and store
 	// AppParams for at once
 	MaxAppsCreated int
@@ -853,11 +866,20 @@ type ConsensusParams struct {
 	// asset that were sent to the close-to address.
 	EnableAssetCloseAmount bool
 
-	// InitialRewardsRateCalculation update the initial rewards rate calculation to take the reward pool minimum balance into account
+	// update the initial rewards rate calculation to take the reward pool minimum balance into account
 	InitialRewardsRateCalculation bool
 
 	// NoEmptyLocalDeltas updates how ApplyDelta.EvalDelta.LocalDeltas are stored
 	NoEmptyLocalDeltas bool
+
+	// EnableKeyregCoherencyCheck enable the following extra checks on key registration transactions:
+	// 1. checking that [VotePK/SelectionPK/VoteKeyDilution] are all set or all clear.
+	// 2. checking that the VoteFirst is less or equal to VoteLast.
+	// 3. checking that in the case of going offline, both the VoteFirst and VoteLast are clear.
+	// 4. checking that in the case of going online the VoteLast is non-zero and greater then the current network round.
+	// 5. checking that in the case of going online the VoteFirst is less or equal to the LastValid+1.
+	// 6. checking that in the case of going online the VoteFirst is less or equal to the next network round.
+	EnableKeyregCoherencyCheck bool
 }
 
 // PaysetCommitType enumerates possible ways for the block header to commit to


Test patch:
diff --git a/cmd/block-generator/generator/generate_test.go b/cmd/block-generator/generator/generate_test.go
index 8c799b9..98fe8cc 100644
--- a/cmd/block-generator/generator/generate_test.go
+++ b/cmd/block-generator/generator/generate_test.go
@@ -87,7 +87,7 @@ func TestAssetOptinEveryAccountOverride(t *testing.T) {
 
 	// Opt all the accounts in, this also verifies that no account is opted in twice
 	var txn sdk_types.Transaction
-	var actual txTypeID
+	var actual TxTypeID
 	for i := 2; uint64(i) <= g.numAccounts; i++ {
 		actual, txn = g.generateAssetTxnInternal(assetOptin, sp, 0)
 		require.Equal(t, assetOptin, actual)
diff --git a/idb/postgres/postgres_integration_test.go b/idb/postgres/postgres_integration_test.go
index 597a42d..157eb1b 100644
--- a/idb/postgres/postgres_integration_test.go
+++ b/idb/postgres/postgres_integration_test.go
@@ -15,6 +15,7 @@ import (
 	sdk_types "github.com/algorand/go-algorand-sdk/types"
 
 	"github.com/algorand/indexer/accounting"
+	"github.com/algorand/indexer/api/generated/v2"
 	"github.com/algorand/indexer/idb"
 	"github.com/algorand/indexer/idb/postgres/internal/encoding"
 	"github.com/algorand/indexer/importer"
@@ -890,3 +891,89 @@ func TestAssetFreezeTxnParticipation(t *testing.T) {
 	assert.Equal(t, 1, acctACount)
 	assert.Equal(t, 1, acctBCount)
 }
+
+func TestAppExtraPages(t *testing.T) {
+	db, shutdownFunc := setupIdb(t, test.MakeGenesis())
+	defer shutdownFunc()
+
+	cache, err := db.GetDefaultFrozen()
+	require.NoError(t, err)
+
+	assetID := uint64(3)
+
+	state := getAccounting(test.Round, cache)
+
+	// Create an app.
+	{
+		// Create a transaction with ExtraProgramPages field set to 1
+		txn := sdk_types.SignedTxnWithAD{
+			SignedTxn: sdk_types.SignedTxn{
+				Txn: sdk_types.Transaction{
+					Type: "appl",
+					Header: sdk_types.Header{
+						Sender: test.AccountA,
+					},
+					ApplicationFields: sdk_types.ApplicationFields{
+						ApplicationCallTxnFields: sdk_types.ApplicationCallTxnFields{
+							ApprovalProgram:   []byte{0x02, 0x20, 0x01, 0x01, 0x22},
+							ClearStateProgram: []byte{0x02, 0x20, 0x01, 0x01, 0x22},
+							ExtraProgramPages: 1,
+						},
+					},
+				},
+			},
+		}
+		txnRow := idb.TxnRow{
+			Round:    uint64(test.Round),
+			TxnBytes: msgpack.Encode(txn),
+			AssetID:  assetID,
+		}
+
+		err := state.AddTransaction(&txnRow)
+		require.NoError(t, err)
+
+		block := test.MakeBlockForTxns(test.Round, &txn)
+		blockImporter := importer.NewDBImporter(db)
+		txnCount, err := blockImporter.ImportDecodedBlock(&block)
+		require.NoError(t, err, "failed to import")
+		require.Equal(t, 1, txnCount)
+	}
+
+	err = db.CommitRoundAccounting(state.RoundUpdates, test.Round, &types.BlockHeader{})
+	require.NoError(t, err, "failed to commit")
+
+	row := db.db.QueryRow("SELECT index, params FROM app WHERE creator = $1", test.AccountA[:])
+
+	var index uint64
+	var paramsStr []byte
+	err = row.Scan(&index, &paramsStr)
+	require.NoError(t, err)
+	require.NotZero(t, index)
+
+	var ap AppParams
+	err = encoding.DecodeJSON(paramsStr, &ap)
+	require.Equal(t, uint32(1), ap.ExtraProgramPages)
+
+	var filter generated.SearchForApplicationsParams
+	var aidx uint64 = uint64(index)
+	filter.ApplicationId = &aidx
+	appRows, _ := db.Applications(context.Background(), &filter)
+	num := 0
+	for row := range appRows {
+		require.NoError(t, row.Error)
+		num++
+		require.NotNil(t, row.Application.Params.ExtraProgramPages, "we should have this field")
+		require.Equal(t, uint64(1), *row.Application.Params.ExtraProgramPages)
+	}
+	require.Equal(t, 1, num)
+
+	rows, _ := db.GetAccounts(context.Background(), idb.AccountQueryOptions{EqualToAddress: test.AccountA[:]})
+	num = 0
+	for row := range rows {
+		require.NoError(t, row.Error)
+		num++
+		require.NotNil(t, row.Account.AppsTotalExtraPages, "we should have this field")
+		require.Equal(t, uint64(1), *row.Account.AppsTotalExtraPages)
+	}
+	require.Equal(t, 1, num)
+}
diff --git a/misc/buildtestdata.sh b/misc/buildtestdata.sh
index ff8b635..9238bc4 100755
--- a/misc/buildtestdata.sh
+++ b/misc/buildtestdata.sh
@@ -9,16 +9,16 @@
 #
 # usage:
 #    #!/usr/bin/env bash
-#    rm -rf ve3    
-#    export GOALGORAND="${GOPATH}/src/github.com/algorand/go-algorand"    
-#    export E2EDATA="${HOME}/algorand/indexer/e2edata"    
-#    export BUILD_BLOCK_ARCHIVE="yes please"    
-#    rm -rf "$E2EDATA"    
-#    mkdir -p "$E2EDATA"    
-#    python3 -m venv ve3    
-#    ve3/bin/pip install py-algorand-sdk    
-#    . ve3/bin/activate    
-#    ./misc/buildtestdata.sh    
+#    rm -rf ve3
+#    export GOALGORAND="${GOPATH}/src/github.com/algorand/go-algorand"
+#    export E2EDATA="${HOME}/algorand/indexer/e2edata"
+#    export BUILD_BLOCK_ARCHIVE="yes please"
+#    rm -rf "$E2EDATA"
+#    mkdir -p "$E2EDATA"
+#    python3 -m venv ve3
+#    ve3/bin/pip install py-algorand-sdk
+#    . ve3/bin/activate
+#    ./misc/buildtestdata.sh
 
 set -x
 set -e
@@ -39,7 +39,7 @@ export ALGOSMALLLAMBDAMSEC=1000
 
 rm -rf "${E2EDATA}"
 mkdir -p "${E2EDATA}"
-(cd "${GOALGORAND}/test/scripts" && TEMPDIR="${E2EDATA}" python3 e2e_client_runner.py --keep-temps e2e_subs/*.sh)
+(cd "${GOALGORAND}" && TEMPDIR="${E2EDATA}" python3 test/scripts/e2e_client_runner.py --keep-temps test/scripts/e2e_subs/*.sh)
 
 (cd "${E2EDATA}" && tar -j -c -f net_done.tar.bz2 --exclude node.log --exclude agreement.cdv net)
 
diff --git a/test/common.sh b/test/common.sh
index 27c8ca4..db2459a 100755
--- a/test/common.sh
+++ b/test/common.sh
@@ -451,6 +451,15 @@ function create_delete_tests() {
       true \
       '"id": 82'
 
+    rest_test "[rest - account/application] account with application" \
+      "/v2/accounts/D2BFTG5GO2PUCLY2O4XIVW7WAQHON4DLX5R5V4O3MZWSWDKBNYZJYKHVBQ?pretty" \
+      200 \
+      true \
+      '"apps-total-schema": {
+      "num-byte-slice": 1,
+      "num-uint": 1
+    }'
+
     ###############
     # Asset Tests #
     ###############