Browse Source

Add some failsafes and fix a bug

master
Jared 1 year ago
parent
commit
0838f361c4
4 changed files with 124 additions and 107 deletions
  1. +11
    -3
      endpoints/contributionstream.go
  2. +1
    -0
      endpoints/createrewardfund.go
  3. +6
    -104
      endpoints/submitfund.go
  4. +106
    -0
      utils/submission.go

+ 11
- 3
endpoints/contributionstream.go View File

@@ -8,6 +8,7 @@ import (
"github.com/gorilla/websocket"
"github.com/imosed/signet/client"
. "github.com/imosed/signet/data"
"github.com/imosed/signet/utils"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
"github.com/stellar/go/clients/horizonclient"
@@ -73,12 +74,19 @@ func InitializeContributionStreams() {
return
}

if tx.Memo == "" {
return
}
Db.Table("reward_funds").Where("memo = ? and fund_wallet = ?", tx.Memo, payment.To).First(&fund)
newAmt := fund.AmountAvailable - amt
Db.Model(&RewardFund{}).Where("id = ?", fund.ID).Update("amount_available", newAmt)
if tx.Memo == "" {
return
}

if newAmt < 5000 && newAmt > 0 {
_, err = utils.SubmitGroupFund(fund.ID)
if err != nil {
log.Error().Err(err).Msg("Could not submit group fund from contribution stream")
}
}

contribution := Contribution{
ModelBase: ModelBase{CreatedAt: tx.LedgerCloseTime},


+ 1
- 0
endpoints/createrewardfund.go View File

@@ -15,6 +15,7 @@ import (
type CreateRewardFundRequest struct {
Asset string `json:"asset"`
FundWallet string `json:"fundWallet"`
FundSecret string `json:"fundSecret"`
SellingWallet string `json:"sellingWallet"`
IssuerWallet string `json:"issuerWallet"`
Memo string `json:"memo"`


+ 6
- 104
endpoints/submitfund.go View File

@@ -2,20 +2,10 @@ package endpoints

import (
"encoding/json"
"fmt"
"net/http"

"github.com/imosed/signet/client"
. "github.com/imosed/signet/data"
"github.com/imosed/signet/utils"
"github.com/rs/zerolog/log"
"github.com/stellar/go/clients/horizonclient"
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/protocols/horizon"
"github.com/stellar/go/txnbuild"
"github.com/stellar/go/xdr"
"gorm.io/gorm/clause"
)

type SubmitFundRequest struct {
@@ -30,109 +20,21 @@ func SubmitFund(w http.ResponseWriter, r *http.Request) {
log.Error().Err(err).Msg("Could not decode body in SubmitFund call")
}

var fund RewardFund
Db.Preload(clause.Associations).Find(&fund, req.FundID)

var resp SuccessResponse
if !req.Submit {
json.NewEncoder(w).Encode(&SuccessResponse{Success: false})
return
}

source := keypair.MustParseFull(fund.FundSecret)
sourceReq := horizonclient.AccountRequest{AccountID: source.Address()}
var sourceAcct horizon.Account
sourceAcct, err = client.SignetClient.AccountDetail(sourceReq)

offerReq := horizonclient.OfferRequest{
Seller: fund.SellingWallet,
Selling: fmt.Sprintf("%s:%s", fund.Asset, fund.IssuerWallet),
Order: horizonclient.OrderDesc,
}
resp.Success = false

if err, ok := utils.FindOffer(offerReq, &fund); !ok {
err = json.NewEncoder(w).Encode(&SuccessResponse{Success: ok})
if req.Submit {
var success bool
success, err = utils.SubmitGroupFund(req.FundID)
if err != nil {
log.Error().Err(err).Msg("Could not deliver response after failing to find issuer offer in submission")
log.Error().Err(err).Msg("Could not submit group fund from SubmitFundRequest")
}
return
}

var currentContributions = fund.Contributions
var submissionAmount = SumContributions(currentContributions)

tr := Db.Begin()
tr.Table("contributions").
Where("reward_fund_id = ? and submitted is null or submitted = false", req.FundID).
Updates(Contribution{Submitted: true})

var tx *txnbuild.Transaction
tx, err = txnbuild.NewTransaction(
txnbuild.TransactionParams{
SourceAccount: &sourceAcct,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
&txnbuild.ChangeTrust{
Line: txnbuild.CreditAsset{
Code: fund.Asset,
Issuer: fund.IssuerWallet,
}.MustToChangeTrustAsset(),
SourceAccount: fund.FundWallet,
},
&txnbuild.ManageBuyOffer{
Selling: txnbuild.NativeAsset{},
Buying: txnbuild.CreditAsset{
Code: fund.Asset,
Issuer: fund.IssuerWallet,
},
Amount: fmt.Sprintf("%f", submissionAmount),
Price: xdr.Price{N: 1, D: xdr.Int32(fund.Price)},
OfferID: 0,
SourceAccount: fund.FundWallet,
},
},
BaseFee: txnbuild.MinBaseFee,
Memo: txnbuild.Memo(nil),
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(), // TODO: change from infinite
},
})
if err != nil {
log.Error().Err(err).Msg("Could not build submission transaction")
tr.Rollback()
return
}

tx, err = tx.Sign(network.TestNetworkPassphrase, source)
if err != nil {
log.Error().Err(err).Msg("Could not sign submission transaction")
tr.Rollback()
return
}

var response horizon.Transaction
response, err = client.SignetClient.SubmitTransaction(tx)
if err != nil {
log.Error().Err(err).Msg("Could not submit transaction")
tr.Rollback()
return
resp.Success = success
}

tr.Commit()
resp.Success = response.Successful

err = json.NewEncoder(w).Encode(resp)
if err != nil {
log.Error().Err(err).Msg("Could not deliver response in SubmitFund call")
}
}

func SumContributions(contributions []Contribution) float64 {
var total float64 = 0
for _, contribution := range contributions {
if !contribution.Submitted {
total += contribution.Amount
}
}
return total
}

+ 106
- 0
utils/submission.go View File

@@ -0,0 +1,106 @@
package utils

import (
"fmt"

"github.com/imosed/signet/client"
. "github.com/imosed/signet/data"
"github.com/stellar/go/clients/horizonclient"
"github.com/stellar/go/keypair"
"github.com/stellar/go/network"
"github.com/stellar/go/protocols/horizon"
"github.com/stellar/go/txnbuild"
"github.com/stellar/go/xdr"
"gorm.io/gorm/clause"
)

func SubmitGroupFund(fundID uint) (bool, error) {
var fund RewardFund
Db.Preload(clause.Associations).Find(&fund, fundID)

var err error

source := keypair.MustParseFull(fund.FundSecret)
sourceReq := horizonclient.AccountRequest{AccountID: source.Address()}
var sourceAcct horizon.Account
sourceAcct, err = client.SignetClient.AccountDetail(sourceReq)

offerReq := horizonclient.OfferRequest{
Seller: fund.SellingWallet,
Selling: fmt.Sprintf("%s:%s", fund.Asset, fund.IssuerWallet),
Order: horizonclient.OrderDesc,
}

if err, ok := FindOffer(offerReq, &fund); !ok {
return false, err
}

var currentContributions = fund.Contributions
var submissionAmount = sumContributions(currentContributions)

tr := Db.Begin()
tr.Table("contributions").
Where("reward_fund_id = ? and submitted is null or submitted = false", fundID).
Updates(Contribution{Submitted: true})

var tx *txnbuild.Transaction
tx, err = txnbuild.NewTransaction(
txnbuild.TransactionParams{
SourceAccount: &sourceAcct,
IncrementSequenceNum: true,
Operations: []txnbuild.Operation{
&txnbuild.ChangeTrust{
Line: txnbuild.CreditAsset{
Code: fund.Asset,
Issuer: fund.IssuerWallet,
}.MustToChangeTrustAsset(),
SourceAccount: fund.FundWallet,
},
&txnbuild.ManageBuyOffer{
Selling: txnbuild.NativeAsset{},
Buying: txnbuild.CreditAsset{
Code: fund.Asset,
Issuer: fund.IssuerWallet,
},
Amount: fmt.Sprintf("%f", submissionAmount),
Price: xdr.Price{N: 1, D: xdr.Int32(fund.Price)},
OfferID: 0,
SourceAccount: fund.FundWallet,
},
},
BaseFee: txnbuild.MinBaseFee,
Memo: txnbuild.Memo(nil),
Preconditions: txnbuild.Preconditions{
TimeBounds: txnbuild.NewInfiniteTimeout(), // TODO: change from infinite
},
})
if err != nil {
tr.Rollback()
return false, err
}

tx, err = tx.Sign(network.TestNetworkPassphrase, source)
if err != nil {
tr.Rollback()
return false, err
}

_, err = client.SignetClient.SubmitTransaction(tx)
if err != nil {
tr.Rollback()
return false, err
}

tr.Commit()
return true, nil
}

func sumContributions(contributions []Contribution) float64 {
var total float64 = 0
for _, contribution := range contributions {
if !contribution.Submitted {
total += contribution.Amount
}
}
return total
}

Loading…
Cancel
Save