Exemplo n.º 1
0
func (cbs *commonBootstrapper) encodeBatchSize() *cb.SignedConfigurationItem {
	configItemKey := sharedconfig.BatchSizeKey
	configItemValue := utils.MarshalOrPanic(&ab.BatchSize{Messages: cbs.batchSize})
	modPolicy := configtx.DefaultModificationPolicyID

	configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch)
	configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
	return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil}
}
Exemplo n.º 2
0
func (kbs *kafkaBootstrapper) encodeKafkaBrokers() *cb.SignedConfigurationItem {
	configItemKey := sharedconfig.KafkaBrokersKey
	configItemValue := utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: kbs.kafkaBrokers})
	modPolicy := configtx.DefaultModificationPolicyID

	configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, kbs.chainID, epoch)
	configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Orderer, lastModified, modPolicy, configItemKey, configItemValue)
	return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil}
}
Exemplo n.º 3
0
func (cbs *commonBootstrapper) encodeAcceptAllPolicy() *cb.SignedConfigurationItem {
	configItemKey := AcceptAllPolicyKey
	configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.AcceptAllPolicy))
	modPolicy := configtx.DefaultModificationPolicyID

	configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch)
	configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue)
	return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil}
}
Exemplo n.º 4
0
func (cbs *commonBootstrapper) lockDefaultModificationPolicy() *cb.SignedConfigurationItem {
	// Lock down the default modification policy to prevent any further policy modifications
	configItemKey := configtx.DefaultModificationPolicyID
	configItemValue := utils.MarshalOrPanic(utils.MakePolicyOrPanic(cauthdsl.RejectAllPolicy))
	modPolicy := configtx.DefaultModificationPolicyID

	configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch)
	configItem := utils.MakeConfigurationItem(configItemChainHeader, cb.ConfigurationItem_Policy, lastModified, modPolicy, configItemKey, configItemValue)
	return &cb.SignedConfigurationItem{ConfigurationItem: utils.MarshalOrPanic(configItem), Signatures: nil}
}
Exemplo n.º 5
0
// Enqueue accepts a message and returns true on acceptance, or false on shutdown.
// Implements the multichain.Chain interface. Called by the drainQueue goroutine,
// which is spawned when the broadcast handler's Handle() function is invoked.
func (ch *chainImpl) Enqueue(env *cb.Envelope) bool {
	if ch.halted {
		return false
	}

	logger.Debug("Enqueueing:", env)
	if err := ch.producer.Send(ch.partition, utils.MarshalOrPanic(newRegularMessage(utils.MarshalOrPanic(env)))); err != nil {
		logger.Errorf("Couldn't post to %s: %s", ch.partition, err)
		return false
	}

	return !ch.halted // If ch.halted has been set to true while sending, we should return false
}
Exemplo n.º 6
0
func makeConfigMessage(chainID string) *cb.Envelope {
	payload := &cb.Payload{
		Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{}),
		Header: &cb.Header{
			ChainHeader: &cb.ChainHeader{
				ChainID: chainID,
				Type:    int32(cb.HeaderType_CONFIGURATION_TRANSACTION),
			},
		},
	}
	return &cb.Envelope{
		Payload: utils.MarshalOrPanic(payload),
	}
}
Exemplo n.º 7
0
func TestConsensusType(t *testing.T) {
	endType := "foo"
	invalidMessage :=
		&cb.ConfigurationItem{
			Type:  cb.ConfigurationItem_Orderer,
			Key:   ConsensusTypeKey,
			Value: []byte("Garbage Data"),
		}
	validMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   ConsensusTypeKey,
		Value: utils.MarshalOrPanic(&ab.ConsensusType{Type: endType}),
	}
	otherValidMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   ConsensusTypeKey,
		Value: utils.MarshalOrPanic(&ab.ConsensusType{Type: "bar"}),
	}
	m := NewManagerImpl()
	m.BeginConfig()

	err := m.ProposeConfig(validMessage)
	if err != nil {
		t.Fatalf("Error applying valid config: %s", err)
	}

	m.CommitConfig()
	m.BeginConfig()

	err = m.ProposeConfig(invalidMessage)
	if err == nil {
		t.Fatalf("Should have failed on invalid message")
	}

	err = m.ProposeConfig(validMessage)
	if err != nil {
		t.Fatalf("Error re-applying valid config: %s", err)
	}

	err = m.ProposeConfig(otherValidMessage)
	if err == nil {
		t.Fatalf("Should not have applied config with different consensus type after it was initially set")
	}

	m.CommitConfig()

	if nowType := m.ConsensusType(); nowType != endType {
		t.Fatalf("Consensus type should have ended as %s but was %s", endType, nowType)
	}
}
Exemplo n.º 8
0
func TestGoodProposal(t *testing.T) {
	newChainID := "NewChainID"

	mcc := newMockChainCreator()
	mcc.ms.msc.chainCreators = []string{provisional.AcceptAllPolicyKey}
	mcc.ms.mpm.mp = &mockPolicy{}

	chainCreateTx := &cb.ConfigurationItem{
		Header: &cb.ChainHeader{
			ChainID: newChainID,
			Type:    int32(cb.HeaderType_CONFIGURATION_ITEM),
		},
		Key:  utils.CreationPolicyKey,
		Type: cb.ConfigurationItem_Orderer,
		Value: utils.MarshalOrPanic(&ab.CreationPolicy{
			Policy: provisional.AcceptAllPolicyKey,
			Digest: coreutil.ComputeCryptoHash([]byte{}),
		}),
	}
	ingressTx := makeConfigTxWithItems(newChainID, chainCreateTx)
	status := mcc.sysChain.proposeChain(ingressTx)
	if status != cb.Status_SUCCESS {
		t.Fatalf("Should have successfully proposed chain")
	}

	expected := 1
	if len(mcc.ms.queue) != expected {
		t.Fatalf("Expected %d creation txs in the chain, but found %d", expected, len(mcc.ms.queue))
	}

	wrapped := mcc.ms.queue[0]
	payload := utils.UnmarshalPayloadOrPanic(wrapped.Payload)
	if payload.Header.ChainHeader.Type != int32(cb.HeaderType_ORDERER_TRANSACTION) {
		t.Fatalf("Wrapped transaction should be of type ORDERER_TRANSACTION")
	}
	envelope := utils.UnmarshalEnvelopeOrPanic(payload.Data)
	if !reflect.DeepEqual(envelope, ingressTx) {
		t.Fatalf("Received different configtx than ingressed into the system")
	}

	sysFilter := newSystemChainFilter(mcc)
	action, committer := sysFilter.Apply(wrapped)

	if action != filter.Accept {
		t.Fatalf("Should have accepted the transaction, as it was already validated")
	}

	if !committer.Isolated() {
		t.Fatalf("Chain creation transactions should be isolated on commit")
	}

	committer.Commit()
	if len(mcc.newChains) != 1 {
		t.Fatalf("Proposal should only have created 1 new chain")
	}

	if !reflect.DeepEqual(mcc.newChains[0], ingressTx) {
		t.Fatalf("New chain should have been created with ingressTx")
	}
}
Exemplo n.º 9
0
// Start allocates the necessary resources for staying up to date with this Chain.
// Implements the multichain.Chain interface. Called by multichain.NewManagerImpl()
// which is invoked when the ordering process is launched, before the call to NewServer().
func (ch *chainImpl) Start() {
	// 1. Post the CONNECT message to prevent panicking that occurs
	// when seeking on a partition that hasn't been created yet.
	logger.Debug("Posting the CONNECT message...")
	if err := ch.producer.Send(ch.partition, utils.MarshalOrPanic(newConnectMessage())); err != nil {
		logger.Criticalf("Couldn't post CONNECT message to %s: %s", ch.partition, err)
		close(ch.exitChan)
		ch.halted = true
		return
	}

	// 2. Set up the listener/consumer for this partition.
	// TODO When restart support gets added to the common components level, start
	// the consumer from lastProcessed. For now, hard-code to oldest available.
	consumer, err := ch.consenter.consFunc()(ch.support.SharedConfig().KafkaBrokers(), ch.consenter.kafkaVersion(), ch.partition, ch.lastProcessed+1)
	if err != nil {
		logger.Criticalf("Cannot retrieve required offset from Kafka cluster for chain %s: %s", ch.partition, err)
		close(ch.exitChan)
		ch.halted = true
		return
	}
	ch.consumer = consumer

	// 3. Set the loop the keep up to date with the chain.
	go ch.loop()
}
Exemplo n.º 10
0
func testNewConsumerMessage(cp ChainPartition, offset int64, kafkaMessage *ab.KafkaMessage) *sarama.ConsumerMessage {
	return &sarama.ConsumerMessage{
		Value:     sarama.ByteEncoder(utils.MarshalOrPanic(kafkaMessage)),
		Topic:     cp.Topic(),
		Partition: cp.Partition(),
		Offset:    offset,
	}
}
Exemplo n.º 11
0
func (mc *mockConsumerImpl) testFillWithBlocks(offset int64) {
	for i := int64(1); i <= offset; i++ {
		go func() {
			mc.disk <- newRegularMessage(utils.MarshalOrPanic(newTestEnvelope(fmt.Sprintf("consumer fill-in %d", i))))
		}()
		<-mc.Recv()
	}
	return
}
Exemplo n.º 12
0
func mockConfigBlock() []byte {
	var blockBytes []byte
	block, err := utils.MakeConfigurationBlock("mytestchainid")
	if err != nil {
		blockBytes = nil
	} else {
		blockBytes = utils.MarshalOrPanic(block)
	}
	return blockBytes
}
Exemplo n.º 13
0
func (cbs *commonBootstrapper) makeGenesisBlock(configEnvelope *cb.ConfigurationEnvelope) *cb.Block {
	configItemChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_ITEM, msgVersion, cbs.chainID, epoch)
	payloadChainHeader := utils.MakeChainHeader(cb.HeaderType_CONFIGURATION_TRANSACTION, configItemChainHeader.Version, cbs.chainID, epoch)
	payloadSignatureHeader := utils.MakeSignatureHeader(nil, utils.CreateNonceOrPanic())
	payloadHeader := utils.MakePayloadHeader(payloadChainHeader, payloadSignatureHeader)
	payload := &cb.Payload{Header: payloadHeader, Data: utils.MarshalOrPanic(configEnvelope)}
	envelope := &cb.Envelope{Payload: utils.MarshalOrPanic(payload), Signature: nil}

	blockData := &cb.BlockData{Data: [][]byte{utils.MarshalOrPanic(envelope)}}

	return &cb.Block{
		Header: &cb.BlockHeader{
			Number:       0,
			PreviousHash: nil,
			DataHash:     blockData.Hash(),
		},
		Data:     blockData,
		Metadata: nil,
	}
}
Exemplo n.º 14
0
func TestBatchSize(t *testing.T) {
	endBatchSize := uint32(10)
	invalidMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   BatchSizeKey,
		Value: []byte("Garbage Data"),
	}
	zeroBatchSize := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   BatchSizeKey,
		Value: utils.MarshalOrPanic(&ab.BatchSize{Messages: 0}),
	}
	validMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   BatchSizeKey,
		Value: utils.MarshalOrPanic(&ab.BatchSize{Messages: endBatchSize}),
	}
	m := NewManagerImpl()
	m.BeginConfig()

	err := m.ProposeConfig(validMessage)
	if err != nil {
		t.Fatalf("Error applying valid config: %s", err)
	}

	err = m.ProposeConfig(invalidMessage)
	if err == nil {
		t.Fatalf("Should have failed on invalid message")
	}

	err = m.ProposeConfig(zeroBatchSize)
	if err == nil {
		t.Fatalf("Should have rejected batch size of 0")
	}

	m.CommitConfig()

	if nowBatchSize := m.BatchSize(); nowBatchSize != endBatchSize {
		t.Fatalf("Got batch size of %d when expecting batch size of %d", nowBatchSize, endBatchSize)
	}
}
Exemplo n.º 15
0
func makeMessage(chainID string, data []byte) *cb.Envelope {
	payload := &cb.Payload{
		Data: data,
		Header: &cb.Header{
			ChainHeader: &cb.ChainHeader{
				ChainID: chainID,
			},
		},
	}
	return &cb.Envelope{
		Payload: utils.MarshalOrPanic(payload),
	}
}
Exemplo n.º 16
0
func TestProducerSend(t *testing.T) {
	cp := newChainPartition(provisional.TestChainID, rawPartition)
	mp := mockNewProducer(t, cp, testMiddleOffset, make(chan *ab.KafkaMessage))
	defer testClose(t, mp)

	go func() {
		<-mp.(*mockProducerImpl).disk // Retrieve the message that we'll be sending below
	}()

	if err := mp.Send(cp, utils.MarshalOrPanic(newRegularMessage([]byte("foo")))); err != nil {
		t.Fatalf("Mock producer was not initialized correctly: %s", err)
	}
}
Exemplo n.º 17
0
func makeConfigTxWithItems(chainID string, items ...*cb.ConfigurationItem) *cb.Envelope {
	signedItems := make([]*cb.SignedConfigurationItem, len(items))
	for i, item := range items {
		signedItems[i] = &cb.SignedConfigurationItem{
			ConfigurationItem: utils.MarshalOrPanic(item),
		}
	}

	payload := &cb.Payload{
		Header: &cb.Header{
			ChainHeader: &cb.ChainHeader{
				Type:    int32(cb.HeaderType_CONFIGURATION_TRANSACTION),
				ChainID: chainID,
			},
		},
		Data: utils.MarshalOrPanic(&cb.ConfigurationEnvelope{
			Items: signedItems,
		}),
	}
	return &cb.Envelope{
		Payload: utils.MarshalOrPanic(payload),
	}
}
Exemplo n.º 18
0
// TODO move to util
func makeNormalTx(chainID string, i int) *cb.Envelope {
	payload := &cb.Payload{
		Header: &cb.Header{
			ChainHeader: &cb.ChainHeader{
				Type:    int32(cb.HeaderType_ENDORSER_TRANSACTION),
				ChainID: chainID,
			},
		},
		Data: []byte(fmt.Sprintf("%d", i)),
	}
	return &cb.Envelope{
		Payload: utils.MarshalOrPanic(payload),
	}
}
Exemplo n.º 19
0
func (mp *mockProducerImpl) testFillWithBlocks(cp ChainPartition, offset int64) {
	dieChan := make(chan struct{})
	deadChan := make(chan struct{})

	go func() { // This goroutine is meant to read only the "fill-in" blocks
		for {
			select {
			case <-mp.disk:
			case <-dieChan:
				close(deadChan)
				return
			}
		}
	}()

	for i := int64(1); i <= offset; i++ {
		mp.Send(cp, utils.MarshalOrPanic(newRegularMessage(utils.MarshalOrPanic(newTestEnvelope(fmt.Sprintf("producer fill-in %d", i))))))
	}

	close(dieChan)
	<-deadChan

	return
}
Exemplo n.º 20
0
func TestProposalWithMissingPolicy(t *testing.T) {
	newChainID := "NewChainID"

	mcc := newMockChainCreator()
	mcc.ms.msc.chainCreators = []string{provisional.AcceptAllPolicyKey}

	chainCreateTx := &cb.ConfigurationItem{
		Key:  utils.CreationPolicyKey,
		Type: cb.ConfigurationItem_Orderer,
		Value: utils.MarshalOrPanic(&ab.CreationPolicy{
			Policy: provisional.AcceptAllPolicyKey,
			Digest: coreutil.ComputeCryptoHash([]byte{}),
		}),
	}
	ingressTx := makeConfigTxWithItems(newChainID, chainCreateTx)

	status := mcc.sysChain.proposeChain(ingressTx)

	if status == cb.Status_SUCCESS {
		t.Fatalf("Should not have validated the transaction with missing policy")
	}
}
Exemplo n.º 21
0
func TestKafkaBrokers(t *testing.T) {
	endList := []string{"127.0.0.1:9092", "foo.bar:9092"}

	invalidMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   KafkaBrokersKey,
		Value: []byte("Garbage Data"),
	}

	zeroBrokers := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   KafkaBrokersKey,
		Value: utils.MarshalOrPanic(&ab.KafkaBrokers{}),
	}

	badList := []string{"127.0.0.1", "foo.bar", "127.0.0.1:-1", "localhost:65536", "foo.bar.:9092", ".127.0.0.1:9092", "-foo.bar:9092"}
	badMessages := []*cb.ConfigurationItem{}
	for _, badAddress := range badList {
		msg := &cb.ConfigurationItem{
			Type:  cb.ConfigurationItem_Orderer,
			Key:   KafkaBrokersKey,
			Value: utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: []string{badAddress}}),
		}
		badMessages = append(badMessages, msg)
	}

	validMessage := &cb.ConfigurationItem{
		Type:  cb.ConfigurationItem_Orderer,
		Key:   KafkaBrokersKey,
		Value: utils.MarshalOrPanic(&ab.KafkaBrokers{Brokers: endList}),
	}

	m := NewManagerImpl()
	m.BeginConfig()

	err := m.ProposeConfig(validMessage)
	if err != nil {
		t.Fatalf("Error applying valid config: %s", err)
	}

	err = m.ProposeConfig(invalidMessage)
	if err == nil {
		t.Fatalf("Should have failed on invalid message")
	}

	err = m.ProposeConfig(zeroBrokers)
	if err == nil {
		t.Fatalf("Should have rejected empty brokers list")
	}

	for i := range badMessages {
		err = m.ProposeConfig(badMessages[i])
		if err == nil {
			t.Fatalf("Should have rejected broker address which is obviously malformed")
		}
	}

	m.CommitConfig()

	nowList := m.KafkaBrokers()
	switch {
	case len(nowList) != len(endList), nowList[0] != endList[0]:
		t.Fatalf("Got brokers list %s when expecting brokers list %s", nowList, endList)
	default:
		return
	}
}