Skip to content

Commit 2b04de8

Browse files
authored
checks and recovery functions (#792)
* introduce ability to inject the checkers * remove vault support form network Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent 386c430 commit 2b04de8

File tree

45 files changed

+582
-525
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+582
-525
lines changed

integration/ports.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ var (
5959
}
6060

6161
AllTestTypes = []*InfrastructureType{
62-
// WebSocketNoReplication,
63-
// LibP2PNoReplication,
62+
WebSocketNoReplication,
63+
LibP2PNoReplication,
6464
WebSocketWithReplication,
6565
}
6666
)

integration/token/fungible/tests.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,7 @@ func TestAll(network *integration.Infrastructure, auditorId string, onRestart On
506506
CheckBalanceAndHolding(network, bob, "", "EUR", 20, auditor)
507507
CheckBalanceAndHolding(network, bob, "", "USD", 110, auditor)
508508
CheckOwnerDB(network, []string{
509-
fmt.Sprintf("transaction record [%s] is unknown for vault but not for the db [Pending]", txID1),
510-
fmt.Sprintf("transaction record [%s] is unknown for vault but not for the db [Pending]", txID2),
509+
//TODO: Errors
511510
}, bob)
512511
fmt.Printf("prepared transactions [%s:%s]", txID1, txID2)
513512
Restart(network, true, onRestart, bob)

integration/token/fungible/views/auditor.go

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/kvs"
1717
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
1818
"github.com/hyperledger-labs/fabric-token-sdk/token"
19-
"github.com/hyperledger-labs/fabric-token-sdk/token/services/network"
2019
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx"
2120
"github.com/pkg/errors"
2221
)
@@ -156,7 +155,7 @@ func (a *AuditView) Call(context view.Context) (interface{}, error) {
156155

157156
for _, rID := range inputs.RevocationHandles() {
158157
rh := hash.Hashable(rID).String()
159-
//logger.Infof("input RH [%s]", rh)
158+
// logger.Infof("input RH [%s]", rh)
160159
assert.NotNil(rID, "found an input with empty RH")
161160
k := kvs.CreateCompositeKeyOrPanic("revocationList", []string{rh})
162161
if kvsInstance.Exists(k) {
@@ -166,7 +165,7 @@ func (a *AuditView) Call(context view.Context) (interface{}, error) {
166165

167166
for _, rID := range outputs.RevocationHandles() {
168167
rh := hash.Hashable(rID).String()
169-
//logger.Infof("output RH [%s]", rh)
168+
// logger.Infof("output RH [%s]", rh)
170169
assert.NotNil(rID, "found an output with empty RH")
171170
k := kvs.CreateCompositeKeyOrPanic("revocationList", []string{rh})
172171
if kvsInstance.Exists(k) {
@@ -302,16 +301,6 @@ func (r *SetTransactionAuditStatusView) Call(context view.Context) (interface{},
302301
assert.NoError(err, "failed to get auditor instance")
303302
assert.NoError(auditor.SetStatus(context.Context(), r.TxID, r.Status, r.Message), "failed to set status of [%s] to [%d]", r.TxID, r.Status)
304303

305-
if r.Status == ttx.Deleted {
306-
tms := token.GetManagementService(context)
307-
assert.NotNil(tms, "failed to get default tms")
308-
net := network.GetInstance(context, tms.Network(), tms.Channel())
309-
assert.NotNil(net, "failed to get network [%s:%s]", tms.Network(), tms.Channel())
310-
v, err := net.Vault(tms.Namespace())
311-
assert.NoError(err)
312-
assert.NoError(v.DiscardTx(r.TxID), "failed to discard tx [%s:%s:%s:%s]", tms.Network(), tms.Channel(), tms.Namespace(), r.TxID)
313-
}
314-
315304
return nil, nil
316305
}
317306

integration/token/fungible/views/checks.go

Lines changed: 12 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,15 @@ SPDX-License-Identifier: Apache-2.0
77
package views
88

99
import (
10-
"bytes"
1110
"encoding/json"
12-
"fmt"
1311

1412
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/assert"
15-
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/hash"
1613
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
1714
"github.com/hyperledger-labs/fabric-token-sdk/token"
18-
"github.com/hyperledger-labs/fabric-token-sdk/token/services/auditdb"
1915
"github.com/hyperledger-labs/fabric-token-sdk/token/services/db/driver"
2016
"github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/htlc"
2117
"github.com/hyperledger-labs/fabric-token-sdk/token/services/network"
2218
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx"
23-
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttxdb"
2419
token2 "github.com/hyperledger-labs/fabric-token-sdk/token/token"
2520
"github.com/pkg/errors"
2621
)
@@ -43,108 +38,7 @@ type CheckTTXDBView struct {
4338
}
4439

4540
func (m *CheckTTXDBView) Call(context view.Context) (interface{}, error) {
46-
var errorMessages []string
47-
48-
tms := token.GetManagementService(context, token.WithTMSID(m.TMSID))
49-
assert.NotNil(tms, "failed to get default tms")
50-
net := network.GetInstance(context, tms.Network(), tms.Channel())
51-
assert.NotNil(net, "failed to get network [%s:%s]", tms.Network(), tms.Channel())
52-
v, err := net.Vault(tms.Namespace())
53-
assert.NoError(err, "failed to get vault [%s:%s:%s]", tms.Network(), tms.Channel(), tms.Namespace())
54-
tv, err := net.TokenVault(tms.Namespace())
55-
assert.NoError(err, "failed to get token vault [%s:%s:%s]", tms.Namespace(), tms.Channel(), tms.Namespace())
56-
l, err := net.Ledger()
57-
assert.NoError(err, "failed to get ledger [%s:%s:%s]", tms.Network(), tms.Channel(), tms.Namespace())
58-
59-
var tokenDB TokenTransactionDB
60-
if m.Auditor {
61-
auditorWallet := tms.WalletManager().AuditorWallet(m.AuditorWalletID)
62-
assert.NotNil(auditorWallet, "cannot find auditor wallet [%s]", m.AuditorWalletID)
63-
db, err := ttx.NewAuditor(context, auditorWallet)
64-
assert.NoError(err, "failed to get auditor instance")
65-
tokenDB = db
66-
} else {
67-
db := ttx.NewOwner(context, tms)
68-
tokenDB = db
69-
}
70-
it, err := tokenDB.Transactions(driver.QueryTransactionsParams{})
71-
assert.NoError(err, "failed to get transaction iterators")
72-
defer it.Close()
73-
for {
74-
transactionRecord, err := it.Next()
75-
assert.NoError(err, "failed to get next transaction record")
76-
if transactionRecord == nil {
77-
break
78-
}
79-
80-
// compare the status in the vault with the status of the record
81-
vc, _, err := v.Status(transactionRecord.TxID)
82-
if err != nil {
83-
errorMessages = append(errorMessages, fmt.Sprintf("failed to get vault status transaction record [%s]: [%s]", transactionRecord.TxID, err))
84-
continue
85-
}
86-
switch {
87-
case vc == network.Unknown:
88-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is unknown for vault but not for the db [%s]", transactionRecord.TxID, driver.TxStatusMessage[transactionRecord.Status]))
89-
case vc == network.Valid && transactionRecord.Status == ttxdb.Pending:
90-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is valid for vault but pending for the db", transactionRecord.TxID))
91-
case vc == network.Valid && transactionRecord.Status == ttxdb.Deleted:
92-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is valid for vault but deleted for the db", transactionRecord.TxID))
93-
case vc == network.Invalid && transactionRecord.Status == ttxdb.Confirmed:
94-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is invalid for vault but confirmed for the db", transactionRecord.TxID))
95-
case vc == network.Invalid && transactionRecord.Status == ttxdb.Pending:
96-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is invalid for vault but pending for the db", transactionRecord.TxID))
97-
case vc == network.Busy && transactionRecord.Status == ttxdb.Confirmed:
98-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is busy for vault but confirmed for the db", transactionRecord.TxID))
99-
case vc == network.Busy && transactionRecord.Status == ttxdb.Deleted:
100-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is busy for vault but deleted for the db", transactionRecord.TxID))
101-
}
102-
103-
// check envelope
104-
//if !net.ExistEnvelope(transactionRecord.TxID) {
105-
// errorMessages = append(errorMessages, fmt.Sprintf("no envelope found for transaction record [%s]", transactionRecord.TxID))
106-
//}
107-
108-
tokenRequest, err := tokenDB.GetTokenRequest(transactionRecord.TxID)
109-
assert.NoError(err, "failed to retrieve token request for [%s]", transactionRecord.TxID)
110-
assert.NotNil(tokenRequest, "token requests must not be nil")
111-
112-
// check the ledger
113-
lVC, _, err := l.Status(transactionRecord.TxID)
114-
if err != nil {
115-
lVC = network.Unknown
116-
}
117-
switch {
118-
case vc == network.Valid && lVC != network.Valid:
119-
if err != nil {
120-
errorMessages = append(errorMessages, fmt.Sprintf("failed to get ledger transaction status for [%s]: [%s]", transactionRecord.TxID, err))
121-
}
122-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is valid for vault but not for the ledger [%d]", transactionRecord.TxID, lVC))
123-
case vc == network.Invalid && lVC != network.Invalid:
124-
if lVC != network.Unknown || transactionRecord.Status != ttxdb.Deleted {
125-
if err != nil {
126-
errorMessages = append(errorMessages, fmt.Sprintf("failed to get ledger transaction status for [%s]: [%s]", transactionRecord.TxID, err))
127-
}
128-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is invalid for vault but not for the ledger [%d]", transactionRecord.TxID, lVC))
129-
}
130-
case vc == network.Unknown && lVC != network.Unknown:
131-
if err != nil {
132-
errorMessages = append(errorMessages, fmt.Sprintf("failed to get ledger transaction status for [%s]: [%s]", transactionRecord.TxID, err))
133-
}
134-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is unknown for vault but not for the ledger [%d]", transactionRecord.TxID, lVC))
135-
case vc == network.Busy && lVC == network.Busy:
136-
// this is fine, let's continue
137-
case vc == network.Busy && lVC != network.Unknown:
138-
if err != nil {
139-
errorMessages = append(errorMessages, fmt.Sprintf("failed to get ledger transaction status for [%s]: [%s]", transactionRecord.TxID, err))
140-
}
141-
errorMessages = append(errorMessages, fmt.Sprintf("transaction record [%s] is busy for vault but not for the ledger [%d]", transactionRecord.TxID, lVC))
142-
}
143-
}
144-
145-
// Match unspent tokens with the ledger
146-
// but first delete the claimed tokens
147-
// TODO: check all owner wallets
41+
// prepare
14842
defaultOwnerWallet := htlc.GetWallet(context, "", token.WithTMSID(m.TMSID))
14943
if defaultOwnerWallet != nil {
15044
htlcWallet := htlc.Wallet(context, defaultOwnerWallet)
@@ -153,39 +47,18 @@ func (m *CheckTTXDBView) Call(context view.Context) (interface{}, error) {
15347
assert.NoError(htlcWallet.DeleteExpiredReceivedTokens(context), "failed to delete expired received tokens")
15448
}
15549

156-
// check unspent tokens
157-
uit, err := tv.QueryEngine().UnspentTokensIterator()
158-
assert.NoError(err, "failed to get unspent tokens")
159-
defer uit.Close()
160-
var unspentTokenIDs []*token2.ID
161-
for {
162-
tok, err := uit.Next()
163-
assert.NoError(err, "failed to get next unspent token")
164-
if tok == nil {
165-
break
166-
}
167-
unspentTokenIDs = append(unspentTokenIDs, tok.Id)
168-
}
169-
ledgerTokenContent, err := net.QueryTokens(context, tms.Namespace(), unspentTokenIDs)
170-
if err != nil {
171-
errorMessages = append(errorMessages, fmt.Sprintf("failed to query tokens: [%s]", err))
172-
} else {
173-
assert.Equal(len(unspentTokenIDs), len(ledgerTokenContent))
174-
index := 0
175-
assert.NoError(tv.QueryEngine().GetTokenOutputs(unspentTokenIDs, func(id *token2.ID, tokenRaw []byte) error {
176-
for _, content := range ledgerTokenContent {
177-
if bytes.Equal(content, tokenRaw) {
178-
return nil
179-
}
180-
}
181-
182-
errorMessages = append(errorMessages, fmt.Sprintf("token content does not match at [%s][%d], [%s]", id, index, hash.Hashable(tokenRaw)))
183-
index++
184-
return nil
185-
}), "failed to match ledger token content with local")
50+
// check
51+
tms := token.GetManagementService(context, token.WithTMSID(m.TMSID))
52+
assert.NotNil(tms, "failed to get default tms")
53+
if m.Auditor {
54+
auditorWallet := tms.WalletManager().AuditorWallet(m.AuditorWalletID)
55+
assert.NotNil(auditorWallet, "cannot find auditor wallet [%s]", m.AuditorWalletID)
56+
db, err := ttx.NewAuditor(context, auditorWallet)
57+
assert.NoError(err, "failed to get auditor instance")
58+
return db.Check(context.Context())
18659
}
187-
188-
return errorMessages, nil
60+
db := ttx.NewOwner(context, tms)
61+
return db.Check(context.Context())
18962
}
19063

19164
type CheckTTXDBViewFactory struct{}
@@ -291,52 +164,3 @@ func (c *CheckIfExistsInVaultViewFactory) NewView(in []byte) (view.View, error)
291164

292165
return f, nil
293166
}
294-
295-
type TransactionRecord struct {
296-
TxID string
297-
Status driver.TxStatus
298-
}
299-
300-
type AuditDBTransactionIterator struct {
301-
*auditdb.TransactionIterator
302-
}
303-
304-
func (t *AuditDBTransactionIterator) Close() {
305-
t.TransactionIterator.Close()
306-
}
307-
308-
func (t *AuditDBTransactionIterator) Next() (*TransactionRecord, error) {
309-
next, err := t.TransactionIterator.Next()
310-
if err != nil {
311-
return nil, err
312-
}
313-
if next == nil {
314-
return nil, nil
315-
}
316-
return &TransactionRecord{
317-
TxID: next.TxID,
318-
Status: next.Status,
319-
}, nil
320-
}
321-
322-
type TTXDBTransactionIterator struct {
323-
*ttxdb.TransactionIterator
324-
}
325-
326-
func (t *TTXDBTransactionIterator) Close() {
327-
t.TransactionIterator.Close()
328-
}
329-
330-
func (t *TTXDBTransactionIterator) Next() (*TransactionRecord, error) {
331-
next, err := t.TransactionIterator.Next()
332-
if err != nil {
333-
return nil, err
334-
}
335-
if next == nil {
336-
return nil, nil
337-
}
338-
return &TransactionRecord{
339-
TxID: next.TxID,
340-
Status: next.Status,
341-
}, nil
342-
}

integration/token/fungible/views/owner.go

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/assert"
1313
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
1414
"github.com/hyperledger-labs/fabric-token-sdk/token"
15-
"github.com/hyperledger-labs/fabric-token-sdk/token/services/network"
1615
"github.com/hyperledger-labs/fabric-token-sdk/token/services/ttx"
1716
)
1817

@@ -31,16 +30,6 @@ func (r *SetTransactionOwnerStatusView) Call(context view.Context) (interface{},
3130
owner := ttx.NewOwner(context, token.GetManagementService(context))
3231
assert.NoError(owner.SetStatus(context.Context(), r.TxID, r.Status, r.Message), "failed to set status of [%s] to [%d]", r.TxID, r.Status)
3332

34-
if r.Status == ttx.Deleted {
35-
tms := token.GetManagementService(context)
36-
assert.NotNil(tms, "failed to get default tms")
37-
net := network.GetInstance(context, tms.Network(), tms.Channel())
38-
assert.NotNil(net, "failed to get network [%s:%s]", tms.Network(), tms.Channel())
39-
v, err := net.Vault(tms.Namespace())
40-
assert.NoError(err, "failed to get vault [%s:%s:%s]", tms.Network(), tms.Channel(), tms.Namespace())
41-
assert.NoError(v.DiscardTx(r.TxID), "failed to discard tx [%s:%s:%s:%s]", tms.Network(), tms.Channel(), tms.Namespace(), r.TxID)
42-
}
43-
4433
return nil, nil
4534
}
4635

0 commit comments

Comments
 (0)