@@ -2,6 +2,7 @@ package api
2
2
3
3
import (
4
4
"context"
5
+ "crypto/sha256"
5
6
"encoding/base64"
6
7
"encoding/hex"
7
8
"errors"
@@ -59,6 +60,10 @@ func (h *Handler) SendBlockchainMessage(ctx context.Context, request *oas.SendBl
59
60
if err != nil {
60
61
return toError (http .StatusBadRequest , fmt .Errorf ("boc must be a base64 encoded string" ))
61
62
}
63
+ checksum := sha256 .Sum256 (payload )
64
+ if _ , prs := h .blacklistedBocCache .Get (checksum ); prs {
65
+ return toError (http .StatusBadRequest , fmt .Errorf ("duplicate message" ))
66
+ }
62
67
msgCopy := blockchain.ExtInMsgCopy {
63
68
MsgBoc : request .Boc .Value ,
64
69
Payload : payload ,
@@ -67,11 +72,13 @@ func (h *Handler) SendBlockchainMessage(ctx context.Context, request *oas.SendBl
67
72
mempoolMessageCounter .Inc ()
68
73
if err := h .msgSender .SendMessage (ctx , msgCopy ); err != nil {
69
74
if strings .Contains (err .Error (), "cannot apply external message to current state" ) {
75
+ h .blacklistedBocCache .Set (checksum , struct {}{}, cache .WithExpiration (time .Minute ))
70
76
return toError (http .StatusNotAcceptable , err )
71
77
}
72
78
sentry .Send ("sending message" , sentry.SentryInfoData {"payload" : request .Boc }, sentry .LevelError )
73
79
return toError (http .StatusInternalServerError , err )
74
80
}
81
+ h .blacklistedBocCache .Set (checksum , struct {}{}, cache .WithExpiration (time .Minute ))
75
82
go func () {
76
83
defer func () {
77
84
if err := recover (); err != nil {
0 commit comments