diff --git a/price/main.go b/price/main.go index 5d24b9a973..7737c8dfa3 100644 --- a/price/main.go +++ b/price/main.go @@ -38,6 +38,15 @@ func Parse(v string) (xdr.Price, error) { return continuedFraction(v) } +// MustParse is like Parse except that it panics on errors. +func MustParse(v string) xdr.Price { + result, err := Parse(v) + if err != nil { + panic(err) + } + return result +} + // continuedFraction calculates and returns the best rational approximation of // the given real number. func continuedFraction(price string) (xdrPrice xdr.Price, err error) { diff --git a/services/horizon/internal/integration/clawback_test.go b/services/horizon/internal/integration/clawback_test.go index 459371bd76..c41d2af465 100644 --- a/services/horizon/internal/integration/clawback_test.go +++ b/services/horizon/internal/integration/clawback_test.go @@ -93,7 +93,7 @@ func TestHappyClawbackAccountSellingLiabilities(t *testing.T) { Buying: txnbuild.NativeAsset{}, Selling: asset, Amount: "5", - Price: "1", + Price: xdr.Price{1, 1}, SourceAccount: fromAccount.GetAccountID(), }) tt.True(submissionResp.Successful) @@ -148,7 +148,7 @@ func TestSadClawbackAccountSufficientFundsSellingLiabilities(t *testing.T) { Buying: txnbuild.NativeAsset{}, Selling: asset, Amount: "5", - Price: "1", + Price: xdr.Price{1, 1}, SourceAccount: fromAccount.GetAccountID(), }) diff --git a/services/horizon/internal/integration/db_test.go b/services/horizon/internal/integration/db_test.go index 42f11cce5f..1d0a391327 100644 --- a/services/horizon/internal/integration/db_test.go +++ b/services/horizon/internal/integration/db_test.go @@ -79,8 +79,8 @@ func generateLiquidityPoolOps(itest *integration.Test, tt *assert.Assertions) (l LiquidityPoolID: [32]byte(poolID), MaxAmountA: "400", MaxAmountB: "777", - MinPrice: "0.5", - MaxPrice: "2", + MinPrice: xdr.Price{1, 2}, + MaxPrice: xdr.Price{2, 1}, }, ) diff --git a/services/horizon/internal/integration/liquidity_pool_test.go b/services/horizon/internal/integration/liquidity_pool_test.go index d907a19ee7..60a5e99f02 100644 --- a/services/horizon/internal/integration/liquidity_pool_test.go +++ b/services/horizon/internal/integration/liquidity_pool_test.go @@ -88,8 +88,8 @@ func TestLiquidityPoolHappyPath(t *testing.T) { LiquidityPoolID: [32]byte(poolID), MaxAmountA: "400", MaxAmountB: "777", - MinPrice: "0.5", - MaxPrice: "2", + MinPrice: xdr.Price{1, 2}, + MaxPrice: xdr.Price{2, 1}, }, ) @@ -475,8 +475,8 @@ func TestLiquidityPoolRevoke(t *testing.T) { LiquidityPoolID: [32]byte(poolID), MaxAmountA: "400", MaxAmountB: "777", - MinPrice: "0.5", - MaxPrice: "2", + MinPrice: xdr.Price{1, 2}, + MaxPrice: xdr.Price{2, 1}, }, &txnbuild.SetTrustLineFlags{ SourceAccount: master.Address(), @@ -667,8 +667,8 @@ func TestLiquidityPoolFailedDepositAndWithdraw(t *testing.T) { LiquidityPoolID: nonExistentPoolID, MaxAmountA: "400", MaxAmountB: "777", - MinPrice: "0.5", - MaxPrice: "2", + MinPrice: xdr.Price{1, 2}, + MaxPrice: xdr.Price{2, 1}, }, ) _, err = itest.Client().SubmitTransaction(tx) diff --git a/services/horizon/internal/integration/muxed_operations_test.go b/services/horizon/internal/integration/muxed_operations_test.go index 7ad311a69a..092b4152ee 100644 --- a/services/horizon/internal/integration/muxed_operations_test.go +++ b/services/horizon/internal/integration/muxed_operations_test.go @@ -50,7 +50,7 @@ func TestMuxedOperations(t *testing.T) { Selling: txnbuild.NativeAsset{}, Buying: txnbuild.CreditAsset{"ABCD", master.Address()}, Amount: "3", - Price: "1", + Price: xdr.Price{1, 1}, }, // This will generate a trade effect: &txnbuild.ManageSellOffer{ @@ -58,7 +58,7 @@ func TestMuxedOperations(t *testing.T) { Selling: txnbuild.CreditAsset{"ABCD", master.Address()}, Buying: txnbuild.NativeAsset{}, Amount: "3", - Price: "1", + Price: xdr.Price{1, 1}, }, &txnbuild.ManageData{ SourceAccount: sponsoredMuxed.Address(), diff --git a/services/horizon/internal/integration/sponsorship_test.go b/services/horizon/internal/integration/sponsorship_test.go index 5cf832f6e7..74a21dd385 100644 --- a/services/horizon/internal/integration/sponsorship_test.go +++ b/services/horizon/internal/integration/sponsorship_test.go @@ -516,7 +516,7 @@ func TestSponsorships(t *testing.T) { Selling: txnbuild.NativeAsset{}, Buying: asset, Amount: "3", - Price: "1", + Price: xdr.Price{1, 1}, }) signers := []*keypair.Full{sponsorPair, newAccountPair} diff --git a/services/horizon/internal/integration/state_verifier_test.go b/services/horizon/internal/integration/state_verifier_test.go index 435566aaba..012257db95 100644 --- a/services/horizon/internal/integration/state_verifier_test.go +++ b/services/horizon/internal/integration/state_verifier_test.go @@ -13,6 +13,7 @@ import ( "github.com/stellar/go/services/horizon/internal/db2/history" "github.com/stellar/go/services/horizon/internal/test/integration" "github.com/stellar/go/txnbuild" + "github.com/stellar/go/xdr" "github.com/stretchr/testify/assert" ) @@ -63,7 +64,7 @@ func TestStateVerifier(t *testing.T) { Selling: txnbuild.NativeAsset{}, Buying: txnbuild.CreditAsset{"ABCD", master.Address()}, Amount: "3", - Price: "1", + Price: xdr.Price{1, 1}, }, &txnbuild.ManageData{ SourceAccount: sponsoredSource.AccountID, diff --git a/txnbuild/CHANGELOG.md b/txnbuild/CHANGELOG.md index 504a09670f..769f41d2ac 100644 --- a/txnbuild/CHANGELOG.md +++ b/txnbuild/CHANGELOG.md @@ -14,6 +14,7 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). * Remove `options ...TransactionFromXDROption` parameter from `TransactionFromXDR()` * Rename `SetOpSourceMuxedAccount()` to (pre-existing) `SetOpSourceAccount()` which now accepts both `G` and `M` (muxed) account strkeys. +* Use xdr.Price to represent prices in txnbuild instead of strings ([#4167](https://github.com/stellar/go/pull/4167)). ## [8.0.0-beta.0](https://github.com/stellar/go/releases/tag/horizonclient-v8.0.0-beta.0) - 2021-10-04 diff --git a/txnbuild/create_passive_offer.go b/txnbuild/create_passive_offer.go index 2e9f851821..02ff86313f 100644 --- a/txnbuild/create_passive_offer.go +++ b/txnbuild/create_passive_offer.go @@ -12,8 +12,7 @@ type CreatePassiveSellOffer struct { Selling Asset Buying Asset Amount string - Price string - price price + Price xdr.Price SourceAccount string } @@ -34,15 +33,11 @@ func (cpo *CreatePassiveSellOffer) BuildXDR() (xdr.Operation, error) { return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'") } - 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: cpo.price.toXDR(), + Price: cpo.Price, } opType := xdr.OperationTypeCreatePassiveSellOffer @@ -65,10 +60,7 @@ 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.fromXDR(result.Price) - cpo.Price = cpo.price.string() - } + cpo.Price = result.Price buyingAsset, err := assetFromXDR(result.Buying) if err != nil { return errors.Wrap(err, "error parsing buying_asset in create_passive_sell_offer operation") diff --git a/txnbuild/create_passive_offer_test.go b/txnbuild/create_passive_offer_test.go index 3b158d6987..d4d0efbea4 100644 --- a/txnbuild/create_passive_offer_test.go +++ b/txnbuild/create_passive_offer_test.go @@ -15,7 +15,7 @@ func TestCreatePassiveSellOfferValidateBuyingAsset(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", ""}, Amount: "10", - Price: "1.0", + Price: xdr.Price{1, 1}, } _, err := NewTransaction( @@ -42,7 +42,7 @@ func TestCreatePassiveSellOfferValidateSellingAsset(t *testing.T) { Selling: CreditAsset{"ABCD0123456789", kp0.Address()}, Buying: NativeAsset{}, Amount: "10", - Price: "1.0", + Price: xdr.Price{1, 1}, } _, err := NewTransaction( @@ -69,7 +69,7 @@ func TestCreatePassiveSellOfferValidateAmount(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "-3", - Price: "1.0", + Price: xdr.Price{1, 1}, } _, err := NewTransaction( @@ -96,7 +96,7 @@ func TestCreatePassiveSellOfferValidatePrice(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "3", - Price: "-1.0", + Price: xdr.Price{-1, 0}, } _, err := NewTransaction( @@ -109,7 +109,7 @@ func TestCreatePassiveSellOfferValidatePrice(t *testing.T) { }, ) if assert.Error(t, err) { - expected := `validation failed for *txnbuild.CreatePassiveSellOffer operation: Field: Price, Error: amount can not be negative` + expected := `validation failed for *txnbuild.CreatePassiveSellOffer operation: Field: Price, Error: price denominator cannot be 0: -1/0` assert.Contains(t, err.Error(), expected) } } @@ -121,7 +121,7 @@ func TestCreatePassiveSellOfferPrice(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "1", - Price: "0.000000001", + Price: xdr.Price{1, 1000000000}, SourceAccount: kp0.Address(), } @@ -129,11 +129,8 @@ func TestCreatePassiveSellOfferPrice(t *testing.T) { 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) } diff --git a/txnbuild/example_test.go b/txnbuild/example_test.go index 7c6d6ed689..eea43fb3e0 100644 --- a/txnbuild/example_test.go +++ b/txnbuild/example_test.go @@ -2,6 +2,8 @@ package txnbuild import ( "fmt" + "github.com/stellar/go/price" + "github.com/stellar/go/xdr" "time" "github.com/stellar/go/keypair" @@ -429,8 +431,7 @@ func ExampleManageSellOffer() { selling := NativeAsset{} buying := CreditAsset{"ABCD", "GAS4V4O2B7DW5T7IQRPEEVCRXMDZESKISR7DVIGKZQYYV3OSQ5SH5LVP"} sellAmount := "100" - price := "0.01" - op, err := CreateOfferOp(selling, buying, sellAmount, price) + op, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01")) check(err) tx, err := NewTransaction( @@ -496,9 +497,8 @@ func ExampleManageSellOffer_updateOffer() { selling := NativeAsset{} buying := CreditAsset{"ABCD", "GAS4V4O2B7DW5T7IQRPEEVCRXMDZESKISR7DVIGKZQYYV3OSQ5SH5LVP"} sellAmount := "50" - price := "0.02" offerID := int64(2497628) - op, err := UpdateOfferOp(selling, buying, sellAmount, price, offerID) + op, err := UpdateOfferOp(selling, buying, sellAmount, price.MustParse("0.02"), offerID) check(err) tx, err := NewTransaction( @@ -533,7 +533,7 @@ func ExampleCreatePassiveSellOffer() { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", "GAS4V4O2B7DW5T7IQRPEEVCRXMDZESKISR7DVIGKZQYYV3OSQ5SH5LVP"}, Amount: "10", - Price: "1.0", + Price: xdr.Price{1, 1}, } tx, err := NewTransaction( @@ -682,7 +682,7 @@ func ExampleManageBuyOffer() { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", "GDQNY3PBOJOKYZSRMK2S7LHHGWZIUISD4QORETLMXEWXBI7KFZZMKTL3"}, Amount: "100", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } @@ -1040,8 +1040,8 @@ func ExampleLiquidityPoolDeposit() { LiquidityPoolID: poolId, MaxAmountA: "0.1000000", MaxAmountB: "0.1000000", - MinPrice: "0.1000000", - MaxPrice: "0.1000000", + MinPrice: price.MustParse("0.1000000"), + MaxPrice: price.MustParse("0.1000000"), }, } diff --git a/txnbuild/helpers.go b/txnbuild/helpers.go index 86dfcece98..87f548c58d 100644 --- a/txnbuild/helpers.go +++ b/txnbuild/helpers.go @@ -84,6 +84,19 @@ func validateAmount(n interface{}) error { return nil } +func validatePrice(p xdr.Price) error { + if p.N == 0 { + return errors.Errorf("price cannot be 0: %d/%d", p.N, p.D) + } + if p.D == 0 { + return errors.Errorf("price denominator cannot be 0: %d/%d", p.N, p.D) + } + if p.N < 0 || p.D < 0 { + return errors.Errorf("price cannot be negative: %d/%d", p.N, p.D) + } + return nil +} + // validateAssetCode checks if the provided asset is valid as an asset code. // It returns an error if the asset is invalid. // The asset must be non native (XLM) with a valid asset code. @@ -141,7 +154,7 @@ func validateChangeTrustAsset(asset ChangeTrustAsset) error { // validatePassiveOffer checks if the fields of a CreatePassiveOffer struct are valid. // It checks that the buying and selling assets are valid stellar assets, and that amount and price are valid. // It returns an error if any field is invalid. -func validatePassiveOffer(buying, selling Asset, offerAmount, price string) error { +func validatePassiveOffer(buying, selling Asset, offerAmount string, price xdr.Price) error { // Note: see discussion on how this can be improved: // https://github.com/stellar/go/pull/1707#discussion_r321508440 err := validateStellarAsset(buying) @@ -159,7 +172,7 @@ func validatePassiveOffer(buying, selling Asset, offerAmount, price string) erro return NewValidationError("Amount", err.Error()) } - err = validateAmount(price) + err = validatePrice(price) if err != nil { return NewValidationError("Price", err.Error()) } @@ -170,7 +183,7 @@ func validatePassiveOffer(buying, selling Asset, offerAmount, price string) erro // validateOffer checks if the fields of ManageBuyOffer or ManageSellOffer struct are valid. // It checks that the buying and selling assets are valid stellar assets, and that amount, price and offerID // are valid. It returns an error if any field is invalid. -func validateOffer(buying, selling Asset, offerAmount, price string, offerID int64) error { +func validateOffer(buying, selling Asset, offerAmount string, price xdr.Price, offerID int64) error { err := validatePassiveOffer(buying, selling, offerAmount, price) if err != nil { return err diff --git a/txnbuild/helpers_test.go b/txnbuild/helpers_test.go index 3a1414580c..daff17b034 100644 --- a/txnbuild/helpers_test.go +++ b/txnbuild/helpers_test.go @@ -268,7 +268,7 @@ func TestValidatePassiveOfferInvalidAmount(t *testing.T) { cpo := CreatePassiveSellOffer{ Buying: buying, Selling: selling, - Price: "1", + Price: xdr.Price{1, 1}, Amount: "-1", } err := validatePassiveOffer(cpo.Buying, cpo.Selling, cpo.Amount, cpo.Price) @@ -284,12 +284,12 @@ func TestValidatePassiveOfferInvalidPrice(t *testing.T) { cpo := CreatePassiveSellOffer{ Buying: buying, Selling: selling, - Price: "-1", + Price: xdr.Price{-1, 1}, Amount: "10", } err := validatePassiveOffer(cpo.Buying, cpo.Selling, cpo.Amount, cpo.Price) assert.Error(t, err) - expectedErrMsg := "Field: Price, Error: amount can not be negative" + expectedErrMsg := "Field: Price, Error: price cannot be negative: -1/1" require.EqualError(t, err, expectedErrMsg, "valid price is required") } @@ -299,7 +299,7 @@ func TestValidatePassiveOfferInvalidAsset(t *testing.T) { cpo := CreatePassiveSellOffer{ Buying: buying, Selling: selling, - Price: "1", + Price: xdr.Price{1, 1}, Amount: "10", } err := validatePassiveOffer(cpo.Buying, cpo.Selling, cpo.Amount, cpo.Price) @@ -313,7 +313,7 @@ func TestValidatePassiveOfferInvalidAsset(t *testing.T) { cpo1 := CreatePassiveSellOffer{ Buying: buying1, Selling: selling1, - Price: "1", + Price: xdr.Price{1, 1}, Amount: "10", } err = validatePassiveOffer(cpo1.Buying, cpo1.Selling, cpo1.Amount, cpo1.Price) @@ -329,7 +329,7 @@ func TestValidateOfferManageBuyOffer(t *testing.T) { mbo := ManageBuyOffer{ Buying: buying, Selling: selling, - Price: "1", + Price: xdr.Price{1, 1}, Amount: "10", OfferID: -1, } @@ -346,7 +346,7 @@ func TestValidateOfferManageSellOffer(t *testing.T) { mso := ManageSellOffer{ Buying: buying, Selling: selling, - Price: "1", + Price: xdr.Price{1, 1}, Amount: "10", OfferID: -1, } diff --git a/txnbuild/liquidity_pool_deposit.go b/txnbuild/liquidity_pool_deposit.go index 5b87f850ff..479f7d1a33 100644 --- a/txnbuild/liquidity_pool_deposit.go +++ b/txnbuild/liquidity_pool_deposit.go @@ -14,8 +14,8 @@ type LiquidityPoolDeposit struct { LiquidityPoolID LiquidityPoolId MaxAmountA string MaxAmountB string - MinPrice string - MaxPrice string + MinPrice xdr.Price + MaxPrice xdr.Price } // NewLiquidityPoolDeposit creates a new LiquidityPoolDeposit operation, @@ -26,7 +26,7 @@ func NewLiquidityPoolDeposit( sourceAccount string, a, b AssetAmount, minPrice, - maxPrice string, + maxPrice xdr.Price, ) (LiquidityPoolDeposit, error) { if b.Asset.LessThan(a.Asset) { return LiquidityPoolDeposit{}, errors.New("AssetA must be <= AssetB") @@ -64,22 +64,12 @@ func (lpd *LiquidityPoolDeposit) BuildXDR() (xdr.Operation, error) { return xdr.Operation{}, errors.Wrap(err, "failed to parse 'MaxAmountB'") } - var minPrice, maxPrice price - err = minPrice.parse(lpd.MinPrice) - if err != nil { - return xdr.Operation{}, errors.Wrap(err, "failed to parse 'MinPrice'") - } - err = maxPrice.parse(lpd.MaxPrice) - if err != nil { - return xdr.Operation{}, errors.Wrap(err, "failed to parse 'MaxPrice'") - } - xdrOp := xdr.LiquidityPoolDepositOp{ LiquidityPoolId: xdrLiquidityPoolId, MaxAmountA: xdrMaxAmountA, MaxAmountB: xdrMaxAmountB, - MinPrice: minPrice.toXDR(), - MaxPrice: maxPrice.toXDR(), + MinPrice: lpd.MinPrice, + MaxPrice: lpd.MaxPrice, } opType := xdr.OperationTypeLiquidityPoolDeposit @@ -109,10 +99,10 @@ func (lpd *LiquidityPoolDeposit) FromXDR(xdrOp xdr.Operation) error { lpd.MaxAmountA = amount.String(result.MaxAmountA) lpd.MaxAmountB = amount.String(result.MaxAmountB) if result.MinPrice != (xdr.Price{}) { - lpd.MinPrice = priceFromXDR(result.MinPrice).string() + lpd.MinPrice = result.MinPrice } if result.MaxPrice != (xdr.Price{}) { - lpd.MaxPrice = priceFromXDR(result.MaxPrice).string() + lpd.MaxPrice = result.MaxPrice } return nil @@ -131,12 +121,12 @@ func (lpd *LiquidityPoolDeposit) Validate() error { return NewValidationError("MaxAmountB", err.Error()) } - err = validateAmount(lpd.MinPrice) + err = validatePrice(lpd.MinPrice) if err != nil { return NewValidationError("MinPrice", err.Error()) } - err = validateAmount(lpd.MaxPrice) + err = validatePrice(lpd.MaxPrice) if err != nil { return NewValidationError("MaxPrice", err.Error()) } diff --git a/txnbuild/liquidity_pool_deposit_test.go b/txnbuild/liquidity_pool_deposit_test.go index 7abd8b721a..15f53ad67a 100644 --- a/txnbuild/liquidity_pool_deposit_test.go +++ b/txnbuild/liquidity_pool_deposit_test.go @@ -1,6 +1,7 @@ package txnbuild import ( + "github.com/stellar/go/price" "testing" "github.com/stretchr/testify/assert" @@ -22,8 +23,8 @@ func TestNewLiquidityPoolDeposit(t *testing.T) { "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H", AssetAmount{assetA, "0.1000000"}, AssetAmount{assetB, "0.2000000"}, - "0.3", - "0.4", + price.MustParse("0.3"), + price.MustParse("0.4"), ) require.NoError(t, err) assert.Equal(t, LiquidityPoolDeposit{ @@ -31,8 +32,8 @@ func TestNewLiquidityPoolDeposit(t *testing.T) { LiquidityPoolID: poolId, MaxAmountA: "0.1000000", MaxAmountB: "0.2000000", - MinPrice: "0.3", - MaxPrice: "0.4", + MinPrice: price.MustParse("0.3"), + MaxPrice: price.MustParse("0.4"), }, lpd) }) @@ -41,8 +42,8 @@ func TestNewLiquidityPoolDeposit(t *testing.T) { "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H", AssetAmount{assetB, "0.1000000"}, AssetAmount{assetA, "0.2000000"}, - "0.3", - "0.4", + price.MustParse("0.3"), + price.MustParse("0.4"), ) require.EqualError(t, err, "AssetA must be <= AssetB") }) @@ -62,8 +63,8 @@ func TestLiquidityPoolDepositRoundTrip(t *testing.T) { LiquidityPoolID: poolId, MaxAmountA: "0.1000000", MaxAmountB: "0.2000000", - MinPrice: "0.3", - MaxPrice: "0.4", + MinPrice: price.MustParse("0.3"), + MaxPrice: price.MustParse("0.4"), } testOperationsMarshallingRoundtrip(t, []Operation{lpd}, false) @@ -74,8 +75,8 @@ func TestLiquidityPoolDepositRoundTrip(t *testing.T) { LiquidityPoolID: poolId, MaxAmountA: "0.1000000", MaxAmountB: "0.2000000", - MinPrice: "0.3", - MaxPrice: "0.4", + MinPrice: price.MustParse("0.3"), + MaxPrice: price.MustParse("0.4"), } testOperationsMarshallingRoundtrip(t, []Operation{lpd}, true) diff --git a/txnbuild/manage_buy_offer.go b/txnbuild/manage_buy_offer.go index 6c1ed9f2ed..18f2e0d792 100644 --- a/txnbuild/manage_buy_offer.go +++ b/txnbuild/manage_buy_offer.go @@ -12,8 +12,7 @@ type ManageBuyOffer struct { Selling Asset Buying Asset Amount string - Price string - price price + Price xdr.Price OfferID int64 SourceAccount string } @@ -35,16 +34,12 @@ func (mo *ManageBuyOffer) BuildXDR() (xdr.Operation, error) { return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'") } - if err = mo.price.parse(mo.Price); err != nil { - return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Price'") - } - opType := xdr.OperationTypeManageBuyOffer xdrOp := xdr.ManageBuyOfferOp{ Selling: xdrSelling, Buying: xdrBuying, BuyAmount: xdrAmount, - Price: mo.price.toXDR(), + Price: mo.Price, OfferId: xdr.Int64(mo.OfferID), } body, err := xdr.NewOperationBody(opType, xdrOp) @@ -67,10 +62,7 @@ func (mo *ManageBuyOffer) FromXDR(xdrOp xdr.Operation) error { mo.SourceAccount = accountFromXDR(xdrOp.SourceAccount) mo.OfferID = int64(result.OfferId) mo.Amount = amount.String(result.BuyAmount) - if result.Price != (xdr.Price{}) { - mo.price.fromXDR(result.Price) - mo.Price = mo.price.string() - } + mo.Price = result.Price buyingAsset, err := assetFromXDR(result.Buying) if err != nil { return errors.Wrap(err, "error parsing buying_asset in manage_buy_offer operation") diff --git a/txnbuild/manage_buy_offer_test.go b/txnbuild/manage_buy_offer_test.go index a9d67d4296..4bd49f5a86 100644 --- a/txnbuild/manage_buy_offer_test.go +++ b/txnbuild/manage_buy_offer_test.go @@ -1,6 +1,7 @@ package txnbuild import ( + "github.com/stellar/go/price" "github.com/stellar/go/xdr" "testing" @@ -16,7 +17,7 @@ func TestManageBuyOfferValidateSellingAsset(t *testing.T) { Selling: CreditAsset{"", kp0.Address()}, Buying: NativeAsset{}, Amount: "100", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } @@ -44,7 +45,7 @@ func TestManageBuyOfferValidateBuyingAsset(t *testing.T) { Selling: CreditAsset{"ABC", kp0.Address()}, Buying: CreditAsset{"XYZ", ""}, Amount: "100", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } @@ -72,7 +73,7 @@ func TestManageBuyOfferValidateAmount(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } @@ -100,7 +101,7 @@ func TestManageBuyOfferValidatePrice(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "0", - Price: "-0.01", + Price: xdr.Price{-1, 100}, OfferID: 0, } @@ -114,7 +115,7 @@ func TestManageBuyOfferValidatePrice(t *testing.T) { }, ) if assert.Error(t, err) { - expected := "validation failed for *txnbuild.ManageBuyOffer operation: Field: Price, Error: amount can not be negative" + expected := "validation failed for *txnbuild.ManageBuyOffer operation: Field: Price, Error: price cannot be negative: -1/100" assert.Contains(t, err.Error(), expected) } } @@ -128,7 +129,7 @@ func TestManageBuyOfferValidateOfferID(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "0", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: -1, } @@ -154,7 +155,7 @@ func TestManageBuyOfferPrice(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "1", - Price: "0.000000001", + Price: price.MustParse("0.000000001"), OfferID: 1, } @@ -162,13 +163,10 @@ func TestManageBuyOfferPrice(t *testing.T) { 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) } func TestManageBuyOfferRoundtrip(t *testing.T) { @@ -177,7 +175,7 @@ func TestManageBuyOfferRoundtrip(t *testing.T) { Selling: CreditAsset{"USD", "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H"}, Buying: NativeAsset{}, Amount: "100.0000000", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } testOperationsMarshallingRoundtrip(t, []Operation{&manageBuyOffer}, false) @@ -188,7 +186,7 @@ func TestManageBuyOfferRoundtrip(t *testing.T) { Selling: CreditAsset{"USD", "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H"}, Buying: NativeAsset{}, Amount: "100.0000000", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } testOperationsMarshallingRoundtrip(t, []Operation{&manageBuyOffer}, true) diff --git a/txnbuild/manage_offer.go b/txnbuild/manage_offer.go index fa0c0aa39f..810eba3d67 100644 --- a/txnbuild/manage_offer.go +++ b/txnbuild/manage_offer.go @@ -9,7 +9,7 @@ import ( // CreateOfferOp returns a ManageSellOffer operation to create a new offer, by // setting the OfferID to "0". The sourceAccount is optional, and if not provided, // will be that of the surrounding transaction. -func CreateOfferOp(selling, buying Asset, amount, price string, sourceAccount ...string) (ManageSellOffer, error) { +func CreateOfferOp(selling, buying Asset, amount string, price xdr.Price, sourceAccount ...string) (ManageSellOffer, error) { if len(sourceAccount) > 1 { return ManageSellOffer{}, errors.New("offer can't have multiple source accounts") } @@ -29,7 +29,7 @@ func CreateOfferOp(selling, buying Asset, amount, price string, sourceAccount .. // UpdateOfferOp returns a ManageSellOffer operation to update an offer. // The sourceAccount is optional, and if not provided, will be that of // the surrounding transaction. -func UpdateOfferOp(selling, buying Asset, amount, price string, offerID int64, sourceAccount ...string) (ManageSellOffer, error) { +func UpdateOfferOp(selling, buying Asset, amount string, price xdr.Price, offerID int64, sourceAccount ...string) (ManageSellOffer, error) { if len(sourceAccount) > 1 { return ManageSellOffer{}, errors.New("offer can't have multiple source accounts") } @@ -61,7 +61,10 @@ func DeleteOfferOp(offerID int64, sourceAccount ...string) (ManageSellOffer, err Selling: NativeAsset{}, Buying: CreditAsset{Code: "FAKE", Issuer: "GBAQPADEYSKYMYXTMASBUIS5JI3LMOAWSTM2CHGDBJ3QDDPNCSO3DVAA"}, Amount: "0", - Price: "1", + Price: xdr.Price{ + N: 1, + D: 1, + }, OfferID: offerID, } if len(sourceAccount) == 1 { @@ -76,8 +79,7 @@ type ManageSellOffer struct { Selling Asset Buying Asset Amount string - Price string - price price + Price xdr.Price OfferID int64 SourceAccount string } @@ -99,16 +101,12 @@ func (mo *ManageSellOffer) BuildXDR() (xdr.Operation, error) { return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Amount'") } - if err = mo.price.parse(mo.Price); err != nil { - return xdr.Operation{}, errors.Wrap(err, "failed to parse 'Price'") - } - opType := xdr.OperationTypeManageSellOffer xdrOp := xdr.ManageSellOfferOp{ Selling: xdrSelling, Buying: xdrBuying, Amount: xdrAmount, - Price: mo.price.toXDR(), + Price: mo.Price, OfferId: xdr.Int64(mo.OfferID), } body, err := xdr.NewOperationBody(opType, xdrOp) @@ -131,10 +129,7 @@ func (mo *ManageSellOffer) FromXDR(xdrOp xdr.Operation) error { mo.SourceAccount = accountFromXDR(xdrOp.SourceAccount) mo.OfferID = int64(result.OfferId) mo.Amount = amount.String(result.Amount) - if result.Price != (xdr.Price{}) { - mo.price.fromXDR(result.Price) - mo.Price = mo.price.string() - } + mo.Price = result.Price buyingAsset, err := assetFromXDR(result.Buying) if err != nil { return errors.Wrap(err, "error parsing buying_asset in manage_sell_offer operation") diff --git a/txnbuild/manage_offer_test.go b/txnbuild/manage_offer_test.go index 63d9209ed4..d8b7504209 100644 --- a/txnbuild/manage_offer_test.go +++ b/txnbuild/manage_offer_test.go @@ -1,6 +1,7 @@ package txnbuild import ( + "github.com/stellar/go/price" "github.com/stellar/go/xdr" "testing" @@ -15,8 +16,7 @@ func TestManageSellOfferValidateSellingAsset(t *testing.T) { selling := CreditAsset{"", kp0.Address()} buying := NativeAsset{} sellAmount := "100" - price := "0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01")) check(err) _, err = NewTransaction( @@ -42,8 +42,7 @@ func TestManageSellOfferValidateBuyingAsset(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"", kp0.Address()} sellAmount := "100" - price := "0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01")) check(err) _, err = NewTransaction( @@ -69,8 +68,7 @@ func TestManageSellOfferValidateAmount(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "-1" - price := "0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01")) check(err) _, err = NewTransaction( @@ -96,8 +94,7 @@ func TestManageSellOfferValidatePrice(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "0" - price := "-0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, xdr.Price{-1, 100}) check(err) _, err = NewTransaction( @@ -110,7 +107,7 @@ func TestManageSellOfferValidatePrice(t *testing.T) { }, ) if assert.Error(t, err) { - expected := "validation failed for *txnbuild.ManageSellOffer operation: Field: Price, Error: amount can not be negative" + expected := "validation failed for *txnbuild.ManageSellOffer operation: Field: Price, Error: price cannot be negative: -1/100" assert.Contains(t, err.Error(), expected) } } @@ -124,7 +121,7 @@ func TestManageSellOfferValidateOfferID(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "0", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: -1, } @@ -150,7 +147,7 @@ func TestManageSellOfferPrice(t *testing.T) { Selling: CreditAsset{"ABCD", kp0.Address()}, Buying: NativeAsset{}, Amount: "1", - Price: "0.000000001", + Price: price.MustParse("0.000000001"), OfferID: 1, } @@ -158,13 +155,10 @@ func TestManageSellOfferPrice(t *testing.T) { 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) } func TestManageSellOfferRoundtrip(t *testing.T) { @@ -173,7 +167,7 @@ func TestManageSellOfferRoundtrip(t *testing.T) { Selling: CreditAsset{"USD", "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H"}, Buying: NativeAsset{}, Amount: "100.0000000", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } testOperationsMarshallingRoundtrip(t, []Operation{&manageSellOffer}, false) @@ -184,7 +178,7 @@ func TestManageSellOfferRoundtrip(t *testing.T) { Selling: CreditAsset{"USD", "GB7BDSZU2Y27LYNLALKKALB52WS2IZWYBDGY6EQBLEED3TJOCVMZRH7H"}, Buying: NativeAsset{}, Amount: "100.0000000", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } testOperationsMarshallingRoundtrip(t, []Operation{&manageSellOffer}, true) diff --git a/txnbuild/operation_test.go b/txnbuild/operation_test.go index 57cb2c2e1b..d462e3a9c5 100644 --- a/txnbuild/operation_test.go +++ b/txnbuild/operation_test.go @@ -125,7 +125,7 @@ func TestManageSellOfferFromXDR(t *testing.T) { assert.Equal(t, "GBUKBCG5VLRKAVYAIREJRUJHOKLIADZJOICRW43WVJCLES52BDOTCQZU", mso.SourceAccount, "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", mso.Price, "Price should match") + assert.Equal(t, xdr.Price{5, 1}, 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) @@ -139,7 +139,7 @@ func TestManageSellOfferFromXDR(t *testing.T) { assert.Equal(t, "", 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", mso.Price, "Price should match") + assert.Equal(t, xdr.Price{5, 1}, 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) @@ -162,7 +162,7 @@ func TestManageBuyOfferFromXDR(t *testing.T) { assert.Equal(t, "GBUKBCG5VLRKAVYAIREJRUJHOKLIADZJOICRW43WVJCLES52BDOTCQZU", mbo.SourceAccount, "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.5", mbo.Price, "Price should match") + assert.Equal(t, xdr.Price{1, 2}, 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) @@ -176,7 +176,7 @@ func TestManageBuyOfferFromXDR(t *testing.T) { assert.Equal(t, "", 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.6", mbo.Price, "Price should match") + assert.Equal(t, xdr.Price{3, 5}, 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) @@ -198,7 +198,7 @@ func TestCreatePassiveSellOfferFromXDR(t *testing.T) { if assert.NoError(t, err) { assert.Equal(t, "", cpo.SourceAccount, "source accounts should match") assert.Equal(t, "10.0000000", cpo.Amount, "Amount should match") - assert.Equal(t, "1", cpo.Price, "Price should match") + assert.Equal(t, xdr.Price{1, 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) diff --git a/txnbuild/price.go b/txnbuild/price.go deleted file mode 100644 index abfa6f74fe..0000000000 --- a/txnbuild/price.go +++ /dev/null @@ -1,69 +0,0 @@ -package txnbuild - -import ( - "strconv" - - pricepkg "github.com/stellar/go/price" - "github.com/stellar/go/support/errors" - "github.com/stellar/go/xdr" -) - -type price struct { - n int - d int - s string -} - -func (p *price) parse(s string) error { - if len(s) == 0 { - return errors.New("cannot parse price from empty string") - } - - xdrPrice, err := pricepkg.Parse(s) - if err != nil { - return errors.Wrap(err, "failed to parse price from string") - } - - if len(p.s) > 0 { - inverse, err := pricepkg.Parse(p.s) - if err == nil && xdrPrice == inverse { - return nil - } - } - - p.n = int(xdrPrice.N) - p.d = int(xdrPrice.D) - p.s = s - return nil -} - -func (p *price) fromXDR(xdrPrice xdr.Price) { - n := int(xdrPrice.N) - d := int(xdrPrice.D) - if n == p.n && d == p.d { - return - } - p.n = n - p.d = d - v := float64(n) / float64(d) - // The special precision -1 uses the smallest number of digits - // necessary such that ParseFloat will return f exactly. - p.s = strconv.FormatFloat(v, 'f', -1, 32) -} - -func priceFromXDR(xdrPrice xdr.Price) price { - var p price - p.fromXDR(xdrPrice) - return p -} - -func (p price) string() string { - return p.s -} - -func (p price) toXDR() xdr.Price { - return xdr.Price{ - N: xdr.Int32(p.n), - D: xdr.Int32(p.d), - } -} diff --git a/txnbuild/price_test.go b/txnbuild/price_test.go deleted file mode 100644 index 70b94453ec..0000000000 --- a/txnbuild/price_test.go +++ /dev/null @@ -1,82 +0,0 @@ -package txnbuild - -import ( - "math" - "testing" - - "github.com/stellar/go/xdr" - "github.com/stretchr/testify/assert" -) - -func TestPriceFromXDR(t *testing.T) { - for _, testCase := range []struct { - name string - input xdr.Price - expected price - }{ - { - "1/2", - xdr.Price{N: 1, D: 2}, - price{n: 1, d: 2, s: "0.5"}, - }, - { - "1", - xdr.Price{N: 1, D: 1}, - price{n: 1, d: 1, s: "1"}, - }, - { - "1 / 1000000000", - xdr.Price{N: 1, D: 1000000000}, - price{n: 1, d: 1000000000, s: "0.000000001"}, - }, - { - "max int 32", - xdr.Price{N: math.MaxInt32, D: 1}, - price{n: math.MaxInt32, d: 1, s: "2147483600"}, - }, - { - "1/3", - xdr.Price{N: 1, D: 3}, - price{n: 1, d: 3, s: "0.33333334"}, - }, - } { - t.Run(testCase.name, func(t *testing.T) { - var p price - p.fromXDR(testCase.input) - - assert.Equal(t, testCase.expected, p) - assert.Equal(t, testCase.input, p.toXDR()) - - assert.NoError(t, p.parse(p.string())) - assert.Equal(t, testCase.expected, p) - }) - } -} - -func TestPriceParse(t *testing.T) { - var p price - assert.NoError(t, p.parse("0.5")) - assert.Equal(t, price{n: 1, d: 2, s: "0.5"}, p) - - assert.NoError(t, p.parse("00.5")) - assert.Equal(t, price{n: 1, d: 2, s: "0.5"}, p) - - assert.NoError(t, p.parse("0.50")) - assert.Equal(t, price{n: 1, d: 2, s: "0.5"}, p) - - assert.EqualError(t, p.parse(""), "cannot parse price from empty string") - assert.Equal(t, price{n: 1, d: 2, s: "0.5"}, p) - - assert.EqualError(t, p.parse("abc"), "failed to parse price from string: invalid price format: abc") - assert.Equal(t, price{n: 1, d: 2, s: "0.5"}, p) - - assert.NoError(t, p.parse("0.33333334")) - assert.Equal(t, price{n: 16666667, d: 50000000, s: "0.33333334"}, p) - - p.fromXDR(xdr.Price{N: 1, D: 3}) - assert.Equal(t, price{n: 1, d: 3, s: "0.33333334"}, p) - assert.NoError(t, p.parse("00.33333334")) - assert.Equal(t, price{n: 1, d: 3, s: "0.33333334"}, p) - assert.NoError(t, p.parse("0.333333340")) - assert.Equal(t, price{n: 1, d: 3, s: "0.33333334"}, p) -} diff --git a/txnbuild/signers_test.go b/txnbuild/signers_test.go index 76a70be69e..6dd98792cf 100644 --- a/txnbuild/signers_test.go +++ b/txnbuild/signers_test.go @@ -1,6 +1,7 @@ package txnbuild import ( + "github.com/stellar/go/price" "testing" "github.com/stellar/go/keypair" @@ -165,7 +166,7 @@ func TestCreatePassiveSellOfferMultSigners(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", kp0.Address()}, Amount: "10", - Price: "1.0", + Price: xdr.Price{1, 1}, SourceAccount: kp1.Address(), } @@ -251,8 +252,7 @@ func TestManageOfferCreateMultSigners(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "100" - price := "0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price, kp1.Address()) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01"), kp1.Address()) check(err) received, err := newSignedTransaction( @@ -308,9 +308,8 @@ func TestManageOfferUpdateMultSigners(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "50" - price := "0.02" offerID := int64(2497628) - updateOffer, err := UpdateOfferOp(selling, buying, sellAmount, price, offerID, kp1.Address()) + updateOffer, err := UpdateOfferOp(selling, buying, sellAmount, price.MustParse("0.02"), offerID, kp1.Address()) check(err) received, err := newSignedTransaction( diff --git a/txnbuild/transaction_test.go b/txnbuild/transaction_test.go index 02b3b3514b..7269d696e9 100644 --- a/txnbuild/transaction_test.go +++ b/txnbuild/transaction_test.go @@ -3,6 +3,7 @@ package txnbuild import ( "crypto/sha256" "encoding/base64" + "github.com/stellar/go/price" "strings" "testing" "time" @@ -722,8 +723,7 @@ func TestManageSellOfferNewOffer(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "100" - price := "0.01" - createOffer, err := CreateOfferOp(selling, buying, sellAmount, price) + createOffer, err := CreateOfferOp(selling, buying, sellAmount, price.MustParse("0.01")) check(err) received, err := newSignedTransaction( @@ -776,9 +776,8 @@ func TestManageSellOfferUpdateOffer(t *testing.T) { selling := NativeAsset{} buying := CreditAsset{"ABCD", kp0.Address()} sellAmount := "50" - price := "0.02" offerID := int64(2497628) - updateOffer, err := UpdateOfferOp(selling, buying, sellAmount, price, offerID) + updateOffer, err := UpdateOfferOp(selling, buying, sellAmount, price.MustParse("0.02"), offerID) check(err) received, err := newSignedTransaction( @@ -807,7 +806,7 @@ func TestCreatePassiveSellOffer(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", kp0.Address()}, Amount: "10", - Price: "1.0", + Price: xdr.Price{1, 1}, } received, err := newSignedTransaction( @@ -956,7 +955,7 @@ func TestManageBuyOfferNewOffer(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", kp0.Address()}, Amount: "100", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: 0, } @@ -985,7 +984,7 @@ func TestManageBuyOfferDeleteOffer(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", kp1.Address()}, Amount: "0", - Price: "0.01", + Price: price.MustParse("0.01"), OfferID: int64(2921622), } @@ -1014,7 +1013,7 @@ func TestManageBuyOfferUpdateOffer(t *testing.T) { Selling: NativeAsset{}, Buying: CreditAsset{"ABCD", kp1.Address()}, Amount: "50", - Price: "0.02", + Price: price.MustParse("0.02"), OfferID: int64(2921622), }