Skip to content

Commit 2f03cf3

Browse files
committed
This commit refactors the ledger codes
https://jira.hyperledger.org/browse/FAB-602 The refactoring allows sharing of transaction execution and validation code across goleveldb and couchdb. This refactoring also allows plugging-in different schemes for various aspects of transaction execution such as maintianing isolation during simulation, validation and commit. Change-Id: I0d3fb1cdff99c3f6f991e7b7469920173f194a87 Signed-off-by: manish <[email protected]>
1 parent 4c63856 commit 2f03cf3

28 files changed

+1546
-922
lines changed

core/ledger/history/couchdb_histmgr.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import (
2020
"bytes"
2121
"strconv"
2222

23-
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt"
23+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwset"
2424
"github.com/hyperledger/fabric/core/ledger/util/couchdb"
2525
"github.com/hyperledger/fabric/protos/common"
2626
putils "github.com/hyperledger/fabric/protos/utils"
@@ -72,7 +72,7 @@ func (histmgr *CouchDBHistMgr) Commit(block *common.Block) error {
7272
}
7373

7474
//preparation for extracting RWSet from transaction
75-
txRWSet := &txmgmt.TxReadWriteSet{}
75+
txRWSet := &rwset.TxReadWriteSet{}
7676

7777
// Get the Result from the Action and then Unmarshal
7878
// it into a TxReadWriteSet using custom unmarshalling

core/ledger/kvledger/kv_ledger.go

+9-11
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ import (
2525
"github.com/hyperledger/fabric/core/ledger/blkstorage"
2626
"github.com/hyperledger/fabric/core/ledger/blkstorage/fsblkstorage"
2727
"github.com/hyperledger/fabric/core/ledger/history"
28-
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt"
2928
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/couchdbtxmgmt"
30-
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/lockbasedtxmgmt"
29+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb/stateleveldb"
30+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr"
3131
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
3232

3333
logging "github.com/op/go-logging"
3434

35+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr"
3536
"github.com/hyperledger/fabric/protos/common"
3637
pb "github.com/hyperledger/fabric/protos/peer"
3738
)
@@ -60,7 +61,7 @@ func NewConf(filesystemPath string, maxBlockfileSize int) *Conf {
6061
// This implementation provides a key-value based data model
6162
type KVLedger struct {
6263
blockStore blkstorage.BlockStore
63-
txtmgmt txmgmt.TxMgr
64+
txtmgmt txmgr.TxMgr
6465
historymgmt history.HistMgr
6566
pendingBlockToCommit *common.Block
6667
}
@@ -81,7 +82,7 @@ func NewKVLedger(conf *Conf) (*KVLedger, error) {
8182
blockStore := fsblkstorage.NewFsBlockStore(blockStorageConf, indexConfig)
8283

8384
//State and History database managers
84-
var txmgmt txmgmt.TxMgr
85+
var txmgmt txmgr.TxMgr
8586
var historymgmt history.HistMgr
8687

8788
if ledgerconfig.IsCouchDBEnabled() == true {
@@ -97,8 +98,9 @@ func NewKVLedger(conf *Conf) (*KVLedger, error) {
9798
couchDBDef.Username, //enter couchDB id here
9899
couchDBDef.Password) //enter couchDB pw here
99100
} else {
100-
// Fall back to using RocksDB lockbased transaction manager
101-
txmgmt = lockbasedtxmgmt.NewLockBasedTxMgr(&lockbasedtxmgmt.Conf{DBPath: conf.txMgrDBPath})
101+
// Fall back to using goleveldb lockbased transaction manager
102+
db := stateleveldb.NewVersionedDBProvider(&stateleveldb.Conf{DBPath: conf.txMgrDBPath}).GetDBHandle("Default")
103+
txmgmt = lockbasedtxmgr.NewLockBasedTxMgr(db)
102104
}
103105

104106
if ledgerconfig.IsHistoryDBEnabled() == true {
@@ -112,13 +114,10 @@ func NewKVLedger(conf *Conf) (*KVLedger, error) {
112114
couchDBDef.Username, //enter couchDB id here
113115
couchDBDef.Password) //enter couchDB pw here
114116
}
115-
116117
l := &KVLedger{blockStore, txmgmt, historymgmt, nil}
117-
118118
if err := recoverStateDB(l); err != nil {
119119
panic(fmt.Errorf(`Error during state DB recovery:%s`, err))
120120
}
121-
122121
return l, nil
123122
}
124123

@@ -136,7 +135,7 @@ func recoverStateDB(l *KVLedger) error {
136135
if savepointValue, err = l.txtmgmt.GetBlockNumFromSavepoint(); err != nil {
137136
return err
138137
}
139-
138+
logger.Debugf("savepointValue=%d, info.Height=%d", savepointValue, info.Height)
140139
//Checking whether the savepointValue is in sync with block storage height
141140
if savepointValue == info.Height {
142141
return nil
@@ -159,7 +158,6 @@ func recoverStateDB(l *KVLedger) error {
159158
}
160159
}
161160
l.pendingBlockToCommit = nil
162-
163161
return nil
164162
}
165163

core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_tx_simulator.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@ import (
2121
"reflect"
2222

2323
"github.com/hyperledger/fabric/core/ledger"
24-
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt"
24+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwset"
2525
logging "github.com/op/go-logging"
2626
)
2727

2828
type kvReadCache struct {
29-
kvRead *txmgmt.KVRead
29+
kvRead *rwset.KVRead
3030
cachedValue []byte
3131
}
3232

3333
type nsRWs struct {
3434
readMap map[string]*kvReadCache
35-
writeMap map[string]*txmgmt.KVWrite
35+
writeMap map[string]*rwset.KVWrite
3636
}
3737

3838
func newNsRWs() *nsRWs {
39-
return &nsRWs{make(map[string]*kvReadCache), make(map[string]*txmgmt.KVWrite)}
39+
return &nsRWs{make(map[string]*kvReadCache), make(map[string]*rwset.KVWrite)}
4040
}
4141

4242
// CouchDBTxSimulator is a transaction simulator used in `CouchDBTxMgr`
@@ -104,7 +104,7 @@ func (s *CouchDBTxSimulator) GetState(ns string, key string) ([]byte, error) {
104104
}
105105
}
106106

107-
nsRWs.readMap[key] = &kvReadCache{txmgmt.NewKVRead(key, version), value}
107+
nsRWs.readMap[key] = &kvReadCache{rwset.NewKVRead(key, version), value}
108108
logger.Debugf("===COUCHDB=== Exiting CouchDBTxSimulator.GetState()")
109109
return value, nil
110110
}
@@ -131,7 +131,7 @@ func (s *CouchDBTxSimulator) SetState(ns string, key string, value []byte) error
131131
kvWrite.SetValue(value)
132132
return nil
133133
}
134-
nsRWs.writeMap[key] = txmgmt.NewKVWrite(key, value)
134+
nsRWs.writeMap[key] = rwset.NewKVWrite(key, value)
135135
logger.Debugf("===COUCHDB=== Exiting CouchDBTxSimulator.SetState()")
136136
return nil
137137
}
@@ -147,26 +147,26 @@ func (s *CouchDBTxSimulator) Done() {
147147
s.txmgr.commitRWLock.RUnlock()
148148
}
149149

150-
func (s *CouchDBTxSimulator) getTxReadWriteSet() *txmgmt.TxReadWriteSet {
151-
txRWSet := &txmgmt.TxReadWriteSet{}
150+
func (s *CouchDBTxSimulator) getTxReadWriteSet() *rwset.TxReadWriteSet {
151+
txRWSet := &rwset.TxReadWriteSet{}
152152
sortedNamespaces := getSortedKeys(s.rwMap)
153153
for _, ns := range sortedNamespaces {
154154
//Get namespace specific read-writes
155155
nsReadWriteMap := s.rwMap[ns]
156156
//add read set
157-
reads := []*txmgmt.KVRead{}
157+
reads := []*rwset.KVRead{}
158158
sortedReadKeys := getSortedKeys(nsReadWriteMap.readMap)
159159
for _, key := range sortedReadKeys {
160160
reads = append(reads, nsReadWriteMap.readMap[key].kvRead)
161161
}
162162

163163
//add write set
164-
writes := []*txmgmt.KVWrite{}
164+
writes := []*rwset.KVWrite{}
165165
sortedWriteKeys := getSortedKeys(nsReadWriteMap.writeMap)
166166
for _, key := range sortedWriteKeys {
167167
writes = append(writes, nsReadWriteMap.writeMap[key])
168168
}
169-
nsRWs := &txmgmt.NsReadWriteSet{NameSpace: ns, Reads: reads, Writes: writes}
169+
nsRWs := &rwset.NsReadWriteSet{NameSpace: ns, Reads: reads, Writes: writes}
170170
txRWSet.NsRWs = append(txRWSet.NsRWs, nsRWs)
171171
}
172172

@@ -239,7 +239,7 @@ func (itr *sKVItr) Next() (ledger.QueryResult, error) {
239239
// Get existing cache for RW at the namespace of the result set if it exists. If none exists, then create it.
240240
nsRWs := itr.simulator.getOrCreateNsRWHolder(itr.scanner.namespace)
241241
nsRWs.readMap[committedKV.key] = &kvReadCache{
242-
&txmgmt.KVRead{Key: committedKV.key, Version: committedKV.version}, committedKV.value}
242+
&rwset.KVRead{Key: committedKV.key, Version: committedKV.version}, committedKV.value}
243243

244244
return &ledger.KV{Key: committedKV.key, Value: committedKV.value}, nil
245245
}

core/ledger/kvledger/txmgmt/couchdbtxmgmt/couchdb_txmgr.go

+19-18
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ package couchdbtxmgmt
1919
import (
2020
"bytes"
2121
"encoding/json"
22-
"errors"
2322
"sync"
2423

2524
"github.com/golang/protobuf/proto"
2625
"github.com/hyperledger/fabric/core/ledger"
27-
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt"
2826
"github.com/hyperledger/fabric/core/ledger/util/couchdb"
2927
"github.com/hyperledger/fabric/core/ledger/util/db"
3028
"github.com/op/go-logging"
3129

32-
"github.com/hyperledger/fabric/core/ledger/kvledger/version"
30+
"fmt"
31+
32+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwset"
33+
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
3334
"github.com/hyperledger/fabric/protos/common"
3435
pb "github.com/hyperledger/fabric/protos/peer"
3536
putils "github.com/hyperledger/fabric/protos/utils"
@@ -153,7 +154,7 @@ func (txmgr *CouchDBTxMgr) ValidateAndPrepare(block *common.Block, doMVCCValidat
153154
}
154155

155156
//preparation for extracting RWSet from transaction
156-
txRWSet := &txmgmt.TxReadWriteSet{}
157+
txRWSet := &rwset.TxReadWriteSet{}
157158

158159
// Get the Result from the Action
159160
// and then Unmarshal it into a TxReadWriteSet using custom unmarshalling
@@ -201,7 +202,7 @@ func (txmgr *CouchDBTxMgr) Shutdown() {
201202
txmgr.db.Close()
202203
}
203204

204-
func (txmgr *CouchDBTxMgr) validateTx(txRWSet *txmgmt.TxReadWriteSet) (bool, error) {
205+
func (txmgr *CouchDBTxMgr) validateTx(txRWSet *rwset.TxReadWriteSet) (bool, error) {
205206

206207
var err error
207208
var currentVersion *version.Height
@@ -226,7 +227,7 @@ func (txmgr *CouchDBTxMgr) validateTx(txRWSet *txmgmt.TxReadWriteSet) (bool, err
226227
return true, nil
227228
}
228229

229-
func (txmgr *CouchDBTxMgr) addWriteSetToBatch(txRWSet *txmgmt.TxReadWriteSet, txHeight *version.Height) error {
230+
func (txmgr *CouchDBTxMgr) addWriteSetToBatch(txRWSet *rwset.TxReadWriteSet, txHeight *version.Height) error {
230231
if txmgr.updateSet == nil {
231232
txmgr.updateSet = newUpdateSet()
232233
}
@@ -259,7 +260,7 @@ func (txmgr *CouchDBTxMgr) Commit() error {
259260
// SaveDoc using couchdb client and use JSON format
260261
rev, err := txmgr.couchDB.SaveDoc(k, "", v.value, nil)
261262
if err != nil {
262-
logger.Errorf("===COUCHDB=== Error during Commit(): %s\n", err.Error())
263+
logger.Debugf("===COUCHDB=== Error during Commit(): %s\n", err)
263264
return err
264265
}
265266
if rev != "" {
@@ -280,7 +281,7 @@ func (txmgr *CouchDBTxMgr) Commit() error {
280281
// SaveDoc using couchdb client and use attachment
281282
rev, err := txmgr.couchDB.SaveDoc(k, "", nil, attachments)
282283
if err != nil {
283-
logger.Errorf("===COUCHDB=== Error during Commit(): %s\n", err.Error())
284+
logger.Debugf("===COUCHDB=== Error during Commit(): %s\n", err)
284285
return err
285286
}
286287
if rev != "" {
@@ -294,7 +295,7 @@ func (txmgr *CouchDBTxMgr) Commit() error {
294295
// Record a savepoint
295296
err := txmgr.recordSavepoint()
296297
if err != nil {
297-
logger.Errorf("===COUCHDB=== Error during recordSavepoint: %s\n", err.Error())
298+
logger.Debugf("===COUCHDB=== Error during recordSavepoint: %s\n", err)
298299
return err
299300
}
300301

@@ -312,37 +313,37 @@ func (txmgr *CouchDBTxMgr) recordSavepoint() error {
312313
// ensure full commit to flush all changes until now to disk
313314
dbResponse, err := txmgr.couchDB.EnsureFullCommit()
314315
if err != nil || dbResponse.Ok != true {
315-
logger.Errorf("====COUCHDB==== Failed to perform full commit\n")
316-
return errors.New("Failed to perform full commit")
316+
logger.Debugf("====COUCHDB==== Failed to perform full commit\n")
317+
return fmt.Errorf("Failed to perform full commit. Err: %s", err)
317318
}
318319

319320
// construct savepoint document
320321
// UpdateSeq would be useful if we want to get all db changes since a logical savepoint
321322
dbInfo, _, err := txmgr.couchDB.GetDatabaseInfo()
322323
if err != nil {
323-
logger.Errorf("====COUCHDB==== Failed to get DB info %s\n", err.Error())
324+
logger.Debugf("====COUCHDB==== Failed to get DB info %s\n", err)
324325
return err
325326
}
326327
savepointDoc.BlockNum = txmgr.blockNum
327328
savepointDoc.UpdateSeq = dbInfo.UpdateSeq
328329

329330
savepointDocJSON, err := json.Marshal(savepointDoc)
330331
if err != nil {
331-
logger.Errorf("====COUCHDB==== Failed to create savepoint data %s\n", err.Error())
332+
logger.Debugf("====COUCHDB==== Failed to create savepoint data %s\n", err)
332333
return err
333334
}
334335

335336
// SaveDoc using couchdb client and use JSON format
336337
_, err = txmgr.couchDB.SaveDoc(savepointDocID, "", savepointDocJSON, nil)
337338
if err != nil {
338-
logger.Errorf("====CouchDB==== Failed to save the savepoint to DB %s\n", err.Error())
339+
logger.Debugf("====CouchDB==== Failed to save the savepoint to DB %s\n", err)
339340
}
340341

341342
// ensure full commit to flush savepoint to disk
342343
dbResponse, err = txmgr.couchDB.EnsureFullCommit()
343344
if err != nil || dbResponse.Ok != true {
344-
logger.Errorf("====COUCHDB==== Failed to perform full commit\n")
345-
return errors.New("Failed to perform full commit")
345+
logger.Debugf("====COUCHDB==== Failed to perform full commit\n")
346+
return fmt.Errorf("Failed to perform full commit. Err:%s", err)
346347
}
347348
return nil
348349
}
@@ -354,14 +355,14 @@ func (txmgr *CouchDBTxMgr) GetBlockNumFromSavepoint() (uint64, error) {
354355
savepointJSON, _, err := txmgr.couchDB.ReadDoc(savepointDocID)
355356
if err != nil {
356357
// TODO: differentiate between 404 and some other error code
357-
logger.Errorf("====COUCHDB==== Failed to read savepoint data %s\n", err.Error())
358+
logger.Debugf("====COUCHDB==== Failed to read savepoint data %s\n", err)
358359
return 0, err
359360
}
360361

361362
savepointDoc := &couchSavepointData{}
362363
err = json.Unmarshal(savepointJSON, &savepointDoc)
363364
if err != nil {
364-
logger.Errorf("====COUCHDB==== Failed to read savepoint data %s\n", err.Error())
365+
logger.Debugf("====COUCHDB==== Failed to read savepoint data %s\n", err)
365366
return 0, err
366367
}
367368

0 commit comments

Comments
 (0)