Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

services/horizon, clients/horizonclient: Allow filtering ingested transactions by account or asset. #4277

Merged
merged 119 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from 114 commits
Commits
Show all changes
119 commits
Select commit Hold shift + click to select a range
cd48ff0
#4222: ported filtering-poc and started real asset filter feature dev
sreuland Feb 22, 2022
8ee5308
Hide ingestion filtering behind a commandline flag
2opremio Feb 22, 2022
01d11c2
Add account filtering support
2opremio Feb 22, 2022
3e345ba
#4222: common GET/SET handler, resource model, and URL paths for filt…
sreuland Feb 24, 2022
b2deb81
#4222: cleaned up URL paths for CRUD on filter configs
sreuland Feb 24, 2022
410876e
#4222: refactored filter list acquistion into filters package
sreuland Feb 25, 2022
0151a47
#4222: changed filter cache name
sreuland Feb 25, 2022
6978425
#4222: removed singleton pattern of filters
sreuland Feb 25, 2022
b2370fc
#4222: cleanup go fmt
sreuland Feb 25, 2022
68a450a
#4222: backfilling tests on filters
sreuland Feb 26, 2022
06d9c8a
#4222: fixed json string to postgres conversion
sreuland Feb 28, 2022
46ccadf
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland Feb 28, 2022
0c5b57b
#4222: back filling tests on filter config web action handlers
sreuland Mar 1, 2022
eea2ae6
#4222: refactor filer config CRUD interface, removed create/del, not …
sreuland Mar 2, 2022
f5a092d
#4222: fix filters internal expired cache state rollover setting
sreuland Mar 3, 2022
580e59c
#4221: added account filter tests
sreuland Mar 4, 2022
9f47343
#4222: added unit test coverage on filters-as-service
sreuland Mar 7, 2022
19928ff
#4222: added filtering log statement
sreuland Mar 7, 2022
cef3622
#4222: added filtering log statement correction
sreuland Mar 7, 2022
b31edb5
Merge branch 'master' into filtering-feature
2opremio Mar 8, 2022
bf664c3
Fix whitespace
2opremio Mar 8, 2022
0df128b
#4222: removed pointer usage on filter resource
sreuland Mar 9, 2022
9c6044d
Add filtering endpoint support to horizon the client
2opremio Mar 8, 2022
8709b45
Start creating an integration test
2opremio Mar 11, 2022
c193a4d
#4222: refactored filter config model from json into typed schema in …
sreuland Mar 12, 2022
6c7b850
#4222: added admin api docs in api blueprint format, include new filt…
sreuland Mar 12, 2022
cf8c9bc
#4222: switched to openapi3 format for admin api doc
sreuland Mar 13, 2022
86ea48c
#4222: added changelog entry for filters features
sreuland Mar 14, 2022
b2a40d8
#4222: updated admin api docs, examples
sreuland Mar 14, 2022
f6aa1e5
#4222: updated changelog for filter feature
sreuland Mar 14, 2022
99f811e
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland Mar 14, 2022
2050a1a
Continue with the integration test
2opremio Mar 14, 2022
30dbd20
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland Apr 18, 2022
3353d76
Add txsub_result table
2opremio Apr 18, 2022
68ea3f9
Serialize the full transaction, not just the result
2opremio Apr 19, 2022
644883c
Initialize, get and cleanup submission results
2opremio Apr 19, 2022
02c5008
Set the transaction submission result during ingestion
2opremio Apr 19, 2022
af9f5fc
Implement mocks by pointer
2opremio Apr 19, 2022
7bbb7d5
Appease go vet
2opremio Apr 19, 2022
5167127
Remove useles tests and adjust base scenario
2opremio Apr 19, 2022
a7c0c43
Remove unused code
2opremio Apr 19, 2022
9d94a82
Appease go vet
2opremio Apr 19, 2022
cbd44a0
Fix failed tx scenario
2opremio Apr 19, 2022
beeb78f
Allow writing to db in order to clean up old entries
2opremio Apr 19, 2022
22dc6b1
Rename DB methods to make then easier to understand
2opremio Apr 19, 2022
d5785d2
Restore rollback method
2opremio Apr 19, 2022
3e42f42
Merge branch 'master' into filtering-feature
2opremio Apr 19, 2022
be6589f
Fix merge conflicts
2opremio Apr 19, 2022
4f306d0
Fix broken test
2opremio Apr 19, 2022
25cdf87
#4222: perform commits on unfiltered processor in all cases
sreuland Apr 20, 2022
b921a76
Fix txsub tests
2opremio Apr 20, 2022
be743ee
Add performance TODO
2opremio Apr 20, 2022
1162fe3
Fix base scenario again
2opremio Apr 20, 2022
d01d591
MOre base scenario fixes
2opremio Apr 20, 2022
c82ae03
And yet some more base scenario fixes
2opremio Apr 20, 2022
cec1091
Regenerate base scenario
2opremio Apr 20, 2022
95fda79
Fixed failed transactions scenario
2opremio Apr 20, 2022
f22e88d
Fix all unit tests except for feebump transactions
2opremio Apr 20, 2022
f1b45c6
minor refactoring
2opremio Apr 20, 2022
794f8ac
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland Apr 20, 2022
e64390e
Add another TODO
2opremio Apr 20, 2022
06fcdcd
#4222: make txsub results init idempotent whether row for tx hash exi…
sreuland Apr 20, 2022
b6be43e
Merge remote-tracking branch 'upstream/filtering-feature' into filter…
sreuland Apr 20, 2022
231ccfe
#4222: remove a TODO for init tx result
sreuland Apr 20, 2022
c6f99f5
Add inner transaction column to txsub_results
2opremio Apr 20, 2022
f7f504c
Forgot to pass the inner hash to the mock
2opremio Apr 20, 2022
c153946
Fix TestInitIdempotent
2opremio Apr 20, 2022
bb7a6b3
#4222: fixed unit tests for mocked InitEmptyTxSubmissionResult
sreuland Apr 20, 2022
c8742be
Merge remote-tracking branch 'origin/master' into filtering-feature
2opremio Apr 21, 2022
6741c72
Resolve merge conflic
2opremio Apr 21, 2022
bc5cb5e
Return the affected rows by SetTxSubmissionResult()
2opremio Apr 21, 2022
5d94ffb
Remove fixed TODO
2opremio Apr 21, 2022
77e8ef6
Modify SetTxSubmissionResult() so that it takes multiple transactions…
2opremio Apr 21, 2022
43264d5
Clarify TODO
2opremio Apr 21, 2022
f8aeef2
Implement batching for SetTxSubmissionResults
2opremio Apr 21, 2022
7cce799
Correct documentation comments
2opremio Apr 21, 2022
17538dc
#4222: separate integration test cases for asset and account whitelist
sreuland Apr 21, 2022
1a3cb42
Only cleanup old submission results every TTL period
2opremio Apr 21, 2022
32aaa4d
Remove superflous TODO
2opremio Apr 21, 2022
3b2b381
Remove another fixed TODO
2opremio Apr 21, 2022
8ea43c0
Remove yet another TODO
2opremio Apr 21, 2022
ffb8ce1
#4222: added metrics 'name=horizon_ingest_ledger_stats_total, type=le…
sreuland Apr 22, 2022
6778bf9
#4222: added metrics 'name=horizon_ingest_processor_run_duration_seco…
sreuland Apr 22, 2022
ba5a684
Revert "#4222: added metrics 'name=horizon_ingest_processor_run_durat…
2opremio Apr 22, 2022
5c3ad55
Get metrics for TxSubmissionResultProcessor and only run it if not re…
2opremio Apr 22, 2022
90a3352
#4222: refactored Admin* Cliet methods into admin client struct/inte…
sreuland Apr 26, 2022
ae706fa
#4222: minor code cleanup per PR feedback
sreuland Apr 26, 2022
565e1aa
#4222: use utility method NewProblemWithInvalidField for common err f…
sreuland Apr 26, 2022
bd1a459
#4222: rerun go formatting, missed one file
sreuland Apr 26, 2022
7843998
#4222: remove superflous TODOs
sreuland Apr 28, 2022
b37dc44
#4222: added history tx lookup back in to txsub tick routing, for las…
sreuland Apr 28, 2022
d476a4e
#4222: removed asset filter inspection of claimablebalance claim/claw…
sreuland Apr 28, 2022
b693b95
#4222: add host/port override for admin client
sreuland Apr 29, 2022
045f34b
fixed typo
sreuland Apr 29, 2022
0a79fd0
#4222: cleaned up creation of problem for sql NotFound
sreuland Apr 29, 2022
54ddeac
#4222: fixed err checking in get tx results loop, increased test cove…
sreuland Apr 29, 2022
058d0ee
streamlined matching/boolean code
sreuland Apr 29, 2022
05e7211
#4222: incorporate pr feedback on code, remove todo
sreuland Apr 29, 2022
065aae3
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland Apr 29, 2022
0b86858
#4222: fixed unit test failure and static check on duration
sreuland Apr 30, 2022
92121f3
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland May 3, 2022
4015550
#4222: refactored into NewAdminClient pattern, pr feedback
sreuland May 4, 2022
0578799
Update typos in changelog
sreuland May 4, 2022
2b1e53b
#4222: removed clock from admin client
sreuland May 4, 2022
3d89915
Update inline code docs for typo
sreuland May 4, 2022
5e8a912
#4222: refactored admin client method names to not be redundant
sreuland May 5, 2022
a14bc78
Merge remote-tracking branch 'upstream/filtering-feature' into filter…
sreuland May 5, 2022
0ae77dc
#4222: removed unnecessary check on duplicate txsub results
sreuland May 5, 2022
e80e5f3
#4222: added inline docs on setTxSubmissionResults
sreuland May 6, 2022
6491458
#4222: cleanup go formatting error
sreuland May 6, 2022
e36549b
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland May 6, 2022
2a0a1bc
#4222: added inline docs on admin http endpoint handlers for referenc…
sreuland May 6, 2022
7b77d7b
#4222: include V0 transactions in asset filter
sreuland May 6, 2022
65405b9
#4222: define length of map at declaration on asset filter
sreuland May 6, 2022
4541374
#4222: set ingestion filter feature flag to default of false
sreuland May 9, 2022
b390c9b
#4222: added info log output for filtered tx drops
sreuland May 9, 2022
29822d4
Merge remote-tracking branch 'upstream/master' into filtering-feature
sreuland May 9, 2022
d59cf46
#4222: changed log output for tx dropped statement to show hex string…
sreuland May 9, 2022
0a78183
Merge branch 'master' into filtering-feature
2opremio May 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions clients/horizonclient/admin_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package horizonclient

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"

hProtocol "github.com/stellar/go/protocols/horizon"
"github.com/stellar/go/support/errors"
)

// port - the horizon admin port, zero value defaults to 4200
// host - the host interface name that horizon has bound admin web service, zero value defaults to 'localhost'
// timeout - the length of time for the http client to wait on responses from admin web service
func NewAdminClient(port uint16, host string, timeout time.Duration) (*AdminClient, error) {
baseURL, err := getAdminBaseURL(port, host)
if err != nil {
return nil, err
}
if timeout == 0 {
timeout = HorizonTimeout
}

return &AdminClient{
baseURL: baseURL,
http: http.DefaultClient,
horizonTimeout: timeout,
}, nil
}

func getAdminBaseURL(port uint16, host string) (string, error) {
baseURL, err := url.Parse("http://localhost")
if err != nil {
return "", err
}
adminPort := uint16(4200)
if port > 0 {
adminPort = port
}
adminHost := baseURL.Hostname()
if len(host) > 0 {
adminHost = host
}
baseURL.Host = fmt.Sprintf("%s:%d", adminHost, adminPort)
return baseURL.String(), nil
}

func (c *AdminClient) sendGetRequest(requestURL string, a interface{}) error {
req, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return errors.Wrap(err, "error creating Admin HTTP request")
}
return c.sendHTTPRequest(req, a)
}

func (c *AdminClient) sendHTTPRequest(req *http.Request, a interface{}) error {
ctx, cancel := context.WithTimeout(context.Background(), c.horizonTimeout)
defer cancel()

if resp, err := c.http.Do(req.WithContext(ctx)); err != nil {
return err
} else {
return decodeResponse(resp, a, req.URL.String(), nil)
}
}

func (c *AdminClient) getIngestionFiltersURL(filter string) string {
return fmt.Sprintf("%s/ingestion/filters/%s", c.baseURL, filter)
}

func (c *AdminClient) GetIngestionAssetFilter() (hProtocol.AssetFilterConfig, error) {
var filter hProtocol.AssetFilterConfig
err := c.sendGetRequest(c.getIngestionFiltersURL("asset"), &filter)
return filter, err
}

func (c *AdminClient) GetIngestionAccountFilter() (hProtocol.AccountFilterConfig, error) {
var filter hProtocol.AccountFilterConfig
err := c.sendGetRequest(c.getIngestionFiltersURL("account"), &filter)
return filter, err
}

func (c *AdminClient) SetIngestionAssetFilter(filter hProtocol.AssetFilterConfig) error {
buf := bytes.NewBuffer(nil)
err := json.NewEncoder(buf).Encode(filter)
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPut, c.getIngestionFiltersURL("asset"), buf)
if err != nil {
return errors.Wrap(err, "error creating HTTP request")
}
req.Header.Add("Content-Type", "application/json")
return c.sendHTTPRequest(req, nil)
}

func (c *AdminClient) SetIngestionAccountFilter(filter hProtocol.AccountFilterConfig) error {
buf := bytes.NewBuffer(nil)
err := json.NewEncoder(buf).Encode(filter)
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPut, c.getIngestionFiltersURL("account"), buf)
if err != nil {
return errors.Wrap(err, "error creating HTTP request")
}
req.Header.Add("Content-Type", "application/json")
return c.sendHTTPRequest(req, nil)
}

// ensure that the horizon admin client implements AdminClientInterface
var _ AdminClientInterface = &AdminClient{}
24 changes: 24 additions & 0 deletions clients/horizonclient/admin_client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package horizonclient

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestDefaultAdminHostPort(t *testing.T) {
horizonAdminClient, err := NewAdminClient(0, "", 0)

fullAdminURL := horizonAdminClient.getIngestionFiltersURL("test")
require.NoError(t, err)
assert.Equal(t, "http://localhost:4200/ingestion/filters/test", fullAdminURL)
}

func TestOverrideAdminHostPort(t *testing.T) {
horizonAdminClient, err := NewAdminClient(1234, "127.0.0.1", 0)

fullAdminURL := horizonAdminClient.getIngestionFiltersURL("test")
require.NoError(t, err)
assert.Equal(t, "http://127.0.0.1:1234/ingestion/filters/test", fullAdminURL)
}
5 changes: 4 additions & 1 deletion clients/horizonclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func (c *Client) sendHTTPRequest(req *http.Request, a interface{}) error {
if resp, err := c.HTTP.Do(req.WithContext(ctx)); err != nil {
return err
} else {
return decodeResponse(resp, &a, c)
return decodeResponse(resp, a, c.HorizonURL, c.clock)
}
}

Expand Down Expand Up @@ -270,6 +270,9 @@ func (c *Client) setDefaultClient() {
// fixHorizonURL strips all slashes(/) at the end of HorizonURL if any, then adds a single slash
func (c *Client) fixHorizonURL() string {
c.fixHorizonURLOnce.Do(func() {
// TODO: we shouldn't happily edit data provided by the user,
sreuland marked this conversation as resolved.
Show resolved Hide resolved
// better store it in an internal variable or, even better,
// just parse it every time (what if the url changes during the life of the client?).
c.HorizonURL = strings.TrimRight(c.HorizonURL, "/") + "/"
})
return c.HorizonURL
Expand Down
18 changes: 11 additions & 7 deletions clients/horizonclient/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ import (
"strings"
"time"

"github.com/stellar/go/support/clock"
"github.com/stellar/go/support/errors"
)

// decodeResponse decodes the response from a request to a horizon server
func decodeResponse(resp *http.Response, object interface{}, hc *Client) (err error) {
func decodeResponse(resp *http.Response, object interface{}, horizonUrl string, clock *clock.Clock) (err error) {
defer resp.Body.Close()
if object == nil {
// Nothing to decode
return nil
}
decoder := json.NewDecoder(resp.Body)

u, err := url.Parse(hc.HorizonURL)
u, err := url.Parse(horizonUrl)
if err != nil {
return errors.Errorf("unable to parse the provided horizon url: %s", hc.HorizonURL)
return errors.Errorf("unable to parse the provided horizon url: %s", horizonUrl)
}
setCurrentServerTime(u.Hostname(), resp.Header["Date"], hc)
setCurrentServerTime(u.Hostname(), resp.Header["Date"], clock)

if !(resp.StatusCode >= 200 && resp.StatusCode < 300) {
horizonError := &Error{
Expand All @@ -32,7 +37,6 @@ func decodeResponse(resp *http.Response, object interface{}, hc *Client) (err er
}
return horizonError
}

err = decoder.Decode(&object)
if err != nil {
return errors.Wrap(err, "error decoding response")
Expand Down Expand Up @@ -120,7 +124,7 @@ func addQueryParams(params ...interface{}) string {
}

// setCurrentServerTime saves the current time returned by a horizon server
func setCurrentServerTime(host string, serverDate []string, hc *Client) {
func setCurrentServerTime(host string, serverDate []string, clock *clock.Clock) {
if len(serverDate) == 0 {
return
}
Expand All @@ -129,7 +133,7 @@ func setCurrentServerTime(host string, serverDate []string, hc *Client) {
return
}
serverTimeMapMutex.Lock()
ServerTimeMap[host] = ServerTimeRecord{ServerTime: st.UTC().Unix(), LocalTimeRecorded: hc.clock.Now().UTC().Unix()}
ServerTimeMap[host] = ServerTimeRecord{ServerTime: st.UTC().Unix(), LocalTimeRecorded: clock.Now().UTC().Unix()}
serverTimeMapMutex.Unlock()
}

Expand Down
18 changes: 18 additions & 0 deletions clients/horizonclient/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,29 @@ type Client struct {
clock *clock.Clock
}

type AdminClient struct {
// fully qualified url for the admin web service
baseURL string

// HTTP client to make requests with
http HTTP

// max client wait time for response
horizonTimeout time.Duration
}

// SubmitTxOpts represents the submit transaction options
type SubmitTxOpts struct {
SkipMemoRequiredCheck bool
}

type AdminClientInterface interface {
GetIngestionAccountFilter() (hProtocol.AccountFilterConfig, error)
GetIngestionAssetFilter() (hProtocol.AssetFilterConfig, error)
SetIngestionAccountFilter(hProtocol.AccountFilterConfig) error
SetIngestionAssetFilter(hProtocol.AssetFilterConfig) error
}

// ClientInterface contains methods implemented by the horizon client
type ClientInterface interface {
Accounts(request AccountsRequest) (hProtocol.AccountsPage, error)
Expand Down
27 changes: 27 additions & 0 deletions clients/horizonclient/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ type MockClient struct {
mock.Mock
}

type MockAdminClient struct {
mock.Mock
}

// Accounts is a mocking method
func (m *MockClient) Accounts(request AccountsRequest) (hProtocol.AccountsPage, error) {
a := m.Called(request)
Expand Down Expand Up @@ -349,5 +353,28 @@ func (m *MockClient) PrevLiquidityPoolsPage(page hProtocol.LiquidityPoolsPage) (
return a.Get(0).(hProtocol.LiquidityPoolsPage), a.Error(1)
}

func (m *MockAdminClient) GetIngestionAccountFilter() (hProtocol.AccountFilterConfig, error) {
a := m.Called()
return a.Get(0).(hProtocol.AccountFilterConfig), a.Error(1)
}

func (m *MockAdminClient) GetIngestionAssetFilter() (hProtocol.AssetFilterConfig, error) {
a := m.Called()
return a.Get(0).(hProtocol.AssetFilterConfig), a.Error(1)
}

func (m *MockAdminClient) SetIngestionAccountFilter(resource hProtocol.AccountFilterConfig) error {
a := m.Called(resource)
return a.Error(0)
}

func (m *MockAdminClient) SetIngestionAssetFilter(resource hProtocol.AssetFilterConfig) error {
a := m.Called(resource)
return a.Error(0)
}

// ensure that the MockClient implements ClientInterface
var _ ClientInterface = &MockClient{}

// ensure that the MockClient implements ClientInterface
var _ AdminClientInterface = &MockAdminClient{}
52 changes: 52 additions & 0 deletions protocols/horizon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,3 +843,55 @@ type LiquidityPoolReserve struct {
Asset string `json:"asset"`
Amount string `json:"amount"`
}

type AssetFilterConfig struct {
Whitelist []string `json:"whitelist"`
Enabled *bool `json:"enabled"`
sreuland marked this conversation as resolved.
Show resolved Hide resolved
LastModified int64 `json:"last_modified,omitempty"`
}

type AccountFilterConfig struct {
Whitelist []string `json:"whitelist"`
Enabled *bool `json:"enabled"`
LastModified int64 `json:"last_modified,omitempty"`
}

func (f *AccountFilterConfig) UnmarshalJSON(data []byte) error {
type accountFilterConfig AccountFilterConfig
var config = accountFilterConfig{}

if err := json.Unmarshal(data, &config); err != nil {
return err
}

if config.Whitelist == nil {
return errors.New("missing required whitelist")
}

if config.Enabled == nil {
return errors.New("missing required enabled")
}
sreuland marked this conversation as resolved.
Show resolved Hide resolved

*f = AccountFilterConfig(config)
return nil
}

func (f *AssetFilterConfig) UnmarshalJSON(data []byte) error {
type assetFilterConfig AssetFilterConfig
var config = assetFilterConfig{}

if err := json.Unmarshal(data, &config); err != nil {
return err
}

if config.Whitelist == nil {
return errors.New("missing required whitelist")
}

if config.Enabled == nil {
return errors.New("missing required enabled")
}

*f = AssetFilterConfig(config)
return nil
}
13 changes: 13 additions & 0 deletions services/horizon/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ This is the final release after the [release candidate](v2.17.0-release-candidat

- Timebounds within the `preconditions` object are strings containing int64 UNIX timestamps in seconds rather than formatted date-times (which was a bug) ([4361](https://github.com/stellar/go/pull/4361)).

* New Ingestion Filters Feature: Provide the ability to select which ledger transactions are accepted at ingestion time to be stored on horizon's historical databse.

Define filter rules through Admin API and the historical ingestion process will check the rules and only persist the ledger transactions that pass the filter rules. Initially, two filters and corresponding rules are possible:

* 'whitelist by account id' ([4221](https://github.com/stellar/go/issues/4221))
* 'whitelist by canonical asset id' ([4222](https://github.com/stellar/go/issues/4222))

The filters and their configuration are optional features and must be enabled with horizon command line parameters `admin-port=4200` and `enable-ingestion-filtering=true`

Once set, filter configurations and their rules are initially empty and the filters are disabled by default. To enable filters, update the configuration settings, refer to the Admin API Docs which are published on the Admin Port at http://localhost:<admin_port>/, follow details and examples for endpoints:
* `/ingestion/filters/account`
* `/ingestion/filters/asset.`

## V2.17.0 Release Candidate

**Upgrading to this version from <= v2.8.3 will trigger a state rebuild. During this process (which will take at least 10 minutes), Horizon will not ingest new ledgers.**
Expand Down
2 changes: 2 additions & 0 deletions services/horizon/cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ func runDBReingestRange(ledgerRanges []history.LedgerRange, reingestForce bool,
HistorySession: horizonSession,
HistoryArchiveURL: config.HistoryArchiveURLs[0],
CheckpointFrequency: config.CheckpointFrequency,
ReingestEnabled: true,
MaxReingestRetries: int(retries),
ReingestRetryBackoffSeconds: int(retryBackoffSeconds),
EnableCaptiveCore: config.EnableCaptiveCoreIngestion,
Expand All @@ -398,6 +399,7 @@ func runDBReingestRange(ledgerRanges []history.LedgerRange, reingestForce bool,
StellarCoreCursor: config.CursorName,
StellarCoreURL: config.StellarCoreURL,
RoundingSlippageFilter: config.RoundingSlippageFilter,
EnableIngestionFiltering: config.EnableIngestionFiltering,
}

if !ingestConfig.EnableCaptiveCore {
Expand Down
Loading