Skip to content

Commit de4f0f5

Browse files
authored
Merge pull request #1486 from 0chain/fix/verifyTxn
Fix challenges
2 parents 688df04 + f6ef0ab commit de4f0f5

File tree

11 files changed

+132
-52
lines changed

11 files changed

+132
-52
lines changed

code/go/0chain.net/blobbercore/allocation/workers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ func sendFinalizeAllocation(allocationID string) {
315315
coreTxn.SmartContractTxnData{
316316
Name: transaction.FINALIZE_ALLOCATION,
317317
InputArgs: request,
318-
})
318+
}, true)
319319
if err != nil {
320320
logging.Logger.Error("sending finalize allocation", zap.Error(err))
321321
return

code/go/0chain.net/blobbercore/challenge/challenge.go

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"encoding/json"
7+
coreTxn "github.com/0chain/gosdk/core/transaction"
78
"sort"
89
"strconv"
910
"time"
@@ -162,10 +163,12 @@ func validateOnValidators(ctx context.Context, c *ChallengeEntity) error {
162163
return nil
163164
}
164165

165-
func (c ChallengeEntity) generateChallengeResponse() (*ChallengeResponse, error) {
166+
func (c *ChallengeEntity) getCommitTransaction(ctx context.Context) (*coreTxn.Transaction, error) {
167+
createdTime := common.ToTime(c.CreatedAt)
166168

167169
logging.Logger.Info("[challenge]verify: ",
168-
zap.Any("challenge_id", c.ChallengeID))
170+
zap.Any("challenge_id", c.ChallengeID),
171+
zap.Time("created", createdTime))
169172

170173
currentRound := roundInfo.CurrentRound + int64(float64(roundInfo.LastRoundDiff)*(float64(time.Since(roundInfo.CurrentRoundCaptureTime).Milliseconds())/float64(GetRoundInterval.Milliseconds())))
171174
logging.Logger.Info("[challenge]commit",
@@ -180,7 +183,8 @@ func (c ChallengeEntity) generateChallengeResponse() (*ChallengeResponse, error)
180183
)
181184

182185
if currentRound-c.RoundCreatedAt > config.StorageSCConfig.ChallengeCompletionTime {
183-
return nil, common.NewError("challenge_expired", "Challenge has expired")
186+
c.CancelChallenge(ctx, ErrExpiredCCT)
187+
return nil, nil
184188
}
185189

186190
sn := &ChallengeResponse{}
@@ -190,5 +194,25 @@ func (c ChallengeEntity) generateChallengeResponse() (*ChallengeResponse, error)
190194
sn.ValidationTickets = append(sn.ValidationTickets, vt)
191195
}
192196
}
193-
return sn, nil
197+
198+
_, _, _, txn, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
199+
Name: transaction.CHALLENGE_RESPONSE,
200+
InputArgs: sn,
201+
}, false)
202+
if err != nil {
203+
logging.Logger.Info("Failed submitting challenge to the mining network", zap.String("err:", err.Error()))
204+
c.CancelChallenge(ctx, err)
205+
return nil, nil
206+
}
207+
208+
err = UpdateChallengeTimingTxnSubmission(c.ChallengeID, common.Timestamp(txn.CreationDate))
209+
if err != nil {
210+
logging.Logger.Error("[challengetiming]txn_submission",
211+
zap.Any("challenge_id", c.ChallengeID),
212+
zap.Time("created", createdTime),
213+
zap.Any("txn_submission", txn.CreationDate),
214+
zap.Error(err))
215+
}
216+
217+
return txn, nil
194218
}

code/go/0chain.net/blobbercore/challenge/protocol.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"encoding/json"
77
"errors"
8+
"github.com/0chain/blobber/code/go/0chain.net/core/transaction"
89
coreTxn "github.com/0chain/gosdk/core/transaction"
910
"math/rand"
1011
"strings"
@@ -490,3 +491,51 @@ func (cr *ChallengeEntity) getPostData(ctx context.Context, allocationObj *alloc
490491
}
491492
return postData, nil
492493
}
494+
495+
func (cr *ChallengeEntity) VerifyChallengeTransaction(ctx context.Context, txn *coreTxn.Transaction) error {
496+
if len(cr.LastCommitTxnIDs) > 0 {
497+
for _, lastTxn := range cr.LastCommitTxnIDs {
498+
logging.Logger.Info("[challenge]commit: Verifying the transaction : " + lastTxn)
499+
t, err := coreTxn.VerifyTransaction(lastTxn)
500+
if err == nil && t.Status != coreTxn.TxnSuccess {
501+
cr.SaveChallengeResult(ctx, t, false)
502+
return nil
503+
}
504+
logging.Logger.Error("[challenge]trans: Error verifying the txn from BC."+lastTxn, zap.String("challenge_id", cr.ChallengeID), zap.Error(err))
505+
}
506+
}
507+
508+
logging.Logger.Info("Verifying challenge response to blockchain.", zap.String("txn", txn.Hash), zap.String("challenge_id", cr.ChallengeID))
509+
var (
510+
t *coreTxn.Transaction
511+
err error
512+
)
513+
for i := 0; i < 3; i++ {
514+
t, err = coreTxn.VerifyTransaction(txn.Hash)
515+
if err == nil {
516+
break
517+
}
518+
time.Sleep(transaction.SLEEP_FOR_TXN_CONFIRMATION * time.Second)
519+
}
520+
521+
if t == nil || err != nil || t.Status != coreTxn.TxnSuccess {
522+
logging.Logger.Error("Error verifying the challenge response transaction",
523+
zap.String("err:", err.Error()),
524+
zap.String("txn", txn.Hash),
525+
zap.String("challenge_id", cr.ChallengeID))
526+
527+
if t != nil {
528+
cr.CommitTxnID = t.Hash
529+
cr.LastCommitTxnIDs = append(cr.LastCommitTxnIDs, t.Hash)
530+
}
531+
532+
if IsEntityNotFoundError(err) {
533+
err = ErrEntityNotFound
534+
}
535+
_ = cr.Save(ctx)
536+
return err
537+
}
538+
logging.Logger.Info("Success response from BC for challenge response transaction", zap.String("txn", txn.TransactionOutput), zap.String("challenge_id", cr.ChallengeID))
539+
cr.SaveChallengeResult(ctx, t, true)
540+
return nil
541+
}

code/go/0chain.net/blobbercore/challenge/worker.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package challenge
33
import (
44
"context"
55
"encoding/json"
6-
"github.com/0chain/blobber/code/go/0chain.net/core/common"
76
"github.com/0chain/gosdk/core/client"
87
coreTxn "github.com/0chain/gosdk/core/transaction"
98
"sync"
@@ -12,7 +11,6 @@ import (
1211
"github.com/0chain/blobber/code/go/0chain.net/blobbercore/config"
1312
"github.com/0chain/blobber/code/go/0chain.net/blobbercore/datastore"
1413
"github.com/0chain/blobber/code/go/0chain.net/core/logging"
15-
"github.com/0chain/blobber/code/go/0chain.net/core/transaction"
1614
"github.com/emirpasic/gods/maps/treemap"
1715
"go.uber.org/zap"
1816
"golang.org/x/sync/semaphore"
@@ -190,32 +188,34 @@ func commitOnChainWorker(ctx context.Context) {
190188

191189
logging.Logger.Info("committing_challenge_tickets", zap.Any("num", len(challenges)), zap.Any("challenges", challenges))
192190

193-
for _, chall := range challenges {
194-
createdTime := common.ToTime(chall.CreatedAt)
195-
196-
sn, err := chall.generateChallengeResponse()
197-
if err != nil {
198-
logging.Logger.Error("generateChallengeResponse", zap.Error(err))
199-
continue
200-
}
201-
202-
_, _, _, txn, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
203-
Name: transaction.CHALLENGE_RESPONSE,
204-
InputArgs: sn,
191+
for _, challenge := range challenges {
192+
chall := challenge
193+
var (
194+
txn *coreTxn.Transaction
195+
err error
196+
)
197+
_ = datastore.GetStore().WithNewTransaction(func(ctx context.Context) error {
198+
txn, err = chall.getCommitTransaction(ctx)
199+
return err
205200
})
206-
if err != nil {
207-
logging.Logger.Error("commitOnChainWorker", zap.Error(err))
208-
deleteChallenge(chall.RoundCreatedAt)
209-
continue
210-
}
211201

212-
err = UpdateChallengeTimingTxnSubmission(chall.ChallengeID, common.Timestamp(txn.CreationDate))
213-
if err != nil {
214-
logging.Logger.Error("[challengetiming]txn_submission",
215-
zap.Any("challenge_id", chall.ChallengeID),
216-
zap.Time("created", createdTime),
217-
zap.Any("txn_submission", txn.CreationDate),
218-
zap.Error(err))
202+
if txn != nil {
203+
wg.Add(1)
204+
go func(challenge *ChallengeEntity) {
205+
defer func() {
206+
wg.Done()
207+
if r := recover(); r != nil {
208+
logging.Logger.Error("verifyChallengeTransaction", zap.Any("err", r))
209+
}
210+
}()
211+
_ = datastore.GetStore().WithNewTransaction(func(ctx context.Context) error {
212+
err := challenge.VerifyChallengeTransaction(ctx, txn)
213+
if err == nil || err != ErrEntityNotFound {
214+
deleteChallenge(challenge.RoundCreatedAt)
215+
}
216+
return nil
217+
})
218+
}(&chall)
219219
}
220220
}
221221
wg.Wait()

code/go/0chain.net/blobbercore/handler/health.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,41 @@ func getBlobberHealthCheckError() error {
3131
return err
3232
}
3333

34-
func BlobberHealthCheck() (*coreTxn.Transaction, error) {
34+
func BlobberHealthCheck() (string, error) {
3535
if config.Configuration.Capacity == 0 {
3636

3737
setBlobberHealthCheckError(ErrBlobberHasRemoved)
38-
return nil, ErrBlobberHasRemoved
38+
return "", ErrBlobberHasRemoved
3939
}
4040

4141
_, _, _, txn, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
4242
Name: transaction.BLOBBER_HEALTH_CHECK,
4343
InputArgs: common.Now(),
44-
})
45-
if err != nil {
44+
}, true)
45+
if err != nil || txn == nil {
4646
logging.Logger.Error("Failed to health check blobber on the blockchain",
4747
zap.Error(err))
4848
setBlobberHealthCheckError(err)
4949

50-
return nil, err
50+
return "", err
5151
}
5252

5353
setBlobberHealthCheckError(nil)
5454

55-
return txn, nil
55+
return txn.Hash, nil
5656
}
5757

58-
func ValidatorHealthCheck() (*coreTxn.Transaction, error) {
58+
func ValidatorHealthCheck() (string, error) {
5959
_, _, _, txn, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
6060
Name: transaction.VALIDATOR_HEALTH_CHECK,
6161
InputArgs: common.Now(),
62-
})
63-
return txn, err
62+
}, true)
63+
64+
if err != nil || txn == nil {
65+
logging.Logger.Error("Failed to health check validator on the blockchain",
66+
zap.Error(err))
67+
return "", err
68+
}
69+
70+
return txn.Hash, err
6471
}

code/go/0chain.net/blobbercore/handler/object_operation_handler_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ func TestDownloadFile(t *testing.T) {
141141
}
142142
}
143143

144-
makeMockMakeSCRestAPICall := func(t *testing.T, p parameters) func(scAddress string, relativePath string, params map[string]string) ([]byte, error) {
145-
return func(scAddress string, relativePath string, params map[string]string) ([]byte, error) {
144+
makeMockMakeSCRestAPICall := func(t *testing.T, p parameters) func(scAddress string, relativePath string, params map[string]string, options ...string) ([]byte, error) {
145+
return func(scAddress string, relativePath string, params map[string]string, options ...string) ([]byte, error) {
146146
require.New(t)
147147
require.EqualValues(t, scAddress, transaction.STORAGE_CONTRACT_ADDRESS)
148148
switch relativePath {

code/go/0chain.net/blobbercore/handler/protocol.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func sendSmartContractBlobberAdd() (*coreTxn.Transaction, error) {
121121
_, _, _, txn, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
122122
Name: transaction.ADD_BLOBBER_SC_NAME,
123123
InputArgs: sn,
124-
})
124+
}, true)
125125
if err != nil {
126126
logging.Logger.Error("Failed to set blobber on the blockchain",
127127
zap.String("err:", err.Error()), zap.Any("Txn", txn), zap.Any("ClientFee", client.TxnFee()))
@@ -152,17 +152,17 @@ var ErrValidatorNotFound = errors.New("validator is not found")
152152
// SendHealthCheck send heartbeat to blockchain
153153
func SendHealthCheck(provider common.ProviderType) (string, error) {
154154

155-
var txn *coreTxn.Transaction
155+
var hash string
156156
var err error
157157

158158
switch provider {
159159
case common.ProviderTypeBlobber:
160-
txn, err = BlobberHealthCheck()
160+
hash, err = BlobberHealthCheck()
161161
case common.ProviderTypeValidator:
162-
txn, err = ValidatorHealthCheck()
162+
hash, err = ValidatorHealthCheck()
163163
default:
164164
return "", errors.New("unknown provider type")
165165
}
166166

167-
return txn.Hash, err
167+
return hash, err
168168
}

code/go/0chain.net/blobbercore/writemarker/protocol.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ func (wme *WriteMarkerEntity) redeemMarker(ctx context.Context, startSeq int64)
170170
hash, out, nonce, txn, err = transaction.SmartContractTxn(STORAGE_CONTRACT_ADDRESS, transaction.SmartContractTxnData{
171171
Name: CLOSE_CONNECTION_SC_NAME,
172172
InputArgs: sn,
173-
})
173+
}, true)
174174
if err != nil {
175175
Logger.Error("Failed during sending close connection to the miner. ", zap.String("err:", err.Error()))
176176
wme.Status = Failed

code/go/0chain.net/validator/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func RegisterValidator() {
214214
hash, out, _, _, err := coreTxn.SmartContractTxn(transaction.STORAGE_CONTRACT_ADDRESS, coreTxn.SmartContractTxnData{
215215
Name: transaction.ADD_VALIDATOR_SC_NAME,
216216
InputArgs: sn,
217-
})
217+
}, true)
218218
if err != nil {
219219
Logger.Error("Add validator transaction could not be verified", zap.Any("err", err), zap.String("txn.Hash", hash))
220220
continue

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ toolchain go1.22.5
66

77
require (
88
github.com/0chain/errors v1.0.3
9-
github.com/0chain/gosdk v1.18.0-RC4
9+
github.com/0chain/gosdk v1.18.0-RC6.0.20241023193003-8d5ec2f50067
1010
github.com/DATA-DOG/go-sqlmock v1.5.0
1111
github.com/didip/tollbooth/v6 v6.1.2
1212
github.com/go-openapi/runtime v0.26.0

0 commit comments

Comments
 (0)