From 6b58537ba3059fe8eba218d0cea43793279eeda8 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 21 Nov 2016 13:44:42 -0500 Subject: [PATCH] [FAB-421] Add multi-chain support to rawledger The original rawledger interface only supports a single chain. However, to support multiple chains, this interface must be extended to support multiple chains. This changeset creates a Factory interface for the rawledger which supports the method GetOrCreate which will get the ledger if it already exists, or create a new one if not. In order to preserve some backwards compatability, and to support the notion of multi-chain more generally in the future with an ordering system chain, the factories accept a genesis block to seed the ordering system chain with. Change-Id: I99844ff1b9a11f383d08c23f60d95f848632876e Signed-off-by: Jason Yellick --- orderer/common/deliver/deliver_test.go | 12 +-- orderer/main.go | 4 +- orderer/rawledger/blackbox_test.go | 86 ++++++++++++++---- orderer/rawledger/fileledger/fileledger.go | 88 +++++++++++++++++-- .../rawledger/fileledger/fileledger_test.go | 8 +- orderer/rawledger/fileledger_test.go | 12 +-- orderer/rawledger/ramledger/ramledger.go | 75 ++++++++++++++-- orderer/rawledger/ramledger/ramledger_test.go | 11 ++- orderer/rawledger/ramledger_test.go | 12 +-- orderer/rawledger/rawledger.go | 6 ++ orderer/sbft/main.go | 2 +- orderer/solo/consensus_test.go | 11 ++- 12 files changed, 269 insertions(+), 58 deletions(-) diff --git a/orderer/common/deliver/deliver_test.go b/orderer/common/deliver/deliver_test.go index b4d888e9f90..991fbaf9347 100644 --- a/orderer/common/deliver/deliver_test.go +++ b/orderer/common/deliver/deliver_test.go @@ -71,7 +71,7 @@ func (m *mockD) Recv() (*ab.DeliverUpdate, error) { func TestOldestSeek(t *testing.T) { ledgerSize := 5 - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) for i := 1; i < ledgerSize; i++ { rl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil) } @@ -103,7 +103,7 @@ func TestOldestSeek(t *testing.T) { func TestNewestSeek(t *testing.T) { ledgerSize := 5 - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) for i := 1; i < ledgerSize; i++ { rl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil) } @@ -132,7 +132,7 @@ func TestNewestSeek(t *testing.T) { func TestSpecificSeek(t *testing.T) { ledgerSize := 5 - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) for i := 1; i < ledgerSize; i++ { rl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil) } @@ -160,7 +160,7 @@ func TestSpecificSeek(t *testing.T) { func TestBadSeek(t *testing.T) { ledgerSize := 5 - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) for i := 1; i < 2*ledgerSize; i++ { rl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil) } @@ -196,7 +196,7 @@ func TestBadSeek(t *testing.T) { func TestBadWindow(t *testing.T) { ledgerSize := 5 - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) m := newMockD() defer close(m.recvChan) @@ -219,7 +219,7 @@ func TestBadWindow(t *testing.T) { func TestAck(t *testing.T) { ledgerSize := 10 windowSize := uint64(2) - rl := ramledger.New(ledgerSize, genesisBlock) + _, rl := ramledger.New(ledgerSize, genesisBlock) for i := 1; i < ledgerSize; i++ { rl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte(fmt.Sprintf("%d", i))}}, nil) } diff --git a/orderer/main.go b/orderer/main.go index 2ed7a3d83f0..7be69ed7f23 100644 --- a/orderer/main.go +++ b/orderer/main.go @@ -186,11 +186,11 @@ func launchSolo(conf *config.TopLevel) { } } - rawledger = fileledger.New(location, genesisBlock) + _, rawledger = fileledger.New(location, genesisBlock) case "ram": fallthrough default: - rawledger = ramledger.New(int(conf.RAMLedger.HistorySize), genesisBlock) + _, rawledger = ramledger.New(int(conf.RAMLedger.HistorySize), genesisBlock) } lastConfigTx := retrieveConfiguration(rawledger) diff --git a/orderer/rawledger/blackbox_test.go b/orderer/rawledger/blackbox_test.go index e93be2c8fbc..38edebbce95 100644 --- a/orderer/rawledger/blackbox_test.go +++ b/orderer/rawledger/blackbox_test.go @@ -18,6 +18,7 @@ package rawledger_test import ( "bytes" + "reflect" "testing" . "github.com/hyperledger/fabric/orderer/rawledger" @@ -26,12 +27,12 @@ import ( ) type ledgerTestable interface { - Initialize() (ledgerFactory, error) + Initialize() (ledgerTestFactory, error) Name() string } -type ledgerFactory interface { - New() ReadWriter +type ledgerTestFactory interface { + New() (Factory, ReadWriter) Destroy() error Persistent() bool } @@ -52,7 +53,7 @@ func getBlock(number uint64, li ReadWriter) *cb.Block { } } -func allTest(t *testing.T, test func(ledgerFactory, *testing.T)) { +func allTest(t *testing.T, test func(ledgerTestFactory, *testing.T)) { for _, lt := range testables { t.Log("Running test for", lt.Name()) @@ -77,8 +78,8 @@ func TestInitialization(t *testing.T) { allTest(t, testInitialization) } -func testInitialization(lf ledgerFactory, t *testing.T) { - li := lf.New() +func testInitialization(lf ledgerTestFactory, t *testing.T) { + _, li := lf.New() if li.Height() != 1 { t.Fatalf("Block height should be 1") } @@ -92,14 +93,14 @@ func TestReinitialization(t *testing.T) { allTest(t, testReinitialization) } -func testReinitialization(lf ledgerFactory, t *testing.T) { +func testReinitialization(lf ledgerTestFactory, t *testing.T) { if !lf.Persistent() { t.Log("Skipping test as persistence is not available for this ledger type") return } - oli := lf.New() + _, oli := lf.New() aBlock := oli.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}, nil) - li := lf.New() + _, li := lf.New() if li.Height() != 2 { t.Fatalf("Block height should be 2") } @@ -116,8 +117,8 @@ func TestAddition(t *testing.T) { allTest(t, testAddition) } -func testAddition(lf ledgerFactory, t *testing.T) { - li := lf.New() +func testAddition(lf ledgerTestFactory, t *testing.T) { + _, li := lf.New() genesis := getBlock(0, li) if genesis == nil { t.Fatalf("Could not retrieve genesis block") @@ -141,8 +142,8 @@ func TestRetrieval(t *testing.T) { allTest(t, testRetrieval) } -func testRetrieval(lf ledgerFactory, t *testing.T) { - li := lf.New() +func testRetrieval(lf ledgerTestFactory, t *testing.T) { + _, li := lf.New() li.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}, nil) it, num := li.Iterator(ab.SeekInfo_OLDEST, 99) if num != 0 { @@ -180,8 +181,8 @@ func TestBlockedRetrieval(t *testing.T) { allTest(t, testBlockedRetrieval) } -func testBlockedRetrieval(lf ledgerFactory, t *testing.T) { - li := lf.New() +func testBlockedRetrieval(lf ledgerTestFactory, t *testing.T) { + _, li := lf.New() it, num := li.Iterator(ab.SeekInfo_SPECIFIED, 1) if num != 1 { t.Fatalf("Expected block iterator at 1, but got %d", num) @@ -206,3 +207,58 @@ func testBlockedRetrieval(lf ledgerFactory, t *testing.T) { t.Fatalf("Expected to successfully retrieve the second block") } } + +func TestMultichain(t *testing.T) { + allTest(t, testMultichain) +} + +func testMultichain(lf ledgerTestFactory, t *testing.T) { + f, _ := lf.New() + chain1 := []byte("chain1") + chain2 := []byte("chain2") + + c1p1 := []byte("c1 payload1") + c1p2 := []byte("c1 payload2") + + c2p1 := []byte("c2 payload1") + + c1, err := f.GetOrCreate(chain1) + if err != nil { + t.Fatalf("Error creating chain1: %s", err) + } + + c1.Append([]*cb.Envelope{&cb.Envelope{Payload: c1p1}}, nil) + c1b1 := c1.Append([]*cb.Envelope{&cb.Envelope{Payload: c1p2}}, nil) + + if c1.Height() != 2 { + t.Fatalf("Block height for c1 should be 2") + } + + c2, err := f.GetOrCreate(chain2) + if err != nil { + t.Fatalf("Error creating chain2: %s", err) + } + c2b0 := c2.Append([]*cb.Envelope{&cb.Envelope{Payload: c2p1}}, nil) + + if c2.Height() != 1 { + t.Fatalf("Block height for c2 should be 1") + } + + c1, err = f.GetOrCreate(chain1) + if err != nil { + t.Fatalf("Error retrieving chain1: %s", err) + } + + if b := getBlock(1, c1); !reflect.DeepEqual(c1b1, b) { + t.Fatalf("Did not properly store block 1 on chain 1:") + } + + c2, err = f.GetOrCreate(chain1) + if err != nil { + t.Fatalf("Error retrieving chain2: %s", err) + } + + if b := getBlock(0, c2); reflect.DeepEqual(c2b0, b) { + t.Fatalf("Did not properly store block 1 on chain 1") + } +} diff --git a/orderer/rawledger/fileledger/fileledger.go b/orderer/rawledger/fileledger/fileledger.go index c1921606a6d..3c97b44df61 100644 --- a/orderer/rawledger/fileledger/fileledger.go +++ b/orderer/rawledger/fileledger/fileledger.go @@ -20,6 +20,8 @@ import ( "fmt" "io/ioutil" "os" + "reflect" + "sync" "github.com/hyperledger/fabric/orderer/rawledger" cb "github.com/hyperledger/fabric/protos/common" @@ -55,21 +57,92 @@ type fileLedger struct { marshaler *jsonpb.Marshaler } -// New creates a new instance of the file ledger -func New(directory string, genesisBlock *cb.Block) rawledger.ReadWriter { +type fileLedgerFactory struct { + directory string + ledgers map[string]rawledger.ReadWriter + mutex sync.Mutex +} + +func New(directory string, systemGenesis *cb.Block) (rawledger.Factory, rawledger.ReadWriter) { + env := &cb.Envelope{} + err := proto.Unmarshal(systemGenesis.Data.Data[0], env) + if err != nil { + logger.Fatalf("Bad envelope in genesis block: %s", err) + } + + payload := &cb.Payload{} + err = proto.Unmarshal(env.Payload, payload) + if err != nil { + logger.Fatalf("Bad payload in genesis block: %s", err) + } + logger.Debugf("Initializing fileLedger at '%s'", directory) if err := os.MkdirAll(directory, 0700); err != nil { - panic(err) + logger.Fatalf("Could not create directory %s: %s", directory, err) } + + flf := &fileLedgerFactory{ + directory: directory, + ledgers: make(map[string]rawledger.ReadWriter), + } + + flt, err := flf.GetOrCreate(payload.Header.ChainHeader.ChainID) + if err != nil { + logger.Fatalf("Error getting orderer system chain dir: %s", err) + } + + fl := flt.(*fileLedger) + + if fl.height > 0 { + block, ok := fl.readBlock(0) + if !ok { + logger.Fatalf("Error reading genesis block for chain of height %d", fl.height) + } + if !reflect.DeepEqual(block, systemGenesis) { + logger.Fatalf("Attempted to reconfigure an existing ordering system chain with new genesis block") + } + } else { + fl.writeBlock(systemGenesis) + fl.height = 1 + fl.lastHash = systemGenesis.Header.Hash() + } + + return flf, fl +} + +func (flf *fileLedgerFactory) GetOrCreate(chainID []byte) (rawledger.ReadWriter, error) { + flf.mutex.Lock() + defer flf.mutex.Unlock() + + key := string(chainID) + + // Check a second time with the lock held + l, ok := flf.ledgers[key] + if ok { + return l, nil + } + + directory := fmt.Sprintf("%s/%x", flf.directory, chainID) + + logger.Debugf("Initializing chain at '%s'", directory) + + if err := os.MkdirAll(directory, 0700); err != nil { + return nil, err + } + + ch := newChain(directory) + flf.ledgers[key] = ch + return ch, nil +} + +// newChain creates a new chain backed by a file ledger +func newChain(directory string) rawledger.ReadWriter { fl := &fileLedger{ directory: directory, fqFormatString: directory + "/" + blockFileFormatString, signal: make(chan struct{}), marshaler: &jsonpb.Marshaler{Indent: " "}, } - if _, err := os.Stat(fl.blockFilename(genesisBlock.Header.Number)); os.IsNotExist(err) { - fl.writeBlock(genesisBlock) - } fl.initializeBlockHeight() logger.Debugf("Initialized to block height %d with hash %x", fl.height-1, fl.lastHash) return fl @@ -97,6 +170,9 @@ func (fl *fileLedger) initializeBlockHeight() { nextNumber++ } fl.height = nextNumber + if fl.height == 0 { + return + } block, found := fl.readBlock(fl.height - 1) if !found { panic(fmt.Errorf("Block %d was in directory listing but error reading", fl.height-1)) diff --git a/orderer/rawledger/fileledger/fileledger_test.go b/orderer/rawledger/fileledger/fileledger_test.go index 29f0f251d2a..1ef36c8acf8 100644 --- a/orderer/rawledger/fileledger/fileledger_test.go +++ b/orderer/rawledger/fileledger/fileledger_test.go @@ -44,11 +44,12 @@ type testEnv struct { } func initialize(t *testing.T) (*testEnv, *fileLedger) { - name, err := ioutil.TempDir("", "hyperledger") + name, err := ioutil.TempDir("", "hyperledger_fabric") if err != nil { t.Fatalf("Error creating temp dir: %s", err) } - return &testEnv{location: name, t: t}, New(name, genesisBlock).(*fileLedger) + _, fl := New(name, genesisBlock) + return &testEnv{location: name, t: t}, fl.(*fileLedger) } func (tev *testEnv) tearDown() { @@ -77,7 +78,8 @@ func TestReinitialization(t *testing.T) { tev, ofl := initialize(t) defer tev.tearDown() ofl.Append([]*cb.Envelope{&cb.Envelope{Payload: []byte("My Data")}}, nil) - fl := New(tev.location, genesisBlock).(*fileLedger) + _, flt := New(tev.location, genesisBlock) + fl := flt.(*fileLedger) if fl.height != 2 { t.Fatalf("Block height should be 2") } diff --git a/orderer/rawledger/fileledger_test.go b/orderer/rawledger/fileledger_test.go index 53ee7a78bba..4a31d9dcfeb 100644 --- a/orderer/rawledger/fileledger_test.go +++ b/orderer/rawledger/fileledger_test.go @@ -39,35 +39,35 @@ func init() { testables = append(testables, &fileLedgerTestEnv{}) } -type fileLedgerFactory struct { +type fileLedgerTestFactory struct { location string } type fileLedgerTestEnv struct { } -func (env *fileLedgerTestEnv) Initialize() (ledgerFactory, error) { +func (env *fileLedgerTestEnv) Initialize() (ledgerTestFactory, error) { var err error location, err := ioutil.TempDir("", "hyperledger") if err != nil { return nil, err } - return &fileLedgerFactory{location: location}, nil + return &fileLedgerTestFactory{location: location}, nil } func (env *fileLedgerTestEnv) Name() string { return "fileledger" } -func (env *fileLedgerFactory) Destroy() error { +func (env *fileLedgerTestFactory) Destroy() error { err := os.RemoveAll(env.location) return err } -func (env *fileLedgerFactory) Persistent() bool { +func (env *fileLedgerTestFactory) Persistent() bool { return true } -func (env *fileLedgerFactory) New() ReadWriter { +func (env *fileLedgerTestFactory) New() (Factory, ReadWriter) { return fileledger.New(env.location, genesisBlock) } diff --git a/orderer/rawledger/ramledger/ramledger.go b/orderer/rawledger/ramledger/ramledger.go index fdd888138dc..2d817819e85 100644 --- a/orderer/rawledger/ramledger/ramledger.go +++ b/orderer/rawledger/ramledger/ramledger.go @@ -17,6 +17,8 @@ limitations under the License. package ramledger import ( + "sync" + "github.com/hyperledger/fabric/orderer/rawledger" cb "github.com/hyperledger/fabric/protos/common" ab "github.com/hyperledger/fabric/protos/orderer" @@ -48,14 +50,65 @@ type ramLedger struct { newest *simpleList } -// New creates a new instance of the ram ledger -func New(maxSize int, genesis *cb.Block) rawledger.ReadWriter { +type ramLedgerFactory struct { + maxSize int + ledgers map[string]rawledger.ReadWriter + mutex sync.Mutex +} + +func New(maxSize int, systemGenesis *cb.Block) (rawledger.Factory, rawledger.ReadWriter) { + rlf := &ramLedgerFactory{ + maxSize: maxSize, + ledgers: make(map[string]rawledger.ReadWriter), + } + env := &cb.Envelope{} + err := proto.Unmarshal(systemGenesis.Data.Data[0], env) + if err != nil { + logger.Fatalf("Bad envelope in genesis block: %s", err) + } + + payload := &cb.Payload{} + err = proto.Unmarshal(env.Payload, payload) + if err != nil { + logger.Fatalf("Bad payload in genesis block: %s", err) + } + + rl, _ := rlf.GetOrCreate(payload.Header.ChainHeader.ChainID) + rl.(*ramLedger).appendBlock(systemGenesis) + return rlf, rl +} + +func (rlf *ramLedgerFactory) GetOrCreate(chainID []byte) (rawledger.ReadWriter, error) { + rlf.mutex.Lock() + defer rlf.mutex.Unlock() + + key := string(chainID) + + // Check a second time with the lock held + l, ok := rlf.ledgers[key] + if ok { + return l, nil + } + + ch := newChain(rlf.maxSize) + rlf.ledgers[key] = ch + return ch, nil +} + +// newChain creates a new instance of the ram ledger for a chain +func newChain(maxSize int) rawledger.ReadWriter { + preGenesis := &cb.Block{ + Header: &cb.BlockHeader{ + Number: ^uint64(0), + }, + } + rl := &ramLedger{ maxSize: maxSize, size: 1, oldest: &simpleList{ signal: make(chan struct{}), - block: genesis, + block: preGenesis, }, } rl.newest = rl.oldest @@ -88,8 +141,10 @@ func (rl *ramLedger) Iterator(startType ab.SeekInfo_StartType, specified uint64) } close(list.signal) case ab.SeekInfo_SPECIFIED: + logger.Debugf("Attempting to return block %d", specified) oldest := rl.oldest - if specified < oldest.block.Header.Number || specified > rl.newest.block.Header.Number+1 { + // Note the two +1's here is to accomodate the 'preGenesis' block of ^uint64(0) + if specified+1 < oldest.block.Header.Number+1 || specified > rl.newest.block.Header.Number+1 { return &rawledger.NotFoundErrorIterator{}, 0 } @@ -111,7 +166,16 @@ func (rl *ramLedger) Iterator(startType ab.SeekInfo_StartType, specified uint64) list = list.next // No need for nil check, because of range check above } } - return &cursor{list: list}, list.block.Header.Number + 1 + cursor := &cursor{list: list} + blockNum := list.block.Header.Number + 1 + + // If the cursor is for pre-genesis, skip it, the block number wraps + if blockNum == ^uint64(0) { + cursor.Next() + blockNum++ + } + + return cursor, blockNum } // Next blocks until there is a new block available, or returns an error if the next block is no longer retrievable @@ -175,6 +239,7 @@ func (rl *ramLedger) appendBlock(block *cb.Block) { rl.size++ if rl.size > rl.maxSize { + logger.Debugf("RAM ledger max size about to be exceeded, removing oldest item: %d", rl.oldest.block.Header.Number) rl.oldest = rl.oldest.next rl.size-- } diff --git a/orderer/rawledger/ramledger/ramledger_test.go b/orderer/rawledger/ramledger/ramledger_test.go index 028b00023a5..e6a952f7dbe 100644 --- a/orderer/rawledger/ramledger/ramledger_test.go +++ b/orderer/rawledger/ramledger/ramledger_test.go @@ -38,7 +38,8 @@ func init() { // Note that 'only' is applicable because the genesis block will be discarded func TestAppend(t *testing.T) { maxSize := 3 - rl := New(maxSize, genesisBlock).(*ramLedger) + _, rlt := New(maxSize, genesisBlock) + rl := rlt.(*ramLedger) var blocks []*cb.Block for i := 0; i < 3; i++ { blocks = append(blocks, &cb.Block{Header: &cb.BlockHeader{Number: uint64(i + 1)}}) @@ -63,7 +64,8 @@ func TestAppend(t *testing.T) { // TestSignal checks if the signal channel closes when an item is appended func TestSignal(t *testing.T) { maxSize := 3 - rl := New(maxSize, genesisBlock).(*ramLedger) + _, rlt := New(maxSize, genesisBlock) + rl := rlt.(*ramLedger) item := rl.newest select { case <-item.signal: @@ -84,8 +86,9 @@ func TestSignal(t *testing.T) { func TestTruncationSafety(t *testing.T) { maxSize := 3 newBlocks := 10 - rl := New(maxSize, genesisBlock).(*ramLedger) - item := rl.oldest + _, rlt := New(maxSize, genesisBlock) + rl := rlt.(*ramLedger) + item := rl.oldest.next for i := 0; i < newBlocks; i++ { rl.appendBlock(&cb.Block{Header: &cb.BlockHeader{Number: uint64(i + 1)}}) } diff --git a/orderer/rawledger/ramledger_test.go b/orderer/rawledger/ramledger_test.go index aa17421838b..7a42d06642f 100644 --- a/orderer/rawledger/ramledger_test.go +++ b/orderer/rawledger/ramledger_test.go @@ -25,27 +25,27 @@ func init() { testables = append(testables, &ramLedgerTestEnv{}) } -type ramLedgerFactory struct{} +type ramledgerTestFactory struct{} type ramLedgerTestEnv struct{} -func (env *ramLedgerTestEnv) Initialize() (ledgerFactory, error) { - return &ramLedgerFactory{}, nil +func (env *ramLedgerTestEnv) Initialize() (ledgerTestFactory, error) { + return &ramledgerTestFactory{}, nil } func (env *ramLedgerTestEnv) Name() string { return "ramledger" } -func (env *ramLedgerFactory) Destroy() error { +func (env *ramledgerTestFactory) Destroy() error { return nil } -func (env *ramLedgerFactory) Persistent() bool { +func (env *ramledgerTestFactory) Persistent() bool { return false } -func (env *ramLedgerFactory) New() ReadWriter { +func (env *ramledgerTestFactory) New() (Factory, ReadWriter) { historySize := 10 return ramledger.New(historySize, genesisBlock) } diff --git a/orderer/rawledger/rawledger.go b/orderer/rawledger/rawledger.go index b270b10c06f..7f819ebdff5 100644 --- a/orderer/rawledger/rawledger.go +++ b/orderer/rawledger/rawledger.go @@ -21,6 +21,12 @@ import ( ab "github.com/hyperledger/fabric/protos/orderer" ) +// Factory retrieves or creates new ledgers by chainID +type Factory interface { + // GetOrCreate gets an existing ledger (if it exists) or creates it if it does not + GetOrCreate(chainID []byte) (ReadWriter, error) +} + // Iterator is useful for a chain Reader to stream blocks as they are created type Iterator interface { // Next blocks until there is a new block available, or returns an error if the next block is no longer retrievable diff --git a/orderer/sbft/main.go b/orderer/sbft/main.go index e00a02ca974..4ec5dbe9e73 100644 --- a/orderer/sbft/main.go +++ b/orderer/sbft/main.go @@ -126,7 +126,7 @@ func serve(c flags) { if err != nil { panic(err) } - ledger := fileledger.New(c.dataDir, genesisBlock) + _, ledger := fileledger.New(c.dataDir, genesisBlock) s.backend, err = backend.NewBackend(config.Peers, conn, ledger, persist) if err != nil { panic(err) diff --git a/orderer/solo/consensus_test.go b/orderer/solo/consensus_test.go index fddb32419b1..f4f1dfc9b51 100644 --- a/orderer/solo/consensus_test.go +++ b/orderer/solo/consensus_test.go @@ -123,7 +123,8 @@ func (m *mockB) Recv() (*cb.Envelope, error) { func TestEmptyBatch(t *testing.T) { filters, cm := getFiltersAndConfig() - bs := newPlainConsenter(1, time.Millisecond, ramledger.New(10, genesisBlock), filters, cm) + _, rl := ramledger.New(10, genesisBlock) + bs := newPlainConsenter(1, time.Millisecond, rl, filters, cm) if bs.rl.(rawledger.Reader).Height() != 1 { t.Fatalf("Expected no new blocks created") } @@ -132,7 +133,7 @@ func TestEmptyBatch(t *testing.T) { func TestBatchTimer(t *testing.T) { filters, cm := getFiltersAndConfig() batchSize := 2 - rl := ramledger.New(10, genesisBlock) + _, rl := ramledger.New(10, genesisBlock) bs := NewConsenter(batchSize, time.Millisecond, rl, filters, cm) defer bs.halt() it, _ := rl.Iterator(ab.SeekInfo_SPECIFIED, 1) @@ -150,7 +151,8 @@ func TestFilledBatch(t *testing.T) { filters, cm := getFiltersAndConfig() batchSize := 2 messages := 10 - bs := newPlainConsenter(batchSize, time.Hour, ramledger.New(10, genesisBlock), filters, cm) + _, rl := ramledger.New(10, genesisBlock) + bs := newPlainConsenter(batchSize, time.Hour, rl, filters, cm) done := make(chan struct{}) go func() { bs.main() @@ -170,7 +172,8 @@ func TestFilledBatch(t *testing.T) { func TestReconfigureGoodPath(t *testing.T) { filters, cm := getFiltersAndConfig() batchSize := 2 - bs := newPlainConsenter(batchSize, time.Hour, ramledger.New(10, genesisBlock), filters, cm) + _, rl := ramledger.New(10, genesisBlock) + bs := newPlainConsenter(batchSize, time.Hour, rl, filters, cm) done := make(chan struct{}) go func() { bs.main()