func TestLedgerReadWrite(t *testing.T) { localConf := localconfig.Load() localConf.General.OrdererType = provisional.ConsensusTypeSbft genesis := provisional.New(localConf).GenesisBlock() _, rl := ramledger.New(10, genesis) b := Backend{ledger: rl} header := []byte("header") e1 := &cb.Envelope{Payload: []byte("data1")} e2 := &cb.Envelope{Payload: []byte("data2")} ebytes1, _ := proto.Marshal(e1) ebytes2, _ := proto.Marshal(e2) data := [][]byte{ebytes1, ebytes2} sgns := make(map[uint64][]byte) sgns[uint64(1)] = []byte("sgn1") sgns[uint64(22)] = []byte("sgn22") batch := simplebft.Batch{Header: header, Payloads: data, Signatures: sgns} b.Deliver(&batch) batch2 := b.LastBatch() if !reflect.DeepEqual(batch, *batch2) { t.Errorf("The wrong batch was returned by LastBatch after Deliver: %v (original was: %v)", batch2, &batch) } }
func newMockMultichainManager() *mockSupportManager { _, rl := ramledger.New(ledgerSize, genesisBlock) mm := &mockSupportManager{ chains: make(map[string]*mockSupport), } mm.chains[string(systemChainID)] = &mockSupport{ ledger: rl, } return mm }
// Tests a chain which contains blocks with multi-transactions mixed with config txs, and a single tx which is not a config tx, none count as config blocks so nil should return func TestGetConfigTxFailure(t *testing.T) { _, rl := ramledger.New(10, genesisBlock) for i := 0; i < 10; i++ { rl.Append([]*cb.Envelope{ makeNormalTx(provisional.TestChainID, i), makeConfigTx(provisional.TestChainID, i), }, nil) } rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, 11)}, nil) pctx := getConfigTx(rl) if pctx != nil { t.Fatalf("Should not have found a configuration tx") } }
// Tests for a normal chain which contains 3 config transactions and other normal transactions to make sure the right one returned func TestGetConfigTx(t *testing.T) { _, rl := ramledger.New(10, genesisBlock) for i := 0; i < 5; i++ { rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, i)}, nil) } rl.Append([]*cb.Envelope{makeConfigTx(provisional.TestChainID, 5)}, nil) ctx := makeConfigTx(provisional.TestChainID, 6) rl.Append([]*cb.Envelope{ctx}, nil) rl.Append([]*cb.Envelope{makeNormalTx(provisional.TestChainID, 7)}, nil) pctx := getConfigTx(rl) if !reflect.DeepEqual(ctx, pctx) { t.Fatalf("Did not select most recent config transaction") } }
// This test essentially brings the entire system up and is ultimately what main.go will replicate func TestManagerImpl(t *testing.T) { lf, rl := ramledger.New(10, genesisBlock) consenters := make(map[string]Consenter) consenters[conf.General.OrdererType] = &mockConsenter{} manager := NewManagerImpl(lf, consenters) _, ok := manager.GetChain("Fake") if ok { t.Errorf("Should not have found a chain that was not created") } chainSupport, ok := manager.GetChain(provisional.TestChainID) if !ok { t.Fatalf("Should have gotten chain which was initialized by ramledger") } messages := make([]*cb.Envelope, conf.General.BatchSize) for i := 0; i < int(conf.General.BatchSize); i++ { messages[i] = makeNormalTx(provisional.TestChainID, i) } for _, message := range messages { chainSupport.Enqueue(message) } it, _ := rl.Iterator(ab.SeekInfo_SPECIFIED, 1) select { case <-it.ReadyChan(): block, status := it.Next() if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve block") } for i := 0; i < int(conf.General.BatchSize); i++ { if !reflect.DeepEqual(utils.ExtractEnvelopeOrPanic(block, i), messages[i]) { t.Errorf("Block contents wrong at index %d", i) } } case <-time.After(time.Second): t.Fatalf("Block 1 not produced after timeout") } }
func (env *ramledgerTestFactory) New() (Factory, ReadWriter) { historySize := 10 return ramledger.New(historySize, genesisBlock) }
// This test brings up the entire system, with the mock consenter, including the broadcasters etc. and creates a new chain func TestNewChain(t *testing.T) { conf := config.Load() lf, rl := ramledger.New(10, genesisBlock) consenters := make(map[string]Consenter) consenters[conf.General.OrdererType] = &mockConsenter{} manager := NewManagerImpl(lf, consenters) oldGenesisTx := utils.ExtractEnvelopeOrPanic(genesisBlock, 0) oldGenesisTxPayload := utils.ExtractPayloadOrPanic(oldGenesisTx) oldConfigEnv := utils.UnmarshalConfigurationEnvelopeOrPanic(oldGenesisTxPayload.Data) newChainID := "TestNewChain" newChainMessage := utils.ChainCreationConfigurationTransaction(provisional.AcceptAllPolicyKey, newChainID, oldConfigEnv) status := manager.ProposeChain(newChainMessage) if status != cb.Status_SUCCESS { t.Fatalf("Error submitting chain creation request") } it, _ := rl.Iterator(ab.SeekInfo_SPECIFIED, 1) select { case <-it.ReadyChan(): block, status := it.Next() if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve block") } if len(block.Data.Data) != 1 { t.Fatalf("Should have had only one message in the orderer transaction block") } genesisConfigTx := utils.UnmarshalEnvelopeOrPanic(utils.UnmarshalPayloadOrPanic(utils.ExtractEnvelopeOrPanic(block, 0).Payload).Data) if !reflect.DeepEqual(genesisConfigTx, newChainMessage) { t.Errorf("Orderer config block contains wrong transaction, expected %v got %v", genesisConfigTx, newChainMessage) } case <-time.After(time.Second): t.Fatalf("Block 1 not produced after timeout in system chain") } chainSupport, ok := manager.GetChain(newChainID) if !ok { t.Fatalf("Should have gotten new chain which was created") } messages := make([]*cb.Envelope, conf.General.BatchSize) for i := 0; i < int(conf.General.BatchSize); i++ { messages[i] = makeNormalTx(newChainID, i) } for _, message := range messages { chainSupport.Enqueue(message) } it, _ = chainSupport.Reader().Iterator(ab.SeekInfo_SPECIFIED, 0) select { case <-it.ReadyChan(): block, status := it.Next() if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve new chain genesis block") } if len(block.Data.Data) != 1 { t.Fatalf("Should have had only one message in the new genesis block") } genesisConfigTx := utils.ExtractEnvelopeOrPanic(block, 0) if !reflect.DeepEqual(genesisConfigTx, newChainMessage) { t.Errorf("Genesis block contains wrong transaction, expected %v got %v", genesisConfigTx, newChainMessage) } case <-time.After(time.Second): t.Fatalf("Block 1 not produced after timeout in system chain") } select { case <-it.ReadyChan(): block, status := it.Next() if status != cb.Status_SUCCESS { t.Fatalf("Could not retrieve block on new chain") } for i := 0; i < int(conf.General.BatchSize); i++ { if !reflect.DeepEqual(utils.ExtractEnvelopeOrPanic(block, i), messages[i]) { t.Errorf("Block contents wrong at index %d in new chain", i) } } case <-time.After(time.Second): t.Fatalf("Block 1 not produced after timeout on new chain") } }
func main() { conf := config.Load() // Start the profiling service if enabled. // The ListenAndServe() call does not return unless an error occurs. if conf.General.Profile.Enabled { go func() { logger.Infof("Starting Go pprof profiling service on %s", conf.General.Profile.Address) panic(fmt.Errorf("Go pprof service failed: %s", http.ListenAndServe(conf.General.Profile.Address, nil))) }() } grpcServer := grpc.NewServer() lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort)) if err != nil { fmt.Println("Failed to listen:", err) return } var genesisBlock *cb.Block // Select the bootstrapping mechanism switch conf.General.GenesisMethod { case "provisional": genesisBlock = provisional.New(conf).GenesisBlock() default: panic(fmt.Errorf("Unknown genesis method %s", conf.General.GenesisMethod)) } var lf rawledger.Factory switch conf.General.LedgerType { case "file": location := conf.FileLedger.Location if location == "" { var err error location, err = ioutil.TempDir("", conf.FileLedger.Prefix) if err != nil { panic(fmt.Errorf("Error creating temp dir: %s", err)) } } lf, _ = fileledger.New(location, genesisBlock) case "ram": fallthrough default: lf, _ = ramledger.New(int(conf.RAMLedger.HistorySize), genesisBlock) } if conf.Kafka.Verbose { sarama.Logger = log.New(os.Stdout, "[sarama] ", log.Lshortfile) } consenters := make(map[string]multichain.Consenter) consenters["solo"] = solo.New(conf.General.BatchTimeout) consenters["kafka"] = kafka.New(conf.Kafka.Version, conf.Kafka.Retry) manager := multichain.NewManagerImpl(lf, consenters) server := NewServer( manager, int(conf.General.QueueSize), int(conf.General.MaxWindowSize), ) ab.RegisterAtomicBroadcastServer(grpcServer, server) grpcServer.Serve(lis) }