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

Merge master into amm #3901

Merged
merged 3 commits into from
Sep 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions clients/horizonclient/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
All notable changes to this project will be documented in this
file. This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

* The restriction that `Fund` can only be called on the DefaultTestNetClient has
been removed. Any horizonclient.Client may now call Fund. Horizon instances not
supporting Fund will error with a resource not found error.

## [v7.1.1](https://github.com/stellar/go/releases/tag/horizonclient-v7.1.1) - 2021-06-25

* Added transaction and operation result codes to the horizonclient.Error string for easy glancing at string only errors for underlying cause.
Expand Down
6 changes: 3 additions & 3 deletions clients/horizonclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,11 +575,11 @@ func (c *Client) Trades(request TradeRequest) (tds hProtocol.TradesPage, err err
// Fund creates a new account funded from friendbot. It only works on test networks. See
// https://www.stellar.org/developers/guides/get-started/create-account.html for more information.
func (c *Client) Fund(addr string) (tx hProtocol.Transaction, err error) {
if !c.isTestNet {
return tx, errors.New("can't fund account from friendbot on production network")
}
friendbotURL := fmt.Sprintf("%sfriendbot?addr=%s", c.fixHorizonURL(), addr)
err = c.sendGetRequest(friendbotURL, &tx)
if IsNotFoundError(err) {
return tx, errors.Wrap(err, "funding is only available on test networks and may not be supported by "+c.fixHorizonURL())
}
return
}

Expand Down
24 changes: 23 additions & 1 deletion clients/horizonclient/client_fund_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ func TestFund(t *testing.T) {
client := &Client{
HorizonURL: "https://localhost/",
HTTP: hmock,
isTestNet: true,
}

hmock.On(
Expand All @@ -37,3 +36,26 @@ func TestFund(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, int32(8269), tx.Ledger)
}

func TestFund_notSupported(t *testing.T) {
friendbotFundResponse := `{
"type": "https://stellar.org/horizon-errors/not_found",
"title": "Resource Missing",
"status": 404,
"detail": "The resource at the url requested was not found. This usually occurs for one of two reasons: The url requested is not valid, or no data in our database could be found with the parameters provided."
}`

hmock := httptest.NewClient()
client := &Client{
HorizonURL: "https://localhost/",
HTTP: hmock,
}

hmock.On(
"GET",
"https://localhost/friendbot?addr=GBLPP2W3X3PJQXYMC7EFWM5G2QCZL7HTCTFNMONS4ITGAYJ3GNNZIQ4V",
).ReturnString(404, friendbotFundResponse)

_, err := client.Fund("GBLPP2W3X3PJQXYMC7EFWM5G2QCZL7HTCTFNMONS4ITGAYJ3GNNZIQ4V")
assert.EqualError(t, err, "funding is only available on test networks and may not be supported by https://localhost/: horizon error: \"Resource Missing\" - check horizon.Error.Problem for more information")
}
2 changes: 0 additions & 2 deletions clients/horizonclient/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ type Client struct {
// AppVersion is the version of the application using the horizonclient package
AppVersion string
horizonTimeout time.Duration
isTestNet bool

// clock is a Clock returning the current time.
clock *clock.Clock
Expand Down Expand Up @@ -215,7 +214,6 @@ var DefaultTestNetClient = &Client{
HorizonURL: "https://horizon-testnet.stellar.org/",
HTTP: http.DefaultClient,
horizonTimeout: HorizonTimeout,
isTestNet: true,
}

// DefaultPublicNetClient is a default client to connect to public network.
Expand Down
2 changes: 1 addition & 1 deletion services/horizon/cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ var dbReapCmd = &cobra.Command{
return err
}
ctx := context.Background()
app.UpdateLedgerState(ctx)
app.UpdateHorizonLedgerState(ctx)
return app.DeleteUnretainedHistory(ctx)
},
}
Expand Down
5 changes: 3 additions & 2 deletions services/horizon/internal/actions_root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ func TestRootAction(t *testing.T) {
ht.App.config.StellarCoreURL = server.URL
ht.App.config.NetworkPassphrase = "test"
assert.NoError(t, ht.App.UpdateStellarCoreInfo(ht.Ctx))
ht.App.UpdateLedgerState(ht.Ctx)
ht.App.UpdateCoreLedgerState(ht.Ctx)
ht.App.UpdateHorizonLedgerState(ht.Ctx)

w := ht.Get("/")

Expand Down Expand Up @@ -95,7 +96,7 @@ func TestRootCoreClientInfoErrored(t *testing.T) {
defer server.Close()

ht.App.config.StellarCoreURL = server.URL
ht.App.UpdateLedgerState(ht.Ctx)
ht.App.UpdateCoreLedgerState(ht.Ctx)

w := ht.Get("/")

Expand Down
31 changes: 23 additions & 8 deletions services/horizon/internal/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func (a *App) GetCoreState() corestate.State {
}

const tickerMaxFrequency = 1 * time.Second
const tickerMaxDuration = 10 * time.Second
const tickerMaxDuration = 5 * time.Second

// NewApp constructs an new App instance from the provided config.
func NewApp(config Config) (*App, error) {
Expand Down Expand Up @@ -208,10 +208,11 @@ func (a *App) HorizonSession() db.SessionInterface {
return a.historyQ.SessionInterface.Clone()
}

// UpdateLedgerState triggers a refresh of several metrics gauges, such as open
// db connections and ledger state
func (a *App) UpdateLedgerState(ctx context.Context) {
var next ledger.Status
// UpdateCoreLedgerState triggers a refresh of Stellar-Core ledger state.
// This is done separately from Horizon ledger state update to prevent issues
// in case Stellar-Core query timeout.
func (a *App) UpdateCoreLedgerState(ctx context.Context) {
var next ledger.CoreStatus

logErr := func(err error, msg string) {
log.WithStack(err).WithField("err", err.Error()).Error(msg)
Expand All @@ -228,7 +229,20 @@ func (a *App) UpdateLedgerState(ctx context.Context) {
return
}
next.CoreLatest = int32(coreInfo.Info.Ledger.Num)
a.ledgerState.SetCoreStatus(next)
}

// UpdateHorizonLedgerState triggers a refresh of Horizon ledger state.
// This is done separately from Core ledger state update to prevent issues
// in case Stellar-Core query timeout.
func (a *App) UpdateHorizonLedgerState(ctx context.Context) {
var next ledger.HorizonStatus

logErr := func(err error, msg string) {
log.WithStack(err).WithField("err", err.Error()).Error(msg)
}

var err error
next.HistoryLatest, next.HistoryLatestClosedAt, err =
a.HistoryQ().LatestLedgerSequenceClosedAt(ctx)
if err != nil {
Expand All @@ -248,7 +262,7 @@ func (a *App) UpdateLedgerState(ctx context.Context) {
return
}

a.ledgerState.SetStatus(next)
a.ledgerState.SetHorizonStatus(next)
}

// UpdateFeeStatsState triggers a refresh of several operation fee metrics.
Expand Down Expand Up @@ -419,9 +433,10 @@ func (a *App) Tick(ctx context.Context) error {
log.Debug("ticking app")

// update ledger state, operation fee state, and stellar-core info in parallel
wg.Add(3)
wg.Add(4)
var err error
go func() { a.UpdateLedgerState(ctx); wg.Done() }()
go func() { a.UpdateCoreLedgerState(ctx); wg.Done() }()
go func() { a.UpdateHorizonLedgerState(ctx); wg.Done() }()
go func() { a.UpdateFeeStatsState(ctx); wg.Done() }()
go func() { err = a.UpdateStellarCoreInfo(ctx); wg.Done() }()
wg.Wait()
Expand Down
6 changes: 4 additions & 2 deletions services/horizon/internal/httpt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ func startHTTPTest(t *testing.T, scenario string) *HTTPT {
}`)

ret.App.config.StellarCoreURL = ret.coreServer.URL
ret.App.UpdateLedgerState(context.Background())
ret.App.UpdateCoreLedgerState(context.Background())
ret.App.UpdateHorizonLedgerState(context.Background())

return ret
}
Expand Down Expand Up @@ -101,5 +102,6 @@ func (ht *HTTPT) ReapHistory(retention uint) {
ht.App.reaper.RetentionCount = retention
err := ht.App.DeleteUnretainedHistory(context.Background())
ht.Require.NoError(err)
ht.App.UpdateLedgerState(context.Background())
ht.App.UpdateCoreLedgerState(context.Background())
ht.App.UpdateHorizonLedgerState(context.Background())
}
12 changes: 10 additions & 2 deletions services/horizon/internal/ledger/ledger_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import (
func Test_HistoryDBLedgerSourceCurrentLedger(t *testing.T) {
state := &State{
RWMutex: sync.RWMutex{},
current: Status{ExpHistoryLatest: 3},
current: Status{
HorizonStatus: HorizonStatus{
ExpHistoryLatest: 3,
},
},
}

ledgerSource := HistoryDBSource{
Expand All @@ -25,7 +29,11 @@ func Test_HistoryDBLedgerSourceCurrentLedger(t *testing.T) {
func Test_HistoryDBLedgerSourceNextLedger(t *testing.T) {
state := &State{
RWMutex: sync.RWMutex{},
current: Status{ExpHistoryLatest: 3},
current: Status{
HorizonStatus: HorizonStatus{
ExpHistoryLatest: 3,
},
},
}

ledgerSource := HistoryDBSource{
Expand Down
24 changes: 23 additions & 1 deletion services/horizon/internal/ledger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ import (
// Status represents a snapshot of both horizon's and stellar-core's view of the
// ledger.
type Status struct {
CoreLatest int32 `db:"core_latest"`
CoreStatus
HorizonStatus
}

type CoreStatus struct {
CoreLatest int32 `db:"core_latest"`
}

type HorizonStatus struct {
HistoryLatest int32 `db:"history_latest"`
HistoryLatestClosedAt time.Time `db:"history_latest_closed_at"`
HistoryElder int32 `db:"history_elder"`
Expand Down Expand Up @@ -41,3 +49,17 @@ func (c *State) SetStatus(next Status) {
defer c.Unlock()
c.current = next
}

// SetCoreStatus updates the cached snapshot of the ledger state of Stellar-Core
func (c *State) SetCoreStatus(next CoreStatus) {
c.Lock()
defer c.Unlock()
c.current.CoreStatus = next
}

// SetHorizonStatus updates the cached snapshot of the ledger state of Horizon
func (c *State) SetHorizonStatus(next HorizonStatus) {
c.Lock()
defer c.Unlock()
c.current.HorizonStatus = next
}
8 changes: 6 additions & 2 deletions services/horizon/internal/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,12 @@ func TestCheckHistoryStaleMiddleware(t *testing.T) {
} {
t.Run(testCase.name, func(t *testing.T) {
state := ledger.Status{
CoreLatest: testCase.coreLatest,
HistoryLatest: testCase.historyLatest,
CoreStatus: ledger.CoreStatus{
CoreLatest: testCase.coreLatest,
},
HorizonStatus: ledger.HorizonStatus{
HistoryLatest: testCase.historyLatest,
},
}
ledgerState := &ledger.State{}
ledgerState.SetStatus(state)
Expand Down
27 changes: 24 additions & 3 deletions services/horizon/internal/resourceadapter/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ func TestPopulateRoot(t *testing.T) {

PopulateRoot(context.Background(),
res,
ledger.Status{CoreLatest: 1, HistoryLatest: 3, HistoryElder: 2},
ledger.Status{
CoreStatus: ledger.CoreStatus{
CoreLatest: 1,
},
HorizonStatus: ledger.HorizonStatus{
HistoryLatest: 3, HistoryElder: 2,
},
},
"hVersion",
"cVersion",
"passphrase",
Expand All @@ -44,7 +51,14 @@ func TestPopulateRoot(t *testing.T) {
res = &horizon.Root{}
PopulateRoot(context.Background(),
res,
ledger.Status{CoreLatest: 1, HistoryLatest: 3, HistoryElder: 2},
ledger.Status{
CoreStatus: ledger.CoreStatus{
CoreLatest: 1,
},
HorizonStatus: ledger.HorizonStatus{
HistoryLatest: 3, HistoryElder: 2,
},
},
"hVersion",
"cVersion",
"passphrase",
Expand All @@ -65,7 +79,14 @@ func TestPopulateRoot(t *testing.T) {
res = &horizon.Root{}
PopulateRoot(context.Background(),
res,
ledger.Status{CoreLatest: 1, HistoryLatest: 3, HistoryElder: 2},
ledger.Status{
CoreStatus: ledger.CoreStatus{
CoreLatest: 1,
},
HorizonStatus: ledger.HorizonStatus{
HistoryLatest: 3, HistoryElder: 2,
},
},
"hVersion",
"cVersion",
"passphrase",
Expand Down
3 changes: 3 additions & 0 deletions txnbuild/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ file. This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

* GenericTransaction, Transaction, and FeeBumpTransaction now implement
encoding.TextMarshaler and encoding.TextUnmarshaler.

## [v7.1.1](https://github.com/stellar/go/releases/tag/horizonclient-v7.1.1) - 2021-06-25

### Bug Fixes
Expand Down
Loading