Skip to content
This repository has been archived by the owner on Feb 1, 2024. It is now read-only.

use FeeStats() from new Go SDK #129

Merged
merged 16 commits into from
Mar 20, 2019
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
47 changes: 32 additions & 15 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 17 additions & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,28 @@ import:
- package: github.com/spf13/pflag
version: v1.0.0
- package: github.com/stellar/go
version: 5bbd27814a3ffca9aeffcbd75a09a6164959776a
version: 61ed9984b1f88fda0d4e5e375021b404d9900959
subpackages:
- build
- clients/horizon
- support/config
- support/errors
##############################################################
# manually added dependencies to fix glide import resolution
##############################################################
- package: github.com/sirupsen/logrus
version: 070c81def33f6362a8267b6a4e56fb7bf23fc6b5
- package: github.com/Sirupsen/logrus
repo: [email protected]:sirupsen/logrus
vcs: git
version: 070c81def33f6362a8267b6a4e56fb7bf23fc6b5
- package: golang.org/x/crypto
version: 2509b142fb2b797aa7587dad548f113b2c0f20ce
- package: golang.org/x/sys
version: 6c81ef8f67ca3f42fc9cd71dfbd5f35b0c4b5771
##############################################################
# /manually added dependencies to fix glide import resolution
##############################################################
- package: github.com/PagerDuty/go-pagerduty
version: 635c5ce271490fba94880e62cde4eea3c1c184b9
- package: github.com/lechengfan/googleauth
Expand Down
5 changes: 3 additions & 2 deletions plugins/batchedExchange.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,10 @@ func (b BatchedExchange) OpenOrders2Offers(orders []model.OpenOrder, baseAsset h
b.offerID2OrderID[ID] = order.ID
}

var lmt time.Time
var lmt *time.Time
if order.Timestamp != nil {
lmt = time.Unix(int64(*order.Timestamp)/1000, 0)
lastModTime := time.Unix(int64(*order.Timestamp)/1000, 0)
lmt = &lastModTime
}
offers = append(offers, hProtocol.Offer{
ID: ID,
Expand Down
87 changes: 50 additions & 37 deletions plugins/sdexExtensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"fmt"
"log"
"net/http"
"strconv"

"github.com/stellar/kelp/support/networking"
"github.com/stellar/go/exp/clients/horizon"
hProtocol "github.com/stellar/go/protocols/horizon"
)

// OpFeeStroops computes fees per operation
Expand Down Expand Up @@ -49,34 +49,26 @@ func SdexFeeFnFromStats(
return nil, fmt.Errorf("unable to create SdexFeeFnFromStats, maxOpFeeStroops should be >= %d (baseFeeStroops): %d", baseFeeStroops, maxOpFeeStroops)
}

client := &horizonclient.Client{
// TODO horizonclient.Client has a bug in it where it does not use "/" to separate the horizonURL from the fee_stats endpoint
HorizonURL: horizonBaseURL + "/",
HTTP: http.DefaultClient,
}

return func() (uint64, error) {
return getFeeFromStats(horizonBaseURL, capacityTrigger, percentile, maxOpFeeStroops)
return getFeeFromStats(client, capacityTrigger, percentile, maxOpFeeStroops)
}, nil
}

func getFeeFromStats(horizonBaseURL string, capacityTrigger float64, percentile uint8, maxOpFeeStroops uint64) (uint64, error) {
feeStatsURL := horizonBaseURL + "/fee_stats"

feeStatsResponseMap := map[string]string{}
e := networking.JSONRequest(http.DefaultClient, "GET", feeStatsURL, "", map[string]string{}, &feeStatsResponseMap, "")
if e != nil {
return 0, fmt.Errorf("error fetching fee stats (URL=%s): %s", feeStatsURL, e)
}

// parse ledgerCapacityUsage
ledgerCapacityUsage, e := strconv.ParseFloat(feeStatsResponseMap["ledger_capacity_usage"], 64)
func getFeeFromStats(horizonClient horizonclient.ClientInterface, capacityTrigger float64, percentile uint8, maxOpFeeStroops uint64) (uint64, error) {
feeStats, e := horizonClient.FeeStats()
if e != nil {
return 0, fmt.Errorf("could not parse ledger_capacity_usage ('%s') as float64: %s", feeStatsResponseMap["ledger_capacity_usage"], e)
return 0, fmt.Errorf("error fetching fee stats: %s", e)
}

// case where we don't trigger the dynamic fees logic
if ledgerCapacityUsage < capacityTrigger {
var lastFeeInt int
lastFeeInt, e = strconv.Atoi(feeStatsResponseMap["last_ledger_base_fee"])
if e != nil {
return 0, fmt.Errorf("could not parse last_ledger_base_fee ('%s') as int: %s", feeStatsResponseMap["last_ledger_base_fee"], e)
}
lastFee := uint64(lastFeeInt)
if feeStats.LedgerCapacityUsage < capacityTrigger {
lastFee := uint64(feeStats.LastLedgerBaseFee)
if lastFee <= maxOpFeeStroops {
log.Printf("lastFee <= maxOpFeeStroops; using last_ledger_base_fee of %d stroops (maxOpFeeStroops = %d)\n", lastFee, maxOpFeeStroops)
return lastFee, nil
Expand All @@ -86,23 +78,44 @@ func getFeeFromStats(horizonBaseURL string, capacityTrigger float64, percentile
}

// parse percentile value
var pStroopsInt64 uint64
pKey := fmt.Sprintf("p%d_accepted_fee", percentile)
if pStroops, ok := feeStatsResponseMap[pKey]; ok {
var pStroopsInt int
pStroopsInt, e = strconv.Atoi(pStroops)
if e != nil {
return 0, fmt.Errorf("could not parse percentile value (%s='%s'): %s", pKey, pStroops, e)
}
pStroopsInt64 = uint64(pStroopsInt)
} else {
return 0, fmt.Errorf("could not fetch percentile value (%s) from feeStatsResponseMap: %s", pKey, e)
acceptedFee, e := getAcceptedFee(&feeStats, percentile)
if e != nil {
return 0, fmt.Errorf("could not fetch accepted fee: %s", e)
}
acceptedFeeInt64 := uint64(acceptedFee)

if pStroopsInt64 <= maxOpFeeStroops {
log.Printf("pStroopsInt64 <= maxOpFeeStroops; using %s of %d stroops (maxOpFeeStroops = %d)\n", pKey, pStroopsInt64, maxOpFeeStroops)
return pStroopsInt64, nil
if acceptedFeeInt64 <= maxOpFeeStroops {
log.Printf("acceptedFeeInt64 <= maxOpFeeStroops; using acceptedFee of %d stroops at percentile=%d (maxOpFeeStroops=%d)\n", acceptedFeeInt64, percentile, maxOpFeeStroops)
return acceptedFeeInt64, nil
}
log.Printf("pStroopsInt64 > maxOpFeeStroops; using maxOpFeeStroops of %d stroops (%s = %d)\n", maxOpFeeStroops, pKey, pStroopsInt64)
log.Printf("acceptedFeeInt64 > maxOpFeeStroops; using maxOpFeeStroops of %d stroops (percentile=%d, acceptedFee=%d stroops)\n", maxOpFeeStroops, percentile, acceptedFeeInt64)
return maxOpFeeStroops, nil
}

func getAcceptedFee(fs *hProtocol.FeeStats, percentile uint8) (int, error) {
switch percentile {
case 10:
return fs.P10AcceptedFee, nil
case 20:
return fs.P20AcceptedFee, nil
case 30:
return fs.P30AcceptedFee, nil
case 40:
return fs.P40AcceptedFee, nil
case 50:
return fs.P50AcceptedFee, nil
case 60:
return fs.P60AcceptedFee, nil
case 70:
return fs.P70AcceptedFee, nil
case 80:
return fs.P80AcceptedFee, nil
case 90:
return fs.P90AcceptedFee, nil
case 95:
return fs.P95AcceptedFee, nil
case 99:
return fs.P99AcceptedFee, nil
}
return 0, fmt.Errorf("unable to get accepted fee for percentile: %d", percentile)
}