Пример #1
0
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)
		})
	})
}
Пример #2
0
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
}
Пример #3
0
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)
	}
}
Пример #4
0
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
}
Пример #5
0
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)
		})
	})
}
Пример #6
0
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)

}
Пример #7
0
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)
	}
}
Пример #8
0
				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)))
Пример #9
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())
		})
	})
})
Пример #10
0
		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"}
				})
Пример #11
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())
		})
	})
})
Пример #12
0
// 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
}
Пример #13
0
// 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
}
Пример #14
0
// 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))
}
Пример #15
0
			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())
Пример #16
0
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
}
Пример #17
0
// 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
}
Пример #18
0
			})

			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)))
			})
		})
	})
})