Skip to content

Commit

Permalink
[FAB-3059] SDK Go - Initialize chain
Browse files Browse the repository at this point in the history
Change-Id: I15974024d51ec3806a59a7d65f86e1405b724faa
Signed-off-by: Bob Stasyszyn <[email protected]>
  • Loading branch information
bstasyszyn committed Apr 10, 2017
1 parent 65db7ec commit b63b116
Show file tree
Hide file tree
Showing 59 changed files with 9,596 additions and 20 deletions.
570 changes: 570 additions & 0 deletions fabric-client/chain.go

Large diffs are not rendered by default.

30 changes: 27 additions & 3 deletions fabric-client/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func TestCreateChain(t *testing.T) {
t.Fatalf(err.Error())
}
// Setup mock orderer
orderer := mockOrderer{fmt.Sprintf("0.0.0.0:1234"), nil}
orderer := mockOrderer{MockURL: fmt.Sprintf("0.0.0.0:1234")}
chain.AddOrderer(&orderer)
// Test with valid cofiguration
err = chain.CreateChannel(&CreateChannelRequest{ConfigData: configTx})
Expand Down Expand Up @@ -250,7 +250,7 @@ func TestJoinChannel(t *testing.T) {
chain, _ := setupTestChain()
peer, _ := CreateNewPeer(testAddress, "", "")
peers = append(peers, peer)
orderer := &mockOrderer{}
orderer := &mockOrderer{DeliverResponse: NewMockDeliverResponse(mocks.NewSimpleMockBlock())}
nonce, _ := util.GenerateRandomNonce()
txID, _ := util.ComputeTxID(nonce, []byte("testID"))
request := &JoinChannelRequest{Targets: peers, Nonce: nonce, TxID: txID}
Expand Down Expand Up @@ -293,6 +293,30 @@ func TestJoinChannel(t *testing.T) {
}
}

func TestChainInitializeFromOrderer(t *testing.T) {
chain, _ := setupTestChain()
builder := &mocks.MockConfigBlockBuilder{Index: 0, LastConfigIndex: 0}
orderer := &mockOrderer{DeliverResponse: NewMockDeliverResponse(builder.Build())}
chain.AddOrderer(orderer)

err := chain.Initialize([]byte{})
if err != nil {
t.Fatalf("channel Initialize failed : %v", err)
}
// TODO: Check data in chain
}

func TestChainInitializeFromUpdate(t *testing.T) {
chain, _ := setupTestChain()
builder := &mocks.MockConfigUpdateEnvelopeBuilder{}

err := chain.Initialize(builder.BuildBytes())
if err != nil {
t.Fatalf("channel Initialize failed : %v", err)
}
// TODO: Check data in chain
}

func setupTestChain() (Chain, error) {
client := NewClient()
user := NewUser("test")
Expand All @@ -314,7 +338,7 @@ func setupMassiveTestChain(numberOfPeers int, numberOfOrderers int) (Chain, erro
}

for i := 0; i < numberOfOrderers; i++ {
orderer := mockOrderer{fmt.Sprintf("http://mock%d.orderers.r.us", i), nil}
orderer := mockOrderer{MockURL: fmt.Sprintf("http://mock%d.orderers.r.us", i)}
chain.AddOrderer(&orderer)
}

Expand Down
25 changes: 11 additions & 14 deletions fabric-client/mockorderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,11 @@ import (
ab "github.com/hyperledger/fabric/protos/orderer"
)

// TestBlock is a test block
var testBlock = &ab.DeliverResponse{
Type: &ab.DeliverResponse_Block{
Block: &common.Block{
Data: &common.BlockData{
Data: [][]byte{[]byte("test")},
},
},
},
}

// mockOrderer is a mock fabricclient.Orderer
type mockOrderer struct {
MockURL string
MockError error
MockURL string
MockError error
DeliverResponse *ab.DeliverResponse
}

// GetURL returns the mock URL of the mock Orderer
Expand All @@ -56,6 +46,13 @@ func (o *mockOrderer) SendDeliver(envelope *SignedEnvelope) (chan *common.Block,
chan error) {
responses := make(chan *common.Block, 1)
errors := make(chan error, 1)
responses <- testBlock.GetBlock()
responses <- o.DeliverResponse.GetBlock()
return responses, errors
}

// NewMockDeliverResponse returns a mock DeliverResponse with the given block
func NewMockDeliverResponse(block *common.Block) *ab.DeliverResponse {
return &ab.DeliverResponse{
Type: &ab.DeliverResponse_Block{Block: block},
}
}
134 changes: 134 additions & 0 deletions fabric-client/mocks/mockdata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package mocks

import (
"github.com/hyperledger/fabric-sdk-go/fabric-client/util"
"github.com/hyperledger/fabric/protos/common"
)

// NewSimpleMockBlock returns a simple mock block
func NewSimpleMockBlock() *common.Block {
return &common.Block{
Data: &common.BlockData{
Data: [][]byte{[]byte("test")},
},
}
}

// MockConfigBlockBuilder is used to build a mock Chain configuration block builder
type MockConfigBlockBuilder struct {
Index uint64
LastConfigIndex uint64
}

// Build will create a mock Chain configuration block
func (b *MockConfigBlockBuilder) Build() *common.Block {
return &common.Block{
Header: &common.BlockHeader{
Number: b.Index,
},
Metadata: &common.BlockMetadata{
Metadata: b.buildMetaDataBytes(),
},
Data: &common.BlockData{
Data: b.buildBlockEnvelopeBytes(),
},
}
}

func (b *MockConfigBlockBuilder) buildMetaDataBytes() [][]byte {
return [][]byte{b.buildSignaturesMetaDataBytes(), b.buildLastConfigMetaDataBytes()}
}

func (b *MockConfigBlockBuilder) buildSignaturesMetaDataBytes() []byte {
return []byte("test signatures")
}

func (b *MockConfigBlockBuilder) buildLastConfigMetaDataBytes() []byte {
return util.MarshalOrPanic(&common.Metadata{Value: b.buildLastConfigBytes()})
}

func (b *MockConfigBlockBuilder) buildLastConfigBytes() []byte {
return util.MarshalOrPanic(&common.LastConfig{Index: b.LastConfigIndex})
}

func (b *MockConfigBlockBuilder) buildBlockEnvelopeBytes() [][]byte {
return [][]byte{b.buildEnvelopeBytes()}
}

func (b *MockConfigBlockBuilder) buildEnvelopeBytes() []byte {
return util.MarshalOrPanic(&common.Envelope{Payload: b.buildPayloadBytes()})
}

func (b *MockConfigBlockBuilder) buildPayloadBytes() []byte {
return util.MarshalOrPanic(&common.Payload{Header: b.buildHeader(), Data: b.buildConfigEnvelopeBytes()})
}

func (b *MockConfigBlockBuilder) buildHeader() *common.Header {
return &common.Header{ChannelHeader: b.buildChannelHeaderBytes()}
}

func (b *MockConfigBlockBuilder) buildChannelHeaderBytes() []byte {
return util.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_CONFIG)})
}

func (b *MockConfigBlockBuilder) buildConfigEnvelopeBytes() []byte {
return util.MarshalOrPanic(&common.ConfigEnvelope{Config: b.buildConfig()})
}

func (b *MockConfigBlockBuilder) buildConfig() *common.Config {
return &common.Config{Sequence: 0, ChannelGroup: b.buildConfigGroup()}
}

func (b *MockConfigBlockBuilder) buildConfigGroup() *common.ConfigGroup {
return &common.ConfigGroup{}
}

type MockConfigUpdateEnvelopeBuilder struct {
}

func (b *MockConfigUpdateEnvelopeBuilder) BuildBytes() []byte {
return util.MarshalOrPanic(&common.Envelope{Payload: b.buildPayloadBytes()})
}

func (b *MockConfigUpdateEnvelopeBuilder) buildPayloadBytes() []byte {
return util.MarshalOrPanic(&common.Payload{Header: b.buildHeader(), Data: b.buildConfigEnvelopeBytes()})
}

func (b *MockConfigUpdateEnvelopeBuilder) buildHeader() *common.Header {
return &common.Header{ChannelHeader: b.buildChannelHeaderBytes()}
}

func (b *MockConfigUpdateEnvelopeBuilder) buildChannelHeaderBytes() []byte {
return util.MarshalOrPanic(&common.ChannelHeader{Type: int32(common.HeaderType_CONFIG_UPDATE)})
}

func (b *MockConfigUpdateEnvelopeBuilder) buildConfigEnvelopeBytes() []byte {
return util.MarshalOrPanic(&common.ConfigEnvelope{Config: b.buildConfig()})
}

func (b *MockConfigUpdateEnvelopeBuilder) buildConfig() *common.Config {
return &common.Config{Sequence: 0, ChannelGroup: b.buildConfigGroup()}
}

func (b *MockConfigUpdateEnvelopeBuilder) buildConfigGroup() *common.ConfigGroup {
return &common.ConfigGroup{}
}
45 changes: 45 additions & 0 deletions fabric-client/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,14 @@ limitations under the License.
package util

import (
"fmt"
"time"

"github.com/hyperledger/fabric/core/crypto/primitives"
ab "github.com/hyperledger/fabric/protos/orderer"

"github.com/golang/protobuf/proto"
google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
"github.com/hyperledger/fabric/protos/common"
protos_utils "github.com/hyperledger/fabric/protos/utils"
)
Expand Down Expand Up @@ -64,3 +68,44 @@ func GenerateRandomNonce() ([]byte, error) {
func ComputeTxID(nonce []byte, creatorID []byte) (string, error) {
return protos_utils.ComputeProposalTxID(nonce, creatorID)
}

// NewNewestSeekPosition returns a SeekPosition that requests the newest block
func NewNewestSeekPosition() *ab.SeekPosition {
return &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}
}

// NewSpecificSeekPosition returns a SeekPosition that requests the block at the given index
func NewSpecificSeekPosition(index uint64) *ab.SeekPosition {
return &ab.SeekPosition{Type: &ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: index}}}
}

// GetLastConfigFromBlock returns the LastConfig data from the given block
func GetLastConfigFromBlock(block *common.Block) (*common.LastConfig, error) {
metadata := &common.Metadata{}
err := proto.Unmarshal(block.Metadata.Metadata[common.BlockMetadataIndex_LAST_CONFIG], metadata)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal meta data at index %d: %v", common.BlockMetadataIndex_LAST_CONFIG, err)
}

lastConfig := &common.LastConfig{}
err = proto.Unmarshal(metadata.Value, lastConfig)
if err != nil {
return nil, fmt.Errorf("unable to unmarshal last config from meta data: %v", err)
}

return lastConfig, err
}

// BuildChannelHeader builds a ChannelHeader with the given parameters
func BuildChannelHeader(channelName string, headerType common.HeaderType, txID string, epoch uint64) (*common.ChannelHeader, error) {
now := time.Now()
channelHeader := &common.ChannelHeader{
Type: int32(headerType),
Version: 1,
Timestamp: &google_protobuf.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())},
ChannelId: channelName,
Epoch: epoch,
TxId: txID,
}
return channelHeader, nil
}
8 changes: 8 additions & 0 deletions vendor/github.com/Knetic/govaluate/CONTRIBUTORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b63b116

Please sign in to comment.