Skip to content

Commit

Permalink
txnbuild: Parse price strings with more than 7 decimals of precision (#…
Browse files Browse the repository at this point in the history
…2588)

* Parse price strings with more than 7 decimals of precision

* Create internal price type
  • Loading branch information
tamirms authored May 15, 2020
1 parent 26c11ef commit c57aa7a
Show file tree
Hide file tree
Showing 14 changed files with 248 additions and 26 deletions.
4 changes: 2 additions & 2 deletions clients/horizonclient/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1063,10 +1063,10 @@ func ExampleClient_StreamTransactions() {
}
}

// Action needed in release: horizonclient-v3.1.0
// Action needed in release: horizonclient-v3.2.0
// Uncomment fee bump examples when protocol 13 is enabled
//func convertToV1Tx(tx *txnbuild.Transaction) (*txnbuild.Transaction, error) {
// // Action needed in release: horizonclient-v3.1.0
// // Action needed in release: horizonclient-v3.2.0
// // remove manual envelope type configuration because
// // once protocol 13 is enabled txnbuild will generate
// // v1 transaction envelopes by default
Expand Down
2 changes: 1 addition & 1 deletion clients/horizonclient/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ func TestSubmitTransactionRequest(t *testing.T) {
}

func convertToV1Tx(t *testing.T, tx *txnbuild.Transaction) *txnbuild.Transaction {
// Action needed in release: horizonclient-v3.1.0
// Action needed in release: horizonclient-v3.2.0
// remove manual envelope type configuration because
// once protocol 13 is enabled txnbuild will generate
// v1 transaction envelopes by default
Expand Down
3 changes: 2 additions & 1 deletion txnbuild/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
All notable changes to this project will be documented in this
file. This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased
## [v3.1.0](https://github.com/stellar/go/releases/tag/horizonclient-v3.1.0) - 2020-05-14

* Fix bug which occurs when parsing xdr offers with prices that require more than 7 decimals of precision ([#2588](https://github.com/stellar/go/pull/2588))
* Add `AddSignatureBase64` function to both `Transaction` and `FeeBumpTransaction` objects for adding a base64-encoded signature. [#2586](https://github.com/stellar/go/pull/2586)

## [v3.0.1](https://github.com/stellar/go/releases/tag/horizonclient-v3.0.1) - 2020-05-11
Expand Down
10 changes: 5 additions & 5 deletions txnbuild/create_passive_offer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package txnbuild

import (
"github.com/stellar/go/amount"
"github.com/stellar/go/price"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/xdr"
)
Expand All @@ -14,6 +13,7 @@ type CreatePassiveSellOffer struct {
Buying Asset
Amount string
Price string
price price
SourceAccount Account
}

Expand All @@ -34,16 +34,15 @@ func (cpo *CreatePassiveSellOffer) BuildXDR() (xdr.Operation, error) {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'")
}

xdrPrice, err := price.Parse(cpo.Price)
if err != nil {
if err = cpo.price.parse(cpo.Price); err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Price'")
}

xdrOp := xdr.CreatePassiveSellOfferOp{
Selling: xdrSelling,
Buying: xdrBuying,
Amount: xdrAmount,
Price: xdrPrice,
Price: cpo.price.toXDR(),
}

opType := xdr.OperationTypeCreatePassiveSellOffer
Expand All @@ -66,7 +65,8 @@ func (cpo *CreatePassiveSellOffer) FromXDR(xdrOp xdr.Operation) error {
cpo.SourceAccount = accountFromXDR(xdrOp.SourceAccount)
cpo.Amount = amount.String(result.Amount)
if result.Price != (xdr.Price{}) {
cpo.Price = price.StringFromFloat64(float64(result.Price.N) / float64(result.Price.D))
cpo.price.fromXDR(result.Price)
cpo.Price = cpo.price.string()
}
buyingAsset, err := assetFromXDR(result.Buying)
if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions txnbuild/create_passive_offer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package txnbuild

import (
"github.com/stellar/go/xdr"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -112,3 +113,28 @@ func TestCreatePassiveSellOfferValidatePrice(t *testing.T) {
assert.Contains(t, err.Error(), expected)
}
}

func TestCreatePassiveSellOfferPrice(t *testing.T) {
kp0 := newKeypair0()
sourceAccount := NewSimpleAccount(kp0.Address(), int64(41137196761100))

offer := CreatePassiveSellOffer{
Selling: CreditAsset{"ABCD", kp0.Address()},
Buying: NativeAsset{},
Amount: "1",
Price: "0.000000001",
SourceAccount: &sourceAccount,
}

xdrOp, err := offer.BuildXDR()
assert.NoError(t, err)
expectedPrice := xdr.Price{N: 1, D: 1000000000}
assert.Equal(t, expectedPrice, xdrOp.Body.CreatePassiveSellOfferOp.Price)
assert.Equal(t, offer.Price, offer.price.string())
assert.Equal(t, expectedPrice, offer.price.toXDR())

parsed := CreatePassiveSellOffer{}
assert.NoError(t, parsed.FromXDR(xdrOp))
assert.Equal(t, offer.Price, parsed.Price)
assert.Equal(t, offer.price, parsed.price)
}
2 changes: 1 addition & 1 deletion txnbuild/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ func ExampleManageBuyOffer() {

}

// Action needed in release: horizonclient-v3.1.0
// Action needed in release: horizonclient-v3.2.0
// Uncomment this example when protocol 13 is enabled
//func ExampleFeeBumpTransaction() {
// kp, _ := keypair.Parse("SBPQUZ6G4FZNWFHKUWC5BEYWF6R52E3SEP7R3GWYSM2XTKGF5LNTWW4R")
Expand Down
2 changes: 1 addition & 1 deletion txnbuild/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func newSignedFeeBumpTransaction(
}

func convertToV1Tx(tx *Transaction) {
// Action needed in release: horizonclient-v3.1.0
// Action needed in release: horizonclient-v3.2.0
// remove manual envelope type configuration because
// once protocol 13 is enabled txnbuild will generate
// v1 transaction envelopes by default
Expand Down
10 changes: 5 additions & 5 deletions txnbuild/manage_buy_offer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package txnbuild

import (
"github.com/stellar/go/amount"
"github.com/stellar/go/price"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/xdr"
)
Expand All @@ -14,6 +13,7 @@ type ManageBuyOffer struct {
Buying Asset
Amount string
Price string
price price
OfferID int64
SourceAccount Account
}
Expand All @@ -35,8 +35,7 @@ func (mo *ManageBuyOffer) BuildXDR() (xdr.Operation, error) {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'")
}

xdrPrice, err := price.Parse(mo.Price)
if err != nil {
if err = mo.price.parse(mo.Price); err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Price'")
}

Expand All @@ -45,7 +44,7 @@ func (mo *ManageBuyOffer) BuildXDR() (xdr.Operation, error) {
Selling: xdrSelling,
Buying: xdrBuying,
BuyAmount: xdrAmount,
Price: xdrPrice,
Price: mo.price.toXDR(),
OfferId: xdr.Int64(mo.OfferID),
}
body, err := xdr.NewOperationBody(opType, xdrOp)
Expand All @@ -69,7 +68,8 @@ func (mo *ManageBuyOffer) FromXDR(xdrOp xdr.Operation) error {
mo.OfferID = int64(result.OfferId)
mo.Amount = amount.String(result.BuyAmount)
if result.Price != (xdr.Price{}) {
mo.Price = price.StringFromFloat64(float64(result.Price.N) / float64(result.Price.D))
mo.price.fromXDR(result.Price)
mo.Price = mo.price.string()
}
buyingAsset, err := assetFromXDR(result.Buying)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions txnbuild/manage_buy_offer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package txnbuild

import (
"github.com/stellar/go/xdr"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -145,3 +146,27 @@ func TestManageBuyOfferValidateOfferID(t *testing.T) {
assert.Contains(t, err.Error(), expected)
}
}

func TestManageBuyOfferPrice(t *testing.T) {
kp0 := newKeypair0()

mbo := ManageBuyOffer{
Selling: CreditAsset{"ABCD", kp0.Address()},
Buying: NativeAsset{},
Amount: "1",
Price: "0.000000001",
OfferID: 1,
}

xdrOp, err := mbo.BuildXDR()
assert.NoError(t, err)
expectedPrice := xdr.Price{N: 1, D: 1000000000}
assert.Equal(t, expectedPrice, xdrOp.Body.ManageBuyOfferOp.Price)
assert.Equal(t, mbo.Price, mbo.price.string())
assert.Equal(t, expectedPrice, mbo.price.toXDR())

parsed := ManageBuyOffer{}
assert.NoError(t, parsed.FromXDR(xdrOp))
assert.Equal(t, mbo.Price, parsed.Price)
assert.Equal(t, mbo.price, parsed.price)
}
10 changes: 5 additions & 5 deletions txnbuild/manage_offer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package txnbuild

import (
"github.com/stellar/go/amount"
"github.com/stellar/go/price"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/xdr"
)
Expand Down Expand Up @@ -78,6 +77,7 @@ type ManageSellOffer struct {
Buying Asset
Amount string
Price string
price price
OfferID int64
SourceAccount Account
}
Expand All @@ -99,8 +99,7 @@ func (mo *ManageSellOffer) BuildXDR() (xdr.Operation, error) {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'")
}

xdrPrice, err := price.Parse(mo.Price)
if err != nil {
if err = mo.price.parse(mo.Price); err != nil {
return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Price'")
}

Expand All @@ -109,7 +108,7 @@ func (mo *ManageSellOffer) BuildXDR() (xdr.Operation, error) {
Selling: xdrSelling,
Buying: xdrBuying,
Amount: xdrAmount,
Price: xdrPrice,
Price: mo.price.toXDR(),
OfferId: xdr.Int64(mo.OfferID),
}
body, err := xdr.NewOperationBody(opType, xdrOp)
Expand All @@ -133,7 +132,8 @@ func (mo *ManageSellOffer) FromXDR(xdrOp xdr.Operation) error {
mo.OfferID = int64(result.OfferId)
mo.Amount = amount.String(result.Amount)
if result.Price != (xdr.Price{}) {
mo.Price = price.StringFromFloat64(float64(result.Price.N) / float64(result.Price.D))
mo.price.fromXDR(result.Price)
mo.Price = mo.price.string()
}
buyingAsset, err := assetFromXDR(result.Buying)
if err != nil {
Expand Down
25 changes: 25 additions & 0 deletions txnbuild/manage_offer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package txnbuild

import (
"github.com/stellar/go/xdr"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -141,3 +142,27 @@ func TestManageSellOfferValidateOfferID(t *testing.T) {
assert.Contains(t, err.Error(), expected)
}
}

func TestManageSellOfferPrice(t *testing.T) {
kp0 := newKeypair0()

mso := ManageSellOffer{
Selling: CreditAsset{"ABCD", kp0.Address()},
Buying: NativeAsset{},
Amount: "1",
Price: "0.000000001",
OfferID: 1,
}

xdrOp, err := mso.BuildXDR()
assert.NoError(t, err)
expectedPrice := xdr.Price{N: 1, D: 1000000000}
assert.Equal(t, expectedPrice, xdrOp.Body.ManageSellOfferOp.Price)
assert.Equal(t, mso.Price, mso.price.string())
assert.Equal(t, expectedPrice, mso.price.toXDR())

parsed := ManageSellOffer{}
assert.NoError(t, parsed.FromXDR(xdrOp))
assert.Equal(t, mso.Price, parsed.Price)
assert.Equal(t, mso.price, parsed.price)
}
10 changes: 5 additions & 5 deletions txnbuild/operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestManageSellOfferFromXDR(t *testing.T) {
assert.Equal(t, "GBUKBCG5VLRKAVYAIREJRUJHOKLIADZJOICRW43WVJCLES52BDOTCQZU", mso.SourceAccount.GetAccountID(), "source accounts should match")
assert.Equal(t, int64(0), mso.OfferID, "OfferID should match")
assert.Equal(t, "300.0000000", mso.Amount, "Amount should match")
assert.Equal(t, "5.0000000", mso.Price, "Price should match")
assert.Equal(t, "5", mso.Price, "Price should match")
assert.Equal(t, true, mso.Selling.IsNative(), "Selling should be native")
assetType, e := mso.Buying.GetType()
assert.NoError(t, e)
Expand All @@ -113,7 +113,7 @@ func TestManageSellOfferFromXDR(t *testing.T) {
assert.Equal(t, nil, mso.SourceAccount, "source accounts should match")
assert.Equal(t, int64(0), mso.OfferID, "OfferID should match")
assert.Equal(t, "400.0000000", mso.Amount, "Amount should match")
assert.Equal(t, "5.0000000", mso.Price, "Price should match")
assert.Equal(t, "5", mso.Price, "Price should match")
assert.Equal(t, true, mso.Buying.IsNative(), "Buying should be native")
assetType, e := mso.Selling.GetType()
assert.NoError(t, e)
Expand All @@ -136,7 +136,7 @@ func TestManageBuyOfferFromXDR(t *testing.T) {
assert.Equal(t, "GBUKBCG5VLRKAVYAIREJRUJHOKLIADZJOICRW43WVJCLES52BDOTCQZU", mbo.SourceAccount.GetAccountID(), "source accounts should match")
assert.Equal(t, int64(0), mbo.OfferID, "OfferID should match")
assert.Equal(t, "100.0000000", mbo.Amount, "Amount should match")
assert.Equal(t, "0.5000000", mbo.Price, "Price should match")
assert.Equal(t, "0.5", mbo.Price, "Price should match")
assert.Equal(t, true, mbo.Selling.IsNative(), "Selling should be native")
assetType, e := mbo.Buying.GetType()
assert.NoError(t, e)
Expand All @@ -150,7 +150,7 @@ func TestManageBuyOfferFromXDR(t *testing.T) {
assert.Equal(t, nil, mbo.SourceAccount, "source accounts should match")
assert.Equal(t, int64(0), mbo.OfferID, "OfferID should match")
assert.Equal(t, "300.0000000", mbo.Amount, "Amount should match")
assert.Equal(t, "0.6000000", mbo.Price, "Price should match")
assert.Equal(t, "0.6", mbo.Price, "Price should match")
assert.Equal(t, true, mbo.Buying.IsNative(), "Buying should be native")
assetType, e := mbo.Selling.GetType()
assert.NoError(t, e)
Expand All @@ -172,7 +172,7 @@ func TestCreatePassiveSellOfferFromXDR(t *testing.T) {
if assert.NoError(t, err) {
assert.Equal(t, nil, cpo.SourceAccount, "source accounts should match")
assert.Equal(t, "10.0000000", cpo.Amount, "Amount should match")
assert.Equal(t, "1.0000000", cpo.Price, "Price should match")
assert.Equal(t, "1", cpo.Price, "Price should match")
assert.Equal(t, true, cpo.Selling.IsNative(), "Selling should be native")
assetType, e := cpo.Buying.GetType()
assert.NoError(t, e)
Expand Down
Loading

0 comments on commit c57aa7a

Please sign in to comment.