Skip to content

Commit

Permalink
Merge pull request #36 from spolu/stan-fixes
Browse files Browse the repository at this point in the history
Various fixes to cut 0.0.2-pre
  • Loading branch information
Stanislas Polu committed Jan 13, 2017
2 parents 0cf3075 + 9954350 commit 703aea4
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 31 deletions.
7 changes: 5 additions & 2 deletions TODO
Expand Up @@ -11,9 +11,8 @@

# preview

[ ] fix mint
[ ] error on offer with same currency
[ ] finish site
[ ] cut 0.0.2-pre
[ ] blog post draft
[ ] documentation
[ ] send r?
Expand All @@ -22,6 +21,7 @@

[ ] close (offer) command
[ ] pay with path of length 2
[ ] list transactions (canonical or destination)
[x] pay command
[x] check existence of quote asset on trust
[x] check credentials
Expand All @@ -45,11 +45,14 @@
# mint

[~] list endpoint
[ ] list (asset) transactions
[ ] list asset operations
[x] list asset offers (order book)
[x] list asset balances
[x] list balances
[x] list assets
[x] paying yourself with a currency you trust does not decrease the balance (expeted, tested)
[x] error on offer with same currency
[x] allow cancellation without plan computation (use offer path, move CheckCanShouldCancel to plan))
[x] reintroduce transaction expiry on top of safe cancelation
[x] propagate cancellation on syncrhonous failure
Expand Down
7 changes: 0 additions & 7 deletions cli/command/list.go
Expand Up @@ -171,7 +171,6 @@ func (c *List) ExecuteAssets(
data := [][][2]string{}
for _, a := range assets {
data = append(data, [][2]string{
[2]string{"ID", a.ID},
[2]string{"Created", fmt.Sprintf("%d", a.Created)},
[2]string{"Asset", a.Name},
})
Expand Down Expand Up @@ -207,8 +206,6 @@ func (c *List) ExecuteBalances(
data := [][][2]string{}
for _, b := range balances {
data = append(data, [][2]string{
[2]string{"ID", b.ID},
[2]string{"Created", fmt.Sprintf("%d", b.Created)},
[2]string{"Asset", b.Asset},
[2]string{"Holder", b.Holder},
[2]string{"Value", b.Value.String()},
Expand Down Expand Up @@ -240,8 +237,6 @@ func (c *List) ExecuteTrustlines(
data := [][][2]string{}
for _, o := range cOffers {
data = append(data, [][2]string{
[2]string{"ID", o.ID},
[2]string{"Created", fmt.Sprintf("%d", o.Created)},
[2]string{"Pair", o.Pair},
[2]string{"Price", o.Price},
[2]string{"Amount", o.Amount.String()},
Expand All @@ -259,8 +254,6 @@ func (c *List) ExecuteTrustlines(
data = [][][2]string{}
for _, o := range pOffers {
data = append(data, [][2]string{
[2]string{"ID", o.ID},
[2]string{"Created", fmt.Sprintf("%d", o.Created)},
[2]string{"Pair", o.Pair},
[2]string{"Price", o.Price},
[2]string{"Amount", o.Amount.String()},
Expand Down
32 changes: 30 additions & 2 deletions cli/command/pay.go
Expand Up @@ -186,7 +186,7 @@ func (c *Pay) Execute(
out.Valuf("%s\n", c.Amount.String())
out.Normf(" Path : ")
if len(c.Path) == 0 {
out.Normf("(empty)")
out.Normf("(empty)\n")
} else {
for j, o := range c.Path {
if j > 0 {
Expand Down Expand Up @@ -234,7 +234,7 @@ func (c *Pay) Execute(
out.Valuf("%s %s\n", c.QuoteAsset, c.Amount.String())
out.Normf(" Path : ")
if len(candidate.Path) == 0 {
out.Normf("(empty)")
out.Normf("(empty)\n")
} else {
for j, o := range candidate.Path {
if j > 0 {
Expand Down Expand Up @@ -270,6 +270,34 @@ func (c *Pay) Execute(
return errors.Trace(err)
}

out.Boldf("Transaction settled:\n")
out.Normf(" ID : ")
out.Valuf("%s\n", tx.ID)
out.Normf(" Created : ")
out.Valuf("%d\n", tx.Created)
out.Normf(" Owner : ")
out.Valuf("%s\n", tx.Owner)
out.Normf(" Pair : ")
out.Valuf("%s\n", tx.Pair)
out.Normf(" Amount : ")
out.Valuf("%s\n", tx.Amount.String())
out.Normf(" Destination : ")
out.Valuf("%s\n", tx.Destination)
out.Normf(" Path : ")
if len(tx.Path) == 0 {
out.Normf("(empty)\n")
} else {
for j, o := range tx.Path {
if j > 0 {
out.Normf("\n ")
}
out.Valuf(o)
}
out.Normf("\n")
}
out.Normf(" Status : ")
out.Valuf("%s\n", tx.Status)

return nil
}

Expand Down
16 changes: 16 additions & 0 deletions mint/async.go
@@ -0,0 +1,16 @@
package mint

// TkName represents a task name.
type TkName string

// TkStatus represents a task status.
type TkStatus string

const (
// TkStPending new or have been retried less than the task max retries.
TkStPending TkStatus = "pending"
// TkStSucceeded successfully executed once.
TkStSucceeded TkStatus = "succeeded"
// TkStFailed retried more than max retries with no success.
TkStFailed TkStatus = "failed"
)
2 changes: 1 addition & 1 deletion mint/async/task/expire_transaction.go
Expand Up @@ -65,7 +65,7 @@ func (t *ExpireTransaction) DeadlineForRetry(
retry uint,
) time.Time {
expiry := time.Duration(mint.TransactionExpiryMs) * time.Millisecond
return t.Created().Add(expiry + time.Duration(retry+1)*expiry)
return t.Created().Add(expiry + time.Duration(retry)*expiry)
}

// Execute idempotently runs the task to completion or errors.
Expand Down
7 changes: 7 additions & 0 deletions mint/endpoint/create_offer.go
Expand Up @@ -87,6 +87,13 @@ func (e *CreateOffer) Validate(
))
}

if e.Pair[0].Name == e.Pair[1].Name {
return errors.Trace(errors.NewUserErrorf(nil,
400, "pair_invalid",
"You cannot create an offer with the same base and quote asset.",
))
}

// Validate price.
basePrice, quotePrice, err := ValidatePrice(ctx, r.PostFormValue("price"))
if err != nil {
Expand Down
3 changes: 0 additions & 3 deletions mint/model/transaction.go
Expand Up @@ -33,7 +33,6 @@ type Transaction struct {

Status mint.TxStatus

Expiry time.Time
Lock string
Secret *string
}
Expand All @@ -56,7 +55,6 @@ func NewTransactionResource(
Amount: (*big.Int)(&transaction.Amount),
Destination: transaction.Destination,
Path: []string(transaction.Path),
Expiry: transaction.Expiry.UnixNano() / mint.TimeResolutionNs,
Status: transaction.Status,
Lock: transaction.Lock,
Operations: []mint.OperationResource{},
Expand Down Expand Up @@ -203,7 +201,6 @@ func (t *Transaction) ID() string {
func (t *Transaction) Save(
ctx context.Context,
) error {
t.Expiry = t.Expiry.UTC()
ext := db.Ext(ctx, "mint")
_, err := sqlx.NamedExec(ext, `
UPDATE transactions
Expand Down
16 changes: 0 additions & 16 deletions mint/protocol.go
Expand Up @@ -137,25 +137,9 @@ type TransactionResource struct {
Path []string `json:"path"`

Status TxStatus `json:"status"`
Expiry int64 `json:"expiry"`
Lock string `json:"lock"`
Secret *string `json:"secret"`

Operations []OperationResource `json:"operations"`
Crossings []CrossingResource `json:"crossings"`
}

// TkName represents a task name.
type TkName string

// TkStatus represents a task status.
type TkStatus string

const (
// TkStPending new or have been retried less than the task max retries.
TkStPending TkStatus = "pending"
// TkStSucceeded successfully executed once.
TkStSucceeded TkStatus = "succeeded"
// TkStFailed retried more than max retries with no success.
TkStFailed TkStatus = "failed"
)
23 changes: 23 additions & 0 deletions mint/test/functional/create_offer_test.go
Expand Up @@ -122,3 +122,26 @@ func TestCreateOfferWithInexistantAsset(
assert.Equal(t, 400, status)
assert.Equal(t, "asset_not_found", e.ErrCode)
}

func TestCreateOfferWithSameAsset(
t *testing.T,
) {
t.Parallel()
m, u, _ := setupCreateOffer(t)
defer tearDownCreateOffer(t, m)

status, raw := u[0].Post(t,
fmt.Sprintf("/offers"),
url.Values{
"pair": {fmt.Sprintf("%s[USD.2]/%s[USD.2]", u[0].Address, u[0].Address)},
"price": {"1/1"},
"amount": {"100"},
})

var e errors.ConcreteUserError
err := raw.Extract("error", &e)
assert.Nil(t, err)

assert.Equal(t, 400, status)
assert.Equal(t, "pair_invalid", e.ErrCode)
}
93 changes: 93 additions & 0 deletions mint/test/functional/create_transaction_test.go
Expand Up @@ -633,3 +633,96 @@ func TestCreateTransactionWithNoOfferAndRemoteBaseAsset(
assert.Nil(t, err)
assert.Equal(t, big.NewInt(5), (*big.Int)(&balance.Value))
}

func TestCreateTransactionUsingOfferToPayOneself(
t *testing.T,
) {
t.Parallel()
m, u, a, o := setupCreateTransaction(t)
defer tearDownCreateTransaction(t, m)

// Credit u[1] on m[0]
status, raw := u[0].Post(t,
fmt.Sprintf("/transactions"),
url.Values{
"pair": {fmt.Sprintf("%s/%s", a[0].Name, a[0].Name)},
"amount": {"10"},
"destination": {u[1].Address},
"path[]": {},
})

assert.Equal(t, 201, status)

var tx mint.TransactionResource
err := raw.Extract("transaction", &tx)
assert.Nil(t, err)

status, raw = u[0].Post(t,
fmt.Sprintf("/transactions/%s/settle", tx.ID),
url.Values{})

assert.Equal(t, 200, status)

err = raw.Extract("transaction", &tx)
assert.Nil(t, err)

// Pay u[1] (himself) using his balance at m[0]
status, raw = u[1].Post(t,
fmt.Sprintf("/transactions"),
url.Values{
"pair": {fmt.Sprintf("%s/%s", a[0].Name, a[1].Name)},
"amount": {"5"},
"destination": {u[1].Address},
"path[]": {
o[1].ID,
},
})

assert.Equal(t, 201, status)

var tx1 mint.TransactionResource
err = raw.Extract("transaction", &tx1)
assert.Nil(t, err)

assert.Regexp(t, mint.IDRegexp, tx1.ID)
assert.Equal(t, mint.TxStReserved, tx1.Status)
assert.Equal(t, 1, len(tx1.Operations))
assert.Equal(t, 1, len(tx1.Crossings))

assert.Equal(t, mint.TxStReserved, tx1.Operations[0].Status)
assert.Equal(t, big.NewInt(5), tx1.Operations[0].Amount)
assert.Equal(t, u[1].Address, tx1.Operations[0].Destination)
assert.Equal(t, u[1].Address, tx1.Operations[0].Source)

assert.Equal(t, mint.TxStReserved, tx1.Crossings[0].Status)
assert.Equal(t, u[1].Address, tx1.Crossings[0].Owner)
assert.Equal(t, o[1].ID, tx1.Crossings[0].Offer)
assert.Equal(t, big.NewInt(5), tx1.Crossings[0].Amount)

// Check transaction on m[0].
status, raw = u[0].Get(t, fmt.Sprintf("/transactions/%s", tx1.ID))

assert.Equal(t, 200, status)

var tx0 mint.TransactionResource
err = raw.Extract("transaction", &tx0)
assert.Nil(t, err)

assert.Regexp(t, mint.IDRegexp, tx0.ID)
assert.Equal(t, mint.TxStReserved, tx0.Status)
assert.Equal(t, 1, len(tx0.Operations))
assert.Equal(t, 0, len(tx0.Crossings))

assert.Equal(t, mint.TxStReserved, tx0.Operations[0].Status)
assert.Equal(t, big.NewInt(5), tx0.Operations[0].Amount)
assert.Equal(t, u[1].Address, tx0.Operations[0].Destination)
assert.Equal(t, u[1].Address, tx0.Operations[0].Source)

// Check balance on m[1]
balance, err := model.LoadCanonicalBalanceByAssetHolder(m[0].Ctx,
a[0].Name, u[1].Address)
assert.Nil(t, err)
// The balance should be 5 because you've reserved 5 for yourself (it will
// go back at 10 post settlement).
assert.Equal(t, big.NewInt(5), (*big.Int)(&balance.Value))
}

0 comments on commit 703aea4

Please sign in to comment.