OrbitsNetwork

2019.07 Monthly Report (OrbitsNetwork)

Index

  1. The role and operation of Super Node in Network Layer

  2. The analysis and application of HyperLedger Fabric

The role and operation of Super Node in Network Layer

2019 Q3

  • Planet Wallet Launching

  • Network Layer Development

As GBT Protocol Roadmap, we are processing to develop Network Layer within 2019 Q3. We analyze pros and cons of the role and operation of Super Node via original projects.

In Orbits Network, Super Nodes store all distributed ledgers and select well-meaning Micro nodes based on their accumulated reliabilities to make an efficient process of verification possible.

1. Offering storage spaces for source files

  • Super nodes provide the storage spaces for Dapp source files. The source files are stored as off-chain.

  • The files which are stored by each super node will be selected by chosen super nodes. There will be no problems of selection as the rewards will be given in proportion to the unit of storage spaces.

2. Offering source files to Micro Nodes

  • Super node provides their own source files whenever micro nodes require.

3. Production of Micro node Authorization pool

  • Super nodes periodically select nodes which will clarify the transactions from Micro nodes.

  • Super nodes spread selected authorization pool after they align the transactions from Micro nodes.

  • Selected super nodes inspect the state of Micro nodes' on/off-line for the generation of authorization pools.

The analysis and application of HyperLedger Fabric

In HyperLedger Fabric, it is possible to divide the whole process into every phases from the generation of transactions to the consensus and perform each phases sequently.

In the first 'execution' step, the main duties are the conduction of transactions and the verification of result values from them.

In the second 'order' step, the main duties are the alignment of all transactions which are verified at previous step and the generation of blocks.

In the final 'validation' step, the main duties are the verifications of all result values from transactions in blocks and the update of latest block after final check of all digital certificates.

This process that each steps are functioned separately could reduce the burden of the nodes which conduct and verify transactions and the nodes which align transactions, also it could reinforce the capacity of the system as it allows parallel processing which could perform more than two works simultaneously.

HyperLedger Fabric supports modular designs to allow participants to operate blockchain technology when they build system by choosing whatever they desire in terms of functions like authorization, consensus algorithm, and cryptography.

1. Endorsement Policy

Endorsement Policy works between peers and the clients who generate transactions. To input new transactions into blocks, it requires a permission from selected peers at an endorsement policy. If a transaction could not reach the requirement, that transaction will be excluded when a peer verifies a block.

The transaction will be recored in a block with invalid tag, it will never affect the future transactions.

Let's take an example to see how to set an endorsement policy. First of all, we assume that there are 7 peers in a system.

Endorsement group = {peer1, peer2, peer3, peer4, peer5, peer6, peer7}

In this case, we could set the endorsement policy like below.

  • All peers in the endorsement group should acquire digital certificates.

  • They should also acquire digital certificates from other peers in same endorsement group.

  • {peer1 OR peer2} AND {any two of peer5, peer6, peer7}

Also we could set the endorsement policy with different weights between peers in the endorsement group.

Endorsement group = {peer1 = 15, peer2 = 10, peer3 = 25, peer4 = 20, peer5 = 10, peer6 = 10, peer7 = 10}

  • All peers should acquire digital certificates from the combinations of peers whose total of weight is above 50.

  • {peer1 OR peer3} AND {the total of weight is above 40}

The blockchain participants of HyperLedger Fabric could enhance the security and the reliability of business via an endorsement policy in diverse settings.

package endorsement
import (
"fmt"
"testing"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/common/chaincode"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/common/policies/inquire"
"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/common"
"github.com/hyperledger/fabric/gossip/discovery"
discoveryprotos "github.com/hyperledger/fabric/protos/discovery"
"github.com/hyperledger/fabric/protos/gossip"
"github.com/hyperledger/fabric/protos/msp"
"github.com/hyperledger/fabric/protos/utils"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var pkiID2MSPID = map[string]string{
"p0": "Org0MSP",
"p1": "Org1MSP",
"p2": "Org2MSP",
"p3": "Org3MSP",
"p4": "Org4MSP",
"p5": "Org5MSP",
"p6": "Org6MSP",
"p7": "Org7MSP",
"p8": "Org8MSP",
"p9": "Org9MSP",
"p10": "Org10MSP",
"p11": "Org11MSP",
"p12": "Org12MSP",
"p13": "Org13MSP",
"p14": "Org14MSP",
"p15": "Org15MSP",
}
... 중략 ...
func TestPeersAuthorizedByCriteria(t *testing.T) {
cc1 := "cc1"
cc2 := "cc2"
members := peerSet{
newPeer(0).withChaincode(cc1, "1.0"),
newPeer(3).withChaincode(cc1, "1.0"),
newPeer(6).withChaincode(cc1, "1.0"),
newPeer(9).withChaincode(cc1, "1.0"),
newPeer(12).withChaincode(cc1, "1.0"),
}.toMembers()
members2 := append(discovery.Members{}, members...)
members2 = append(members2, peerSet{newPeer(13).withChaincode(cc1, "1.1").withChaincode(cc2, "1.0")}.toMembers()...)
members2 = append(members2, peerSet{newPeer(14).withChaincode(cc1, "1.1")}.toMembers()...)
members2 = append(members2, peerSet{newPeer(15).withChaincode(cc2, "1.0")}.toMembers()...)
alivePeers := peerSet{
newPeer(0),
newPeer(2),
newPeer(4),
newPeer(6),
newPeer(8),
newPeer(10),
newPeer(11),
newPeer(12),
newPeer(13),
newPeer(14),
newPeer(15),
}.toMembers()
identities := identitySet(pkiID2MSPID)
for _, tst := range []struct {
name string
arguments *discoveryprotos.ChaincodeInterest
totalExistingMembers discovery.Members
metadata []*chaincode.Metadata
expected discovery.Members
}{
{
name: "Nil interest",
arguments: nil,
totalExistingMembers: members,
expected: members,
},
{
name: "Empty interest invocation chain",
arguments: &discoveryprotos.ChaincodeInterest{},
totalExistingMembers: members,
expected: members,
},
{
name: "Chaincodes only installed on some peers",
arguments: &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{
{Name: cc1}, {Name: cc2},
},
},
totalExistingMembers: members2,
metadata: []*chaincode.Metadata{{
Name: "cc1", Version: "1.1",
}, {
Name: "cc2", Version: "1.0",
}},
expected: peerSet{newPeer(13).withChaincode(cc1, "1.1").withChaincode(cc2, "1.0")}.toMembers(),
},
{
name: "Only some peers authorized by collection",
arguments: &discoveryprotos.ChaincodeInterest{
Chaincodes: []*discoveryprotos.ChaincodeCall{
{Name: cc1, CollectionNames: []string{"collection"}},
},
},
totalExistingMembers: members,
metadata: []*chaincode.Metadata{{
Name: cc1, Version: "1.0",
CollectionsConfig: buildCollectionConfig(map[string][]*msp.MSPPrincipal{
"collection": {
peerRole("p0"),
peerRole("p12"),
},
}),
}},
expected: peerSet{
newPeer(0).withChaincode(cc1, "1.0"),
newPeer(12).withChaincode(cc1, "1.0")}.toMembers(),
},
} {
t.Run(tst.name, func(t *testing.T) {
g := &gossipMock{}
pf := &policyFetcherMock{}
mf := &metadataFetcher{}
g.On("Peers").Return(alivePeers)
g.On("IdentityInfo").Return(identities)
g.On("PeersOfChannel").Return(tst.totalExistingMembers).Once()
for _, md := range tst.metadata {
mf.On("Metadata").Return(md).Once()
}
analyzer := NewEndorsementAnalyzer(g, pf, &principalEvaluatorMock{}, mf)
actualMembers, err := analyzer.PeersAuthorizedByCriteria(common.ChainID("mychannel"), tst.arguments)
assert.NoError(t, err)
assert.Equal(t, tst.expected, actualMembers)
})
}
}

Reference and application of weight algorithm based on reliability.

2. Channel

The communications between peers only happen through channels. All organizations can share information via channels or some organizations whose business interests are matched could create an extra channel and share information via that channel. Compare to public blockchain which has accessible distributed ledgers to every blockchain participants like Ethereum, in hyper-ledger fabric, on the other hand, each channels has their own sole distributed ledger in which only participants from a specific channel could reach the distributed ledger of that channel. In other words, it could provide the confidentiality of data which was not possible in original public blockchains.

// InitCmdFactory init the ChannelCmdFactory with clients to endorser and orderer according to params
func InitCmdFactory(isEndorserRequired, isPeerDeliverRequired, isOrdererRequired bool) (*ChannelCmdFactory, error) {
if isPeerDeliverRequired && isOrdererRequired {
// this is likely a bug during development caused by adding a new cmd
return nil, errors.New("ERROR - only a single deliver source is currently supported")
}
var err error
cf := &ChannelCmdFactory{}
cf.Signer, err = common.GetDefaultSignerFnc()
if err != nil {
return nil, errors.WithMessage(err, "error getting default signer")
}
cf.BroadcastFactory = func() (common.BroadcastClient, error) {
return common.GetBroadcastClientFnc()
}
// for join and list, we need the endorser as well
if isEndorserRequired {
// creating an EndorserClient with these empty parameters will create a
// connection using the values of "peer.address" and
// "peer.tls.rootcert.file"
cf.EndorserClient, err = common.GetEndorserClientFnc(common.UndefinedParamValue, common.UndefinedParamValue)
if err != nil {
return nil, errors.WithMessage(err, "error getting endorser client for channel")
}
}
// for fetching blocks from a peer
if isPeerDeliverRequired {
cf.DeliverClient, err = common.NewDeliverClientForPeer(channelID, bestEffort)
if err != nil {
return nil, errors.WithMessage(err, "error getting deliver client for channel")
}
}
// for create and fetch, we need the orderer as well
if isOrdererRequired {
if len(strings.Split(common.OrderingEndpoint, ":")) != 2 {
return nil, errors.Errorf("ordering service endpoint %s is not valid or missing", common.OrderingEndpoint)
}
cf.DeliverClient, err = common.NewDeliverClientForOrderer(channelID, bestEffort)
if err != nil {
return nil, err
}
}
logger.Infof("Endorser and orderer connections initialized")
return cf, nil
}

Reference the resolution of the problem which was caused by continuously growing storage of UTXO information in smartphone.

3. Gossip

  • Peers constantly generate broadcast messages to validate other node's states which are in the same channel. What if a peer can not respond to the broadcast messages within specific period of time? Then the peer is considered as having problems and it will be recognized as off-line in network.

  • Peers choose other peers in same channel randomly and send distributed ledgers to them via Gossip Protocol. Peers who get distributed ledgers via Gossip protocol contrast their own ledger with new one and if there is any update information, they also upload the new part. Peers from each organization can get update distributed ledger via an orderer. If every peer from each organizations will ask an orderer a distributed ledger each time, the orderer will be likely to over-work. Therefore, Peers decide to elect a leader peer and communicate with an orderer instead of each peer ask the orderer each time.

package gossip
import (
"fmt"
"time"
"github.com/hyperledger/fabric/gossip/api"
"github.com/hyperledger/fabric/gossip/comm"
"github.com/hyperledger/fabric/gossip/common"
"github.com/hyperledger/fabric/gossip/discovery"
"github.com/hyperledger/fabric/gossip/filter"
proto "github.com/hyperledger/fabric/protos/gossip"
)
// Gossip is the interface of the gossip component
type Gossip interface {
// SelfMembershipInfo returns the peer's membership information
SelfMembershipInfo() discovery.NetworkMember
// SelfChannelInfo returns the peer's latest StateInfo message of a given channel
SelfChannelInfo(common.ChainID) *proto.SignedGossipMessage
// Send sends a message to remote peers
Send(msg *proto.GossipMessage, peers ...*comm.RemotePeer)
// SendByCriteria sends a given message to all peers that match the given SendCriteria
SendByCriteria(*proto.SignedGossipMessage, SendCriteria) error
// GetPeers returns the NetworkMembers considered alive
Peers() []discovery.NetworkMember
// PeersOfChannel returns the NetworkMembers considered alive
// and also subscribed to the channel given
PeersOfChannel(common.ChainID) []discovery.NetworkMember
// UpdateMetadata updates the self metadata of the discovery layer
// the peer publishes to other peers
UpdateMetadata(metadata []byte)
// UpdateLedgerHeight updates the ledger height the peer
// publishes to other peers in the channel
UpdateLedgerHeight(height uint64, chainID common.ChainID)
// UpdateChaincodes updates the chaincodes the peer publishes
// to other peers in the channel
UpdateChaincodes(chaincode []*proto.Chaincode, chainID common.ChainID)
// Gossip sends a message to other peers to the network
Gossip(msg *proto.GossipMessage)
// PeerFilter receives a SubChannelSelectionCriteria and returns a RoutingFilter that selects
// only peer identities that match the given criteria, and that they published their channel participation
PeerFilter(channel common.ChainID, messagePredicate api.SubChannelSelectionCriteria) (filter.RoutingFilter, error)
// Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate.
// If passThrough is false, the messages are processed by the gossip layer beforehand.
// If passThrough is true, the gossip layer doesn't intervene and the messages
// can be used to send a reply back to the sender
Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage)
// JoinChan makes the Gossip instance join a channel
JoinChan(joinMsg api.JoinChannelMessage, chainID common.ChainID)
// LeaveChan makes the Gossip instance leave a channel.
// It still disseminates stateInfo message, but doesn't participate
// in block pulling anymore, and can't return anymore a list of peers
// in the channel.
LeaveChan(chainID common.ChainID)
// SuspectPeers makes the gossip instance validate identities of suspected peers, and close
// any connections to peers with identities that are found invalid
SuspectPeers(s api.PeerSuspector)
// IdentityInfo returns information known peer identities
IdentityInfo() api.PeerIdentitySet
// Stop stops the gossip component
Stop()
}
... 생략 ...

Reference and application of protocol at network layer

Reference

  1. 하이퍼레저 패브릭으로 배우는 블록체인 / ETRI 블록체인기술연구센터 윤대근/ 제이펍