func TestFinder(t *testing.T) { Convey("Finder", t, func() { test.LoadScenario("paths") conn := test.OpenDatabase(test.StellarCoreDatabaseUrl()) defer conn.Close() finder := &Finder{ Ctx: test.Context(), SqlQuery: db.SqlQuery{conn}, } native := makeAsset(xdr.AssetTypeAssetTypeNative, "", "") usd := makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN") eur := makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN") Convey("Find", func() { query := paths.Query{ DestinationAddress: "GAEDTJ4PPEFVW5XV2S7LUXBEHNQMX5Q2GM562RJGOQG7GVCE5H3HIB4V", DestinationAsset: eur, DestinationAmount: xdr.Int64(200000000), SourceAssets: []xdr.Asset{usd}, } paths, err := finder.Find(query) So(err, ShouldBeNil) So(len(paths), ShouldEqual, 4) query.DestinationAmount = xdr.Int64(200000001) paths, err = finder.Find(query) So(err, ShouldBeNil) So(len(paths), ShouldEqual, 2) query.DestinationAmount = xdr.Int64(500000001) paths, err = finder.Find(query) So(err, ShouldBeNil) So(len(paths), ShouldEqual, 0) }) Convey("regression: paths that involve native currencies can be found", func() { query := paths.Query{ DestinationAddress: "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN", DestinationAsset: native, DestinationAmount: xdr.Int64(1), SourceAssets: []xdr.Asset{usd, native}, } paths, err := finder.Find(query) So(err, ShouldBeNil) So(len(paths), ShouldEqual, 2) }) }) }
func (this *Ledger) Populate(ctx context.Context, row db.LedgerRecord) { this.ID = row.LedgerHash this.PT = row.PagingToken() this.Hash = row.LedgerHash this.PrevHash = row.PreviousLedgerHash.String this.Sequence = row.Sequence this.TransactionCount = row.TransactionCount this.OperationCount = row.OperationCount this.ClosedAt = row.ClosedAt this.TotalCoins = amount.String(xdr.Int64(row.TotalCoins)) this.FeePool = amount.String(xdr.Int64(row.FeePool)) this.BaseFee = row.BaseFee this.BaseReserve = amount.String(xdr.Int64(row.BaseReserve)) this.MaxTxSetSize = row.MaxTxSetSize self := fmt.Sprintf("/ledgers/%d", row.Sequence) lb := hal.LinkBuilder{httpx.BaseURL(ctx)} this.Links.Self = lb.Link(self) this.Links.Transactions = lb.PagedLink(self, "transactions") this.Links.Operations = lb.PagedLink(self, "operations") this.Links.Payments = lb.PagedLink(self, "payments") this.Links.Effects = lb.PagedLink(self, "effects") return }
func TestFinder(t *testing.T) { tt := test.Start(t).Scenario("paths") defer tt.Finish() finder := &Finder{ Q: &core.Q{Repo: tt.CoreRepo()}, } native := makeAsset(xdr.AssetTypeAssetTypeNative, "", "") usd := makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN") eur := makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN") query := paths.Query{ DestinationAddress: "GAEDTJ4PPEFVW5XV2S7LUXBEHNQMX5Q2GM562RJGOQG7GVCE5H3HIB4V", DestinationAsset: eur, DestinationAmount: xdr.Int64(200000000), SourceAssets: []xdr.Asset{usd}, } p, err := finder.Find(query) if tt.Assert.NoError(err) { tt.Assert.Len(p, 3) } query.DestinationAmount = xdr.Int64(200000001) p, err = finder.Find(query) if tt.Assert.NoError(err) { tt.Assert.Len(p, 2) } query.DestinationAmount = xdr.Int64(500000001) p, err = finder.Find(query) if tt.Assert.NoError(err) { tt.Assert.Len(p, 0) } // regression: paths that involve native currencies can be found query = paths.Query{ DestinationAddress: "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN", DestinationAsset: native, DestinationAmount: xdr.Int64(1), SourceAssets: []xdr.Asset{usd, native}, } p, err = finder.Find(query) if tt.Assert.NoError(err) { tt.Assert.Len(p, 2) } }
func Parse(v string) (xdr.Int64, error) { var f, o, r big.Rat _, ok := f.SetString(v) if !ok { return xdr.Int64(0), fmt.Errorf("cannot parse amount: %s", v) } o.SetInt64(One) r.Mul(&f, &o) is := r.FloatString(0) i, err := strconv.ParseInt(is, 10, 64) if err != nil { return xdr.Int64(0), err } return xdr.Int64(i), nil }
func TestOrderBook(t *testing.T) { Convey("orderBook", t, func() { test.LoadScenario("paths") conn := test.OpenDatabase(test.StellarCoreDatabaseUrl()) defer conn.Close() ob := orderBook{ Selling: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), Buying: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), DB: db.SqlQuery{conn}, } Convey("Cost", func() { r, err := ob.Cost(ob.Buying, 10) So(err, ShouldBeNil) So(r, ShouldEqual, xdr.Int64(10)) // this cost should consume the entire lowest priced order, whose price // is 1.0, thus the output should be the same r, err = ob.Cost(ob.Buying, 100000000) So(err, ShouldBeNil) So(r, ShouldEqual, xdr.Int64(100000000)) // now we are taking from the next offer, where the price is 2.0 r, err = ob.Cost(ob.Buying, 100000001) So(err, ShouldBeNil) So(r, ShouldEqual, xdr.Int64(100000002)) r, err = ob.Cost(ob.Buying, 500000000) So(err, ShouldBeNil) So(r, ShouldEqual, xdr.Int64(900000000)) r, err = ob.Cost(ob.Buying, 500000001) So(err, ShouldNotBeNil) }) }) }
func TestOrderBook(t *testing.T) { tt := test.Start(t).Scenario("paths") defer tt.Finish() ob := orderBook{ Selling: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), Buying: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), Q: &core.Q{Repo: tt.CoreRepo()}, } r, err := ob.Cost(ob.Buying, 10000000) if tt.Assert.NoError(err) { tt.Assert.Equal(xdr.Int64(10000000), r) } // this cost should consume the entire lowest priced order, whose price // is 1.0, thus the output should be the same r, err = ob.Cost(ob.Buying, 100000000) if tt.Assert.NoError(err) { tt.Assert.Equal(xdr.Int64(100000000), r) } // now we are taking from the next offer, where the price is 2.0 r, err = ob.Cost(ob.Buying, 100000001) if tt.Assert.NoError(err) { tt.Assert.Equal(xdr.Int64(100000002), r) } r, err = ob.Cost(ob.Buying, 500000000) if tt.Assert.NoError(err) { tt.Assert.Equal(xdr.Int64(900000000), r) } _, err = ob.Cost(ob.Buying, 500000001) tt.Assert.Error(err) }
func TestOrderBook_BadCost(t *testing.T) { tt := test.Start(t).Scenario("bad_cost") defer tt.Finish() ob := orderBook{ Selling: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "EUR", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), Buying: makeAsset( xdr.AssetTypeAssetTypeCreditAlphanum4, "USD", "GDSBCQO34HWPGUGQSP3QBFEXVTSR2PW46UIGTHVWGWJGQKH3AFNHXHXN"), Q: &core.Q{Repo: tt.CoreRepo()}, } r, err := ob.Cost(ob.Buying, 10000000) if tt.Assert.NoError(err) { tt.Assert.Equal(xdr.Int64(2000000000), r) } }
Buying: NativeAsset(), Price: Price("41.265"), } ) JustBeforeEach(func() { subject = ManageOfferBuilder{} subject.Mutate(mut) }) Describe("CreateOffer", func() { Context("creates offer properly", func() { It("sets values properly", func() { builder := CreateOffer(rate, "20") Expect(builder.MO.Amount).To(Equal(xdr.Int64(200000000))) Expect(builder.MO.Selling.Type).To(Equal(xdr.AssetTypeAssetTypeCreditAlphanum4)) Expect(builder.MO.Selling.AlphaNum4.AssetCode).To(Equal([4]byte{'E', 'U', 'R', 0})) aid, _ := stellarbase.AddressToAccountId(rate.Selling.Issuer) Expect(builder.MO.Selling.AlphaNum4.Issuer.MustEd25519()).To(Equal(aid.MustEd25519())) Expect(builder.MO.Selling.AlphaNum12).To(BeNil()) Expect(builder.MO.Buying.Type).To(Equal(xdr.AssetTypeAssetTypeNative)) Expect(builder.MO.Buying.AlphaNum4).To(BeNil()) Expect(builder.MO.Buying.AlphaNum12).To(BeNil()) Expect(builder.MO.Price.N).To(Equal(xdr.Int32(8253))) Expect(builder.MO.Price.D).To(Equal(xdr.Int32(200))) Expect(builder.MO.OfferId).To(Equal(xdr.Uint64(0)))
Context("using a valid stellar address", func() { BeforeEach(func() { mut = SourceAccount{address} }) It("succeeds", func() { Expect(subject.Err).NotTo(HaveOccurred()) }) It("sets the destination to the correct xdr.AccountId", func() { aid, _ := stellarbase.AddressToAccountId(address) Expect(subject.O.SourceAccount.MustEd25519()).To(Equal(aid.MustEd25519())) }) }) Context("using an invalid value", func() { BeforeEach(func() { mut = SourceAccount{bad} }) It("failed", func() { Expect(subject.Err).To(HaveOccurred()) }) }) }) Describe("NativeAmount", func() { BeforeEach(func() { mut = NativeAmount{"101"} }) It("sets the starting balance properly", func() { Expect(subject.P.Asset.Type).To(Equal(xdr.AssetTypeAssetTypeNative)) Expect(subject.P.Amount).To(Equal(xdr.Int64(1010000000))) }) It("succeeds", func() { Expect(subject.Err).NotTo(HaveOccurred()) }) }) })
bad = "foo" ) Describe("Payment", func() { JustBeforeEach(func() { subject = PaymentBuilder{} subject.Mutate(mut) }) Describe("CreditAmount", func() { Context("AlphaNum4", func() { BeforeEach(func() { mut = CreditAmount{"USD", address, "50.0"} }) It("sets the asset properly", func() { Expect(subject.P.Amount).To(Equal(xdr.Int64(500000000))) Expect(subject.P.Asset.Type).To(Equal(xdr.AssetTypeAssetTypeCreditAlphanum4)) Expect(subject.P.Asset.AlphaNum4.AssetCode).To(Equal([4]byte{'U', 'S', 'D', 0})) aid, _ := stellarbase.AddressToAccountId(address) Expect(subject.P.Asset.AlphaNum4.Issuer.MustEd25519()).To(Equal(aid.MustEd25519())) Expect(subject.P.Asset.AlphaNum12).To(BeNil()) }) It("succeeds", func() { Expect(subject.Err).NotTo(HaveOccurred()) }) }) Context("AlphaNum12", func() { BeforeEach(func() { mut = CreditAmount{"ABCDEF", address, "50.0"} })
Describe("SourceAccount", func() { Context("using a valid stellar address", func() { BeforeEach(func() { mut = SourceAccount{address} }) It("succeeds", func() { Expect(subject.Err).NotTo(HaveOccurred()) }) It("sets the destination to the correct xdr.AccountId", func() { aid, _ := stellarbase.AddressToAccountId(address) Expect(subject.O.SourceAccount.MustEd25519()).To(Equal(aid.MustEd25519())) }) }) Context("using an invalid value", func() { BeforeEach(func() { mut = SourceAccount{bad} }) It("failed", func() { Expect(subject.Err).To(HaveOccurred()) }) }) }) Describe("NativeAmount", func() { BeforeEach(func() { mut = NativeAmount{"101"} }) It("sets the starting balance properly", func() { Expect(subject.CA.StartingBalance).To(Equal(xdr.Int64(1010000000))) }) It("succeeds", func() { Expect(subject.Err).NotTo(HaveOccurred()) }) }) })
// MutatePayment for NativeAmount sets the PaymentOp's currency field to // native and sets its amount to the provided integer func (m NativeAmount) MutatePayment(o *xdr.PaymentOp) error { asset, err := xdr.NewAsset(xdr.AssetTypeAssetTypeNative, nil) o.Asset = asset o.Amount = xdr.Int64(m.Amount) return err }
// MutatePayment for NativeAmount sets the PaymentOp's currency field to // native and sets its amount to the provided integer func (m NativeAmount) MutatePayment(o *xdr.PaymentOp) error { o.Currency = xdr.NewCurrencyCurrencyTypeNative() o.Amount = xdr.Int64(m.Amount) return nil }
// AmountAsString returns the amount as a string, formatted using // the amount.String() utility from go-stellar-base. func (p *PriceLevel) AmountAsString() string { return amount.String(xdr.Int64(p.Amount)) }
Expect(found).ToNot(BeNil()) Expect(found.Data.Type).To(Equal(xdr.LedgerEntryTypeAccount)) account := found.Data.MustAccount().AccountId Expect(account.Equals(masterAccount)).To(BeTrue()) }) }) Describe("StateAfter", func() { It("returns newly created entries correctly", func() { state, err := createAccount.StateAfter(newAccount.LedgerKey(), 0) Expect(err).ToNot(HaveOccurred()) Expect(state).ToNot(BeNil()) account := state.Data.MustAccount() Expect(account.Balance).To(Equal(xdr.Int64(1000000000))) }) }) Describe("StateBefore", func() { Context("Accounts", func() { It("return nil when the account was created in the operation", func() { state, err := createAccount.StateBefore(newAccount.LedgerKey(), 0) Expect(err).ToNot(HaveOccurred()) Expect(state).To(BeNil()) }) It("passes a sanity test", func() { before, err := createAccount.StateBefore(masterAccount.LedgerKey(), 0) Expect(err).ToNot(HaveOccurred()) Expect(before).ToNot(BeNil())
func (ob *orderBook) Cost(source xdr.Asset, sourceAmount xdr.Int64) (result xdr.Int64, err error) { // load offers from the two assets var ( // selling/buying types st, bt xdr.AssetType // selling/buying codes sc, bc string // selling/buying issuers si, bi string ) err = ob.Selling.Extract(&st, &sc, &si) if err != nil { return } err = ob.Buying.Extract(&bt, &bc, &bi) if err != nil { return } sql := sq. Select("amount", "pricen", "priced", "offerid"). From("offers"). Where(sq.Eq{ "sellingassettype": st, "COALESCE(sellingassetcode, '')": sc, "COALESCE(sellingissuer, '')": si}). Where(sq.Eq{ "buyingassettype": bt, "COALESCE(buyingassetcode, '')": bc, "COALESCE(buyingissuer, '')": bi}) inverted := assets.Equals(source, ob.Buying) if !inverted { sql = sql.OrderBy("price ASC") } else { sql = sql.OrderBy("price DESC") } rows, err := ob.DB.Query(context.TODO(), sql) if err != nil { return } defer rows.Close() var ( needed = int64(sourceAmount) cost int64 ) for rows.Next() { // load data from the row var available, pricen, priced, offerid int64 if inverted { err = rows.Scan(&available, &priced, &pricen, &offerid) available = mul(available, pricen, priced) } else { err = rows.Scan(&available, &pricen, &priced, &offerid) } if err != nil { return } if available >= needed { cost += mul(needed, pricen, priced) result = xdr.Int64(cost) return } cost += mul(available, pricen, priced) needed -= available } err = ErrNotEnough return }
// MutateCreateAccount for NativeAmount sets the CreateAccountOp's // StartingBalance field func (m NativeAmount) MutateCreateAccount(o *xdr.CreateAccountOp) error { o.StartingBalance = xdr.Int64(m.Amount) return nil }
}) It("failed", func() { Expect(subject.Err).To(HaveOccurred()) }) }) }) Describe("Limit", func() { Context("sets limit properly", func() { BeforeEach(func() { mut = Limit("20") }) It("sets limit value properly", func() { Expect(subject.CT.Limit).To(Equal(xdr.Int64(200000000))) }) }) Context("sets max limit properly", func() { BeforeEach(func() { mut = MaxLimit }) It("sets limit value properly", func() { Expect(subject.CT.Limit).To(Equal(xdr.Int64(9223372036854775807))) }) }) }) })