Skip to content

Commit 1093492

Browse files
author
Jason Yellick
committed
[FAB-998] Add new-chain sample client
https://jira.hyperledger.org/browse/FAB-998 This changeset introduces a sample client that sends a single envelope via the broadcast RPC to the ordering service. This envelope contains a configuration envelope that calls for the creation of a new chain. The client is invoked as follows: $ broadcast_config -cmd new-chain -chainID newChainID As is the case with the bd_counter sample client, the user can also set the logging level (-loglevel) and the address of the RPC server (-server). The user may also set the backing creation policy (-creationPolicy). This changeset also adds chainID support for the deliver_stdout and the broadcast_timestamp sample clients. Change-Id: I782eb77c45f5c8d91c75c4440e47a20ab76a560e Signed-off-by: Kostas Christidis <[email protected]> Signed-off-by: Jason Yellick <[email protected]>
1 parent 9028424 commit 1093492

File tree

6 files changed

+245
-17
lines changed

6 files changed

+245
-17
lines changed

orderer/sample_clients/bd_counter/main.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"google.golang.org/grpc"
2828
)
2929

30+
const pkgName = "orderer/bd_counter"
31+
3032
var logger *logging.Logger
3133

3234
type configImpl struct {
@@ -49,7 +51,7 @@ func main() {
4951
logging.SetBackend(backend)
5052
formatter := logging.MustStringFormatter("[%{time:15:04:05}] %{shortfile:18s}: %{color}[%{level:-5s}]%{color:reset} %{message}")
5153
logging.SetFormatter(formatter)
52-
logger = logging.MustGetLogger("orderer/bd_counter")
54+
logger = logging.MustGetLogger(pkgName)
5355

5456
flag.StringVar(&client.config.rpc, "rpc", "broadcast",
5557
"The RPC that this client is requesting.")
@@ -78,7 +80,7 @@ func main() {
7880

7981
conn, err := grpc.Dial(client.config.server, grpc.WithInsecure())
8082
if err != nil {
81-
logger.Fatalf("Client did not connect to %s: %v\n", client.config.server, err)
83+
logger.Fatalf("Client did not connect to %s: %v", client.config.server, err)
8284
}
8385
defer conn.Close()
8486
client.rpc = ab.NewAtomicBroadcastClient(conn)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"fmt"
21+
"io"
22+
23+
cb "github.com/hyperledger/fabric/protos/common"
24+
ab "github.com/hyperledger/fabric/protos/orderer"
25+
context "golang.org/x/net/context"
26+
)
27+
28+
func (c *clientImpl) broadcast(envelope *cb.Envelope) {
29+
stream, err := c.rpc.Broadcast(context.Background())
30+
if err != nil {
31+
panic(fmt.Errorf("Failed to invoke broadcast RPC: %s", err))
32+
}
33+
go c.recvBroadcastReplies(stream)
34+
35+
if err := stream.Send(envelope); err != nil {
36+
panic(fmt.Errorf("Failed to send broadcast message to ordering service: %s", err))
37+
}
38+
logger.Debugf("Sent broadcast message \"%v\" to ordering service\n", envelope)
39+
40+
if err := stream.CloseSend(); err != nil {
41+
panic(fmt.Errorf("Failed to close the send direction of the broadcast stream: %v", err))
42+
}
43+
44+
<-c.doneChan // Wait till we've had a chance to get back a reply (or an error)
45+
logger.Info("Client shutting down")
46+
}
47+
48+
func (c *clientImpl) recvBroadcastReplies(stream ab.AtomicBroadcast_BroadcastClient) {
49+
defer close(c.doneChan)
50+
for {
51+
reply, err := stream.Recv()
52+
if err == io.EOF {
53+
return
54+
}
55+
if err != nil {
56+
panic(fmt.Errorf("Failed to receive a broadcast reply from orderer: %v", err))
57+
}
58+
logger.Info("Broadcast reply from orderer:", reply.Status.String())
59+
break
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"flag"
21+
"os"
22+
"strings"
23+
24+
ab "github.com/hyperledger/fabric/protos/orderer"
25+
logging "github.com/op/go-logging"
26+
"google.golang.org/grpc"
27+
)
28+
29+
const pkgName = "orderer/broadcast_config"
30+
31+
var logger *logging.Logger
32+
33+
// Include here all the possible arguments for a command
34+
type argsImpl struct {
35+
creationPolicy string
36+
chainID string
37+
}
38+
39+
// This holds the command and its arguments
40+
type cmdImpl struct {
41+
cmd string
42+
args argsImpl
43+
}
44+
45+
type configImpl struct {
46+
logLevel logging.Level
47+
server string
48+
cmd cmdImpl
49+
}
50+
51+
type clientImpl struct {
52+
config configImpl
53+
rpc ab.AtomicBroadcastClient
54+
doneChan chan struct{}
55+
}
56+
57+
func main() {
58+
var loglevel string
59+
60+
client := &clientImpl{doneChan: make(chan struct{})}
61+
62+
backend := logging.NewLogBackend(os.Stderr, "", 0)
63+
logging.SetBackend(backend)
64+
formatter := logging.MustStringFormatter("[%{time:15:04:05}] %{shortfile:18s}: %{color}[%{level:-5s}]%{color:reset} %{message}")
65+
logging.SetFormatter(formatter)
66+
logger = logging.MustGetLogger(pkgName)
67+
68+
flag.StringVar(&loglevel, "loglevel", "info",
69+
"The logging level. (Suggested values: info, debug)")
70+
flag.StringVar(&client.config.server, "server",
71+
"127.0.0.1:7050", "The RPC server to connect to.")
72+
flag.StringVar(&client.config.cmd.cmd, "cmd", "new-chain",
73+
"The action that this client is requesting via the config transaction.")
74+
flag.StringVar(&client.config.cmd.args.creationPolicy, "creationPolicy", "AcceptAllPolicy",
75+
"In case of a new-chain command, the chain createion policy this request should be validated against.")
76+
flag.StringVar(&client.config.cmd.args.chainID, "chainID", "NewChainID",
77+
"In case of a new-chain command, the chain ID to create.")
78+
flag.Parse()
79+
80+
client.config.logLevel, _ = logging.LogLevel(strings.ToUpper(loglevel))
81+
logging.SetLevel(client.config.logLevel, logger.Module)
82+
83+
conn, err := grpc.Dial(client.config.server, grpc.WithInsecure())
84+
if err != nil {
85+
logger.Fatalf("Client did not connect to %s: %v", client.config.server, err)
86+
}
87+
defer conn.Close()
88+
client.rpc = ab.NewAtomicBroadcastClient(conn)
89+
90+
switch client.config.cmd.cmd {
91+
case "new-chain":
92+
envelope := newChainRequest(client.config.cmd.args.creationPolicy, client.config.cmd.args.chainID)
93+
logger.Infof("Requesting the creation of chain \"%s\"", client.config.cmd.args.chainID)
94+
client.broadcast(envelope)
95+
default:
96+
panic("Invalid cmd given")
97+
}
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"github.com/hyperledger/fabric/orderer/common/bootstrap/static"
21+
cb "github.com/hyperledger/fabric/protos/common"
22+
ab "github.com/hyperledger/fabric/protos/orderer"
23+
"github.com/hyperledger/fabric/protos/utils"
24+
)
25+
26+
var genesisBlock *cb.Block
27+
28+
func init() {
29+
helper := static.New()
30+
var err error
31+
genesisBlock, err = helper.GenesisBlock()
32+
if err != nil {
33+
panic("Error retrieving static genesis block")
34+
}
35+
}
36+
37+
func newChainRequest(creationPolicy, newChainID string) *cb.Envelope {
38+
oldGenesisTx := utils.ExtractEnvelopeOrPanic(genesisBlock, 0)
39+
oldGenesisTxPayload := utils.ExtractPayloadOrPanic(oldGenesisTx)
40+
oldConfigEnv := utils.UnmarshalConfigurationEnvelopeOrPanic(oldGenesisTxPayload.Data)
41+
42+
return ab.ChainCreationConfigurationTransaction(static.AcceptAllPolicyKey, newChainID, oldConfigEnv)
43+
}

orderer/sample_clients/broadcast_timestamp/client.go

+21-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"flag"
2021
"fmt"
2122
"time"
2223

@@ -30,19 +31,20 @@ import (
3031
)
3132

3233
type broadcastClient struct {
33-
client ab.AtomicBroadcast_BroadcastClient
34+
client ab.AtomicBroadcast_BroadcastClient
35+
chainID string
3436
}
3537

3638
// newBroadcastClient creates a simple instance of the broadcastClient interface
37-
func newBroadcastClient(client ab.AtomicBroadcast_BroadcastClient) *broadcastClient {
38-
return &broadcastClient{client: client}
39+
func newBroadcastClient(client ab.AtomicBroadcast_BroadcastClient, chainID string) *broadcastClient {
40+
return &broadcastClient{client: client, chainID: chainID}
3941
}
4042

4143
func (s *broadcastClient) broadcast(transaction []byte) error {
4244
payload, err := proto.Marshal(&cb.Payload{
4345
Header: &cb.Header{
4446
ChainHeader: &cb.ChainHeader{
45-
ChainID: static.TestChainID,
47+
ChainID: s.chainID,
4648
},
4749
},
4850
Data: transaction,
@@ -66,7 +68,16 @@ func (s *broadcastClient) getAck() error {
6668

6769
func main() {
6870
config := config.Load()
69-
serverAddr := fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort)
71+
72+
var chainID string
73+
var serverAddr string
74+
var messages uint64
75+
76+
flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.")
77+
flag.StringVar(&chainID, "chainID", static.TestChainID, "The chain ID to broadcast to.")
78+
flag.Uint64Var(&messages, "messages", 1, "The number of messages to braodcast.")
79+
flag.Parse()
80+
7081
conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
7182
defer conn.Close()
7283
if err != nil {
@@ -79,9 +90,11 @@ func main() {
7990
return
8091
}
8192

82-
s := newBroadcastClient(client)
83-
s.broadcast([]byte(fmt.Sprintf("Testing %v", time.Now())))
84-
err = s.getAck()
93+
s := newBroadcastClient(client, chainID)
94+
for i := uint64(0); i < messages; i++ {
95+
s.broadcast([]byte(fmt.Sprintf("Testing %v", time.Now())))
96+
err = s.getAck()
97+
}
8598
if err != nil {
8699
fmt.Printf("\nError: %v\n", err)
87100
}

orderer/sample_clients/deliver_stdout/client.go

+18-7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package main
1818

1919
import (
20+
"flag"
2021
"fmt"
2122

2223
"github.com/hyperledger/fabric/orderer/common/bootstrap/static"
@@ -29,12 +30,13 @@ import (
2930

3031
type deliverClient struct {
3132
client ab.AtomicBroadcast_DeliverClient
33+
chainID string
3234
windowSize uint64
3335
unAcknowledged uint64
3436
}
3537

36-
func newDeliverClient(client ab.AtomicBroadcast_DeliverClient, windowSize uint64) *deliverClient {
37-
return &deliverClient{client: client, windowSize: windowSize}
38+
func newDeliverClient(client ab.AtomicBroadcast_DeliverClient, chainID string, windowSize uint64) *deliverClient {
39+
return &deliverClient{client: client, chainID: chainID, windowSize: windowSize}
3840
}
3941

4042
func (r *deliverClient) seekOldest() error {
@@ -43,7 +45,7 @@ func (r *deliverClient) seekOldest() error {
4345
Seek: &ab.SeekInfo{
4446
Start: ab.SeekInfo_OLDEST,
4547
WindowSize: r.windowSize,
46-
ChainID: static.TestChainID,
48+
ChainID: r.chainID,
4749
},
4850
},
4951
})
@@ -55,7 +57,7 @@ func (r *deliverClient) seekNewest() error {
5557
Seek: &ab.SeekInfo{
5658
Start: ab.SeekInfo_NEWEST,
5759
WindowSize: r.windowSize,
58-
ChainID: static.TestChainID,
60+
ChainID: r.chainID,
5961
},
6062
},
6163
})
@@ -68,7 +70,7 @@ func (r *deliverClient) seek(blockNumber uint64) error {
6870
Start: ab.SeekInfo_SPECIFIED,
6971
SpecifiedNumber: blockNumber,
7072
WindowSize: r.windowSize,
71-
ChainID: static.TestChainID,
73+
ChainID: r.chainID,
7274
},
7375
},
7476
})
@@ -109,7 +111,16 @@ func (r *deliverClient) readUntilClose() {
109111

110112
func main() {
111113
config := config.Load()
112-
serverAddr := fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort)
114+
115+
var chainID string
116+
var serverAddr string
117+
var windowSize uint64
118+
119+
flag.StringVar(&serverAddr, "server", fmt.Sprintf("%s:%d", config.General.ListenAddress, config.General.ListenPort), "The RPC server to connect to.")
120+
flag.StringVar(&chainID, "chainID", static.TestChainID, "The chain ID to deliver from.")
121+
flag.Uint64Var(&windowSize, "windowSize", 10, "The window size for the deliver.")
122+
flag.Parse()
123+
113124
conn, err := grpc.Dial(serverAddr, grpc.WithInsecure())
114125
if err != nil {
115126
fmt.Println("Error connecting:", err)
@@ -121,7 +132,7 @@ func main() {
121132
return
122133
}
123134

124-
s := newDeliverClient(client, 10)
135+
s := newDeliverClient(client, chainID, windowSize)
125136
s.seekOldest()
126137
s.readUntilClose()
127138

0 commit comments

Comments
 (0)