Skip to content

Commit 7ea71da

Browse files
committed
Merge branch 'arweave-tx-support'
2 parents 63a7732 + 233ff19 commit 7ea71da

File tree

7 files changed

+91
-62
lines changed

7 files changed

+91
-62
lines changed

commentapi/comment.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ type CreateArgs struct {
9090
IsProtected bool `json:"is_protected"`
9191
Amount *float64 `json:"amount"`
9292
DryRun bool `json:"dry_run"`
93-
PaymentTxId *string `json:"payment_tx_id"`
93+
PaymentTxID *string `json:"payment_tx_id"`
9494
}
9595

9696
// CreateResponse response for the comment.Create rpc call

config/config.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package config
22

33
import (
4+
"strings"
5+
46
"github.com/OdyseeTeam/commentron/db"
57
"github.com/OdyseeTeam/commentron/env"
68
"github.com/OdyseeTeam/commentron/helper"
@@ -13,7 +15,7 @@ import (
1315
// SocketyToken token used to communicate with Sockety
1416
var SocketyToken string
1517

16-
//IsTestMode turns off validations for local testing
18+
// IsTestMode turns off validations for local testing
1719
var IsTestMode bool
1820

1921
// InitializeConfiguration inits the base configuration of commentron
@@ -51,6 +53,11 @@ func initSlack(config *env.Config) {
5153
Channel: slackChannel,
5254
IconEmoji: ":speech_balloon:",
5355
Username: "Commentron",
56+
Filters: []slackrus.Filter{
57+
func(entry *logrus.Entry) bool {
58+
return !strings.Contains(entry.Message, "could not get claim from sdk")
59+
},
60+
},
5461
})
5562
}
5663
}

migration/bindata.go

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/lbry/apis.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,13 @@ func (c apiClient) CheckPerk(options CheckPerkOptions) (bool, error) {
9191
return perkRes.Data.HasAccess, nil
9292
}
9393

94+
// ArweavePaymentDetailsResponse is the response structure from internal-apis for the arweave payment details api
9495
type ArweavePaymentDetailsResponse struct {
9596
Amount uint64 `json:"amount"`
9697
Currency string `json:"currency"`
9798
Status string `json:"status"`
98-
UserId uint64 `json:"user_id"`
99-
ChannelClaimId string `json:"channel_claim_id"`
99+
UserID uint64 `json:"user_id"`
100+
ChannelClaimID string `json:"channel_claim_id"`
100101
TippedAt time.Time `json:"tipped_at"`
101102
}
102103
type apiArweavePaymentDetailsResponse struct {
@@ -105,12 +106,12 @@ type apiArweavePaymentDetailsResponse struct {
105106
Data ArweavePaymentDetailsResponse `json:"data"`
106107
}
107108

108-
func (c apiClient) GetDetailsForTransaction(txId string) (*ArweavePaymentDetailsResponse, error) {
109+
func (c apiClient) GetDetailsForTransaction(txID string) (*ArweavePaymentDetailsResponse, error) {
109110
const apiPath = "/arweave/payment/retrieve"
110111
client := http.Client{}
111112
form := make(url.Values)
112113
form.Set("auth_token", apiToken)
113-
form.Set("tx_id", txId)
114+
form.Set("tx_id", txID)
114115

115116
response, err := client.PostForm(apiURL+apiPath, form)
116117
if err != nil {

server/lbry/client.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@ func (m *mockAPI) CheckPerk(options CheckPerkOptions) (bool, error) {
9696
return false, nil
9797
}
9898

99-
func (m *mockAPI) GetDetailsForTransaction(txId string) (*ArweavePaymentDetailsResponse, error) {
99+
func (m *mockAPI) GetDetailsForTransaction(txID string) (*ArweavePaymentDetailsResponse, error) {
100100
return nil, nil
101101
}

server/services/v1/comments/comments.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ func populateItem(comment *m.Comment, channel *m.Channel, replies int) commentap
2929
}
3030

3131
item := commentapi.CommentItem{
32-
Comment: comment.Body,
33-
CommentID: comment.CommentID,
34-
ClaimID: comment.LbryClaimID,
35-
Timestamp: comment.Timestamp,
36-
ParentID: comment.ParentID.String,
37-
Signature: comment.Signature.String,
32+
Comment: comment.Body,
33+
CommentID: comment.CommentID,
34+
ClaimID: comment.LbryClaimID,
35+
Timestamp: comment.Timestamp,
36+
ParentID: comment.ParentID.String,
37+
//Signature: comment.Signature.String,
3838
SigningTs: comment.Signingts.String,
3939
IsHidden: comment.IsHidden.Bool,
4040
IsPinned: comment.IsPinned,

server/services/v1/comments/create.go

+47-49
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,12 @@ func create(_ *http.Request, args *commentapi.CreateArgs, reply *commentapi.Crea
6767

6868
var frequencyCheck = checkFrequency
6969

70-
if args.Amount != nil {
71-
if args.DryRun {
70+
isPaidComment := args.Amount != nil || args.PaymentIntentID != nil //this is because odysee android app doesn't pass an amount for dryruns...
71+
isDryRun := args.DryRun && (args.SupportTxID != nil || args.PaymentIntentID != nil || args.PaymentTxID != nil)
72+
isActualTransaction := isPaidComment && (args.SupportTxID != nil || args.PaymentIntentID != nil || args.PaymentTxID != nil)
73+
74+
if isPaidComment {
75+
if isDryRun {
7276
cents := *args.Amount
7377
if args.SupportTxID != nil {
7478
lbc, err := btcutil.NewAmount(*args.Amount)
@@ -80,40 +84,15 @@ func create(_ *http.Request, args *commentapi.CreateArgs, reply *commentapi.Crea
8084
cents *= 100
8185
}
8286
request.comment.Amount.SetValid(uint64(cents))
83-
} else {
87+
} else if isActualTransaction {
8488
err := updateSupportInfo(request)
8589
if err != nil {
8690
return err
8791
}
88-
}
89-
// ignore the frequency if it's a tipped comment
90-
frequencyCheck = ignoreFrequency
91-
}
92-
93-
if args.SupportTxID != nil || args.PaymentIntentID != nil || args.PaymentTxId != nil {
94-
if args.DryRun {
95-
if args.Amount != nil {
96-
if args.PaymentIntentID != nil {
97-
cents := uint64(*args.Amount * 100)
98-
request.comment.Amount.SetValid(cents)
99-
} else if args.SupportTxID != nil {
100-
lbc, err := btcutil.NewAmount(*args.Amount)
101-
if err != nil {
102-
return errors.Err(err)
103-
}
104-
request.comment.Amount.SetValid(uint64(lbc.ToUnit(btcutil.AmountSatoshi)))
105-
} else if args.PaymentTxId != nil {
106-
//assume cents
107-
request.comment.Amount.SetValid(uint64(*args.Amount))
108-
}
109-
}
11092
} else {
111-
err := updateSupportInfo(request)
112-
if err != nil {
113-
return err
114-
}
93+
return errors.Err("you must specify a transaction if it's a paid comment")
11594
}
116-
// ignore the frequency if its a tipped comment
95+
// ignore the frequency if it's a tipped comment
11796
frequencyCheck = ignoreFrequency
11897
}
11998

@@ -737,6 +716,8 @@ func getCounter(key string, expiration time.Duration) (*counter.Counter, error)
737716

738717
func updateSupportInfo(request *createRequest) error {
739718
triesLeft := 3
719+
backoff := time.Second
720+
740721
for {
741722
triesLeft--
742723
err := updateSupportInfoAttempt(request, true)
@@ -746,20 +727,36 @@ func updateSupportInfo(request *createRequest) error {
746727
if triesLeft == 0 {
747728
return err
748729
}
749-
time.Sleep(1 * time.Second)
730+
time.Sleep(backoff)
731+
backoff *= 2
750732
}
751733
}
752734

735+
func checkReplays(txID string) error {
736+
existingComment, err := m.Comments(m.CommentWhere.TXID.EQ(null.StringFrom(txID))).One(db.RO)
737+
if err != nil && !errors.Is(err, sql.ErrNoRows) {
738+
if !errors.Is(err, sql.ErrNoRows) {
739+
return errors.Err(err)
740+
}
741+
}
742+
if existingComment != nil {
743+
return errors.Err("a comment with this transaction id already exists")
744+
}
745+
return nil
746+
}
747+
753748
func updateSupportInfoAttempt(request *createRequest, retry bool) error {
754-
//TODO: fix replay attacks
755-
//todo: fix stolen tx attacks
756749
if request.args.PaymentIntentID != nil {
757750
env := ""
758751
if request.args.Environment != nil {
759752
env = *request.args.Environment
760753
}
761-
paymentintentClient := &paymentintent.Client{B: stripe.GetBackend(stripe.APIBackend), Key: config.ConnectAPIKey(config.From(env))}
762-
pi, err := paymentintentClient.Get(*request.args.PaymentIntentID, &stripe.PaymentIntentParams{})
754+
err := checkReplays(*request.args.PaymentIntentID)
755+
if err != nil {
756+
return err
757+
}
758+
pic := &paymentintent.Client{B: stripe.GetBackend(stripe.APIBackend), Key: config.ConnectAPIKey(config.From(env))}
759+
pi, err := pic.Get(*request.args.PaymentIntentID, &stripe.PaymentIntentParams{})
763760
if err != nil {
764761
if !retry {
765762
logrus.Error(errors.Prefix("could not get payment intent %s", *request.args.PaymentIntentID))
@@ -772,9 +769,13 @@ func updateSupportInfoAttempt(request *createRequest, retry bool) error {
772769
request.comment.Amount.SetValid(uint64(pi.Amount))
773770
request.comment.IsFiat = true
774771
request.comment.Currency.SetValid(pi.Currency)
772+
request.comment.TXID.SetValid(*request.args.PaymentIntentID)
775773
return nil
776774
} else if request.args.SupportTxID != nil {
777-
request.comment.TXID.SetValid(util.StrFromPtr(request.args.SupportTxID))
775+
err := checkReplays(*request.args.SupportTxID)
776+
if err != nil {
777+
return err
778+
}
778779
txSummary, err := lbry.SDK.GetTx(request.comment.TXID.String)
779780
if err != nil {
780781
return errors.Err(err)
@@ -790,35 +791,32 @@ func updateSupportInfoAttempt(request *createRequest, retry bool) error {
790791
if err != nil {
791792
return errors.Err(err)
792793
}
794+
request.comment.TXID.SetValid(util.StrFromPtr(request.args.SupportTxID))
793795
request.comment.Amount.SetValid(amount)
796+
request.comment.Currency.SetValid("LBC")
794797
return nil
795-
} else if request.args.PaymentTxId != nil {
796-
//check for replays
797-
existingComment, err := m.Comments(m.CommentWhere.TXID.EQ(null.StringFromPtr(request.args.PaymentTxId))).One(db.RO)
798-
if err != nil && !errors.Is(err, sql.ErrNoRows) {
799-
if !errors.Is(err, sql.ErrNoRows) {
800-
return errors.Err(err)
801-
}
802-
}
803-
if existingComment != nil {
804-
return errors.Err("a comment with this transaction id already exists")
798+
} else if request.args.PaymentTxID != nil {
799+
err := checkReplays(*request.args.PaymentTxID)
800+
if err != nil {
801+
return err
805802
}
806-
//query internal apis to verify the transaction
807-
pi, err := lbry.API.GetDetailsForTransaction(*request.args.PaymentTxId)
803+
pi, err := lbry.API.GetDetailsForTransaction(*request.args.PaymentTxID)
808804
if err != nil {
809805
return err
810806
}
811807
if pi.Status != "confirmed" {
812808
return errors.Err("transaction is not confirmed")
813809
}
814-
if pi.ChannelClaimId != request.args.ChannelID {
810+
if pi.ChannelClaimID != request.args.ChannelID {
815811
return errors.Err("channel mismatch for transaction")
816812
}
817813
if time.Since(pi.TippedAt) > time.Hour {
818814
return errors.Err("transaction is too old")
819815
}
820816
request.comment.Amount.SetValid(pi.Amount)
821817
request.comment.Currency.SetValid(pi.Currency)
818+
request.comment.TXID.SetValid(*request.args.PaymentTxID)
819+
request.comment.IsFiat = true
822820
}
823821
return nil
824822
}

0 commit comments

Comments
 (0)