Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit eb9db60

Browse files
committed
[FAB-8422] Refactor broadcast to sign proposal
This change moves signing of broadcasts to the broadcast method. Change-Id: I0af49bcce888c8213baeb372fa0f6444c3baf6c5 Signed-off-by: Troy Ronda <troy@troyronda.com>
1 parent ef2097c commit eb9db60

File tree

6 files changed

+146
-155
lines changed

6 files changed

+146
-155
lines changed

api/apifabclient/resource.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@ type CreateChannelRequest struct {
4040
// required by the channel create policy when using the `config` parameter.
4141
// see signChannelConfig() method of this package
4242
Signatures []*common.ConfigSignature
43-
44-
// TODO: InvokeChannelRequest allows the TransactionID to be passed in.
45-
// This request struct also has the field for consistency but perhaps it should be removed.
46-
TxnID TransactionID
4743
}
4844

4945
// InstallChaincodeRequest requests chaincode installation on the network

pkg/fabric-client/channel/block.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,22 +71,12 @@ func (c *Channel) block(pos *ab.SeekPosition) (*common.Block, error) {
7171
return nil, errors.Wrap(err, "marshal seek info failed")
7272
}
7373

74-
seekPayload := &common.Payload{
74+
payload := common.Payload{
7575
Header: seekHeader,
7676
Data: seekInfoBytes,
7777
}
7878

79-
seekPayloadBytes, err := proto.Marshal(seekPayload)
80-
if err != nil {
81-
return nil, err
82-
}
83-
84-
signedEnvelope, err := txn.SignPayload(c.clientContext, seekPayloadBytes)
85-
if err != nil {
86-
return nil, errors.WithMessage(err, "SignPayload failed")
87-
}
88-
89-
return txn.SendEnvelope(c.clientContext, signedEnvelope, c.Orderers())
79+
return txn.SendPayload(c.clientContext, &payload, c.Orderers())
9080
}
9181

9282
// newNewestSeekPosition returns a SeekPosition that requests the newest block

pkg/fabric-client/resource/resource.go

Lines changed: 75 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"github.com/hyperledger/fabric-sdk-go/pkg/logging"
2222
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
2323
pb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/peer"
24-
protos_utils "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/utils"
2524
)
2625

2726
var logger = logging.NewLogger("fabric_sdk_go")
@@ -70,21 +69,47 @@ func (c *Resource) SignChannelConfig(config []byte, signer fab.IdentityContext)
7069

7170
// CreateChannel calls the orderer to start building the new channel.
7271
func (c *Resource) CreateChannel(request fab.CreateChannelRequest) (fab.TransactionID, error) {
73-
haveEnvelope := false
72+
if request.Orderer == nil {
73+
return fab.TransactionID{}, errors.New("missing orderer request parameter for the initialize channel")
74+
}
75+
76+
if request.Name == "" {
77+
return fab.TransactionID{}, errors.New("missing name request parameter for the new channel")
78+
}
79+
7480
if request.Envelope != nil {
75-
logger.Debug("createChannel - have envelope")
76-
haveEnvelope = true
81+
return c.createChannelFromEnvelope(request)
7782
}
7883

79-
if !haveEnvelope && request.TxnID.ID == "" {
80-
txnID, err := txn.NewID(c.clientContext)
81-
if err != nil {
82-
return txnID, err
83-
}
84-
request.TxnID = txnID
84+
if request.Config == nil {
85+
return fab.TransactionID{}, errors.New("missing envelope request parameter containing the configuration of the new channel")
8586
}
8687

87-
return request.TxnID, c.createOrUpdateChannel(request, haveEnvelope)
88+
if request.Signatures == nil {
89+
return fab.TransactionID{}, errors.New("missing signatures request parameter for the new channel")
90+
}
91+
92+
txnID, err := txn.NewID(c.clientContext)
93+
if err != nil {
94+
return txnID, err
95+
}
96+
97+
return txnID, c.createOrUpdateChannel(txnID, request)
98+
}
99+
100+
// TODO: this function was extracted from createOrUpdateChannel, but needs a closer examination.
101+
func (c *Resource) createChannelFromEnvelope(request fab.CreateChannelRequest) (fab.TransactionID, error) {
102+
env, err := c.extractSignedEnvelope(request.Envelope)
103+
if err != nil {
104+
return fab.TransactionID{}, errors.WithMessage(err, "signed envelope not valid")
105+
}
106+
107+
// Send request
108+
_, err = request.Orderer.SendBroadcast(env)
109+
if err != nil {
110+
return fab.TransactionID{}, errors.WithMessage(err, "failed broadcast to orderer")
111+
}
112+
return fab.TransactionID{}, nil
88113
}
89114

90115
// GenesisBlockFromOrderer returns the genesis block from the defined orderer that may be
@@ -107,6 +132,10 @@ func (c *Resource) GenesisBlockFromOrderer(channelName string, orderer fab.Order
107132
Stop: seekStop,
108133
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
109134
}
135+
seekInfoBytes, err := proto.Marshal(seekInfo)
136+
if err != nil {
137+
return nil, errors.Wrap(err, "marshaling of seek info header failed")
138+
}
110139

111140
tlsCertHash := ccomm.TLSCertHash(c.clientContext.Config())
112141
channelHeaderOpts := txn.ChannelHeaderOpts{
@@ -116,24 +145,15 @@ func (c *Resource) GenesisBlockFromOrderer(channelName string, orderer fab.Order
116145
}
117146
seekInfoHeader, err := txn.CreateChannelHeader(common.HeaderType_DELIVER_SEEK_INFO, channelHeaderOpts)
118147
if err != nil {
119-
return nil, errors.Wrap(err, "BuildChannelHeader failed")
120-
}
121-
seekHeader, err := txn.CreateHeader(c.clientContext, seekInfoHeader, txnID)
122-
if err != nil {
123-
return nil, errors.Wrap(err, "BuildHeader failed")
124-
}
125-
seekPayload := &common.Payload{
126-
Header: seekHeader,
127-
Data: protos_utils.MarshalOrPanic(seekInfo),
148+
return nil, errors.Wrap(err, "CreateChannelHeader failed")
128149
}
129-
seekPayloadBytes := protos_utils.MarshalOrPanic(seekPayload)
130150

131-
signedEnvelope, err := txn.SignPayload(c.clientContext, seekPayloadBytes)
151+
payload, err := txn.CreatePayload(txnID, seekInfoHeader, seekInfoBytes)
132152
if err != nil {
133-
return nil, errors.WithMessage(err, "SignPayload failed")
153+
return nil, errors.Wrap(err, "CreatePayload failed")
134154
}
135155

136-
block, err := txn.SendEnvelope(c.clientContext, signedEnvelope, orderers)
156+
block, err := txn.SendPayload(c.clientContext, payload, orderers)
137157
if err != nil {
138158
return nil, errors.WithMessage(err, "SendEnvelope failed")
139159
}
@@ -168,101 +188,50 @@ func (c *Resource) JoinChannel(request fab.JoinChannelRequest) error {
168188
return err
169189
}
170190

171-
// createOrUpdateChannel creates a new channel or updates an existing channel.
172-
func (c *Resource) createOrUpdateChannel(request fab.CreateChannelRequest, haveEnvelope bool) error {
173-
// Validate request
174-
if request.Config == nil && !haveEnvelope {
175-
return errors.New("missing envelope request parameter containing the configuration of the new channel")
191+
func (c *Resource) extractSignedEnvelope(reqEnvelope []byte) (*fab.SignedEnvelope, error) {
192+
envelope := &common.Envelope{}
193+
err := proto.Unmarshal(reqEnvelope, envelope)
194+
if err != nil {
195+
return nil, errors.Wrap(err, "unmarshal request envelope failed")
176196
}
177-
178-
if request.Signatures == nil && !haveEnvelope {
179-
return errors.New("missing signatures request parameter for the new channel")
197+
se := fab.SignedEnvelope{
198+
Signature: envelope.Signature,
199+
Payload: envelope.Payload,
180200
}
201+
return &se, nil
202+
}
181203

182-
if request.TxnID.ID == "" && !haveEnvelope {
183-
return errors.New("txId required")
184-
}
204+
// createOrUpdateChannel creates a new channel or updates an existing channel.
205+
func (c *Resource) createOrUpdateChannel(txnID fab.TransactionID, request fab.CreateChannelRequest) error {
185206

186-
if request.TxnID.Nonce == nil && !haveEnvelope {
187-
return errors.New("nonce required")
207+
configUpdateEnvelope := &common.ConfigUpdateEnvelope{
208+
ConfigUpdate: request.Config,
209+
Signatures: request.Signatures,
188210
}
189-
190-
if request.Orderer == nil {
191-
return errors.New("missing orderer request parameter for the initialize channel")
211+
configUpdateEnvelopeBytes, err := proto.Marshal(configUpdateEnvelope)
212+
if err != nil {
213+
return errors.Wrap(err, "marshal configUpdateEnvelope failed")
192214
}
193215

194-
if request.Name == "" {
195-
return errors.New("missing name request parameter for the new channel")
216+
channelHeaderOpts := txn.ChannelHeaderOpts{
217+
ChannelID: request.Name,
218+
TxnID: txnID,
219+
TLSCertHash: ccomm.TLSCertHash(c.clientContext.Config()),
196220
}
197-
198-
// channel = null;
199-
var signature []byte
200-
var payloadBytes []byte
201-
202-
if haveEnvelope {
203-
logger.Debug("createOrUpdateChannel - have envelope")
204-
envelope := &common.Envelope{}
205-
err := proto.Unmarshal(request.Envelope, envelope)
206-
if err != nil {
207-
return errors.Wrap(err, "unmarshal request envelope failed")
208-
}
209-
signature = envelope.Signature
210-
payloadBytes = envelope.Payload
211-
} else {
212-
logger.Debug("createOrUpdateChannel - have config_update")
213-
configUpdateEnvelope := &common.ConfigUpdateEnvelope{
214-
ConfigUpdate: request.Config,
215-
Signatures: request.Signatures,
216-
}
217-
218-
// TODO: Move
219-
channelHeaderOpts := txn.ChannelHeaderOpts{
220-
ChannelID: request.Name,
221-
TxnID: request.TxnID,
222-
TLSCertHash: ccomm.TLSCertHash(c.clientContext.Config()),
223-
}
224-
channelHeader, err := txn.CreateChannelHeader(common.HeaderType_CONFIG_UPDATE, channelHeaderOpts)
225-
if err != nil {
226-
return errors.WithMessage(err, "BuildChannelHeader failed")
227-
}
228-
229-
header, err := txn.CreateHeader(c.clientContext, channelHeader, request.TxnID)
230-
if err != nil {
231-
return errors.Wrap(err, "BuildHeader failed")
232-
}
233-
configUpdateEnvelopeBytes, err := proto.Marshal(configUpdateEnvelope)
234-
if err != nil {
235-
return errors.Wrap(err, "marshal configUpdateEnvelope failed")
236-
}
237-
payload := &common.Payload{
238-
Header: header,
239-
Data: configUpdateEnvelopeBytes,
240-
}
241-
payloadBytes, err = proto.Marshal(payload)
242-
if err != nil {
243-
return errors.Wrap(err, "marshal payload failed")
244-
}
245-
246-
signingMgr := c.clientContext.SigningManager()
247-
if signingMgr == nil {
248-
return errors.New("signing manager is nil")
249-
}
250-
251-
signature, err = signingMgr.Sign(payloadBytes, c.clientContext.PrivateKey())
252-
if err != nil {
253-
return errors.WithMessage(err, "signing payload failed")
254-
}
221+
channelHeader, err := txn.CreateChannelHeader(common.HeaderType_CONFIG_UPDATE, channelHeaderOpts)
222+
if err != nil {
223+
return errors.WithMessage(err, "CreateChannelHeader failed")
255224
}
256225

257-
// Send request
258-
_, err := request.Orderer.SendBroadcast(&fab.SignedEnvelope{
259-
Signature: signature,
260-
Payload: payloadBytes,
261-
})
226+
payload, err := txn.CreatePayload(txnID, channelHeader, configUpdateEnvelopeBytes)
262227
if err != nil {
263-
return errors.WithMessage(err, "failed broadcast to orderer")
228+
return errors.WithMessage(err, "CreatePayload failed")
264229
}
265230

231+
_, err = txn.BroadcastPayload(c.clientContext, payload, []fab.Orderer{request.Orderer})
232+
if err != nil {
233+
return errors.WithMessage(err, "SendEnvelope failed")
234+
}
266235
return nil
267236
}
268237

pkg/fabric-client/txn/env.go

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,19 @@ func computeTxnID(nonce, creator []byte, h hash.Hash) (string, error) {
7272
return id, nil
7373
}
7474

75-
// SignPayload signs payload
76-
//
77-
// TODO: Determine if this function should be exported after refactoring is completed.
78-
func SignPayload(ctx context, payload []byte) (*fab.SignedEnvelope, error) {
75+
// signPayload signs payload
76+
func signPayload(ctx context, payload *common.Payload) (*fab.SignedEnvelope, error) {
77+
payloadBytes, err := proto.Marshal(payload)
78+
if err != nil {
79+
return nil, errors.WithMessage(err, "marshaling of payload failed")
80+
}
81+
7982
signingMgr := ctx.SigningManager()
80-
signature, err := signingMgr.Sign(payload, ctx.PrivateKey())
83+
signature, err := signingMgr.Sign(payloadBytes, ctx.PrivateKey())
8184
if err != nil {
82-
return nil, err
85+
return nil, errors.WithMessage(err, "signing of payload failed")
8386
}
84-
return &fab.SignedEnvelope{Payload: payload, Signature: signature}, nil
87+
return &fab.SignedEnvelope{Payload: payloadBytes, Signature: signature}, nil
8588
}
8689

8790
// ChannelHeaderOpts holds the parameters to create a ChannelHeader.
@@ -133,15 +136,11 @@ func CreateChannelHeader(headerType common.HeaderType, opts ChannelHeaderOpts) (
133136
return channelHeader, nil
134137
}
135138

136-
// CreateHeader creates a Header from a ChannelHeader.
137-
func CreateHeader(ctx fab.IdentityContext, channelHeader *common.ChannelHeader, txnID fab.TransactionID) (*common.Header, error) {
138-
creator, err := ctx.Identity()
139-
if err != nil {
140-
return nil, errors.WithMessage(err, "extracting creator from identity context failed")
141-
}
139+
// createHeader creates a Header from a ChannelHeader.
140+
func createHeader(txnID fab.TransactionID, channelHeader *common.ChannelHeader) (*common.Header, error) {
142141

143142
signatureHeader := &common.SignatureHeader{
144-
Creator: creator,
143+
Creator: txnID.Creator,
145144
Nonce: txnID.Nonce,
146145
}
147146
sh, err := proto.Marshal(signatureHeader)
@@ -152,9 +151,24 @@ func CreateHeader(ctx fab.IdentityContext, channelHeader *common.ChannelHeader,
152151
if err != nil {
153152
return nil, errors.Wrap(err, "marshal channelHeader failed")
154153
}
155-
header := &common.Header{
154+
header := common.Header{
156155
SignatureHeader: sh,
157156
ChannelHeader: ch,
158157
}
159-
return header, nil
158+
return &header, nil
159+
}
160+
161+
// CreatePayload creates a slice of payload bytes from a ChannelHeader and a data slice.
162+
func CreatePayload(txnID fab.TransactionID, channelHeader *common.ChannelHeader, data []byte) (*common.Payload, error) {
163+
header, err := createHeader(txnID, channelHeader)
164+
if err != nil {
165+
return nil, errors.Wrap(err, "header creation failed")
166+
}
167+
168+
payload := common.Payload{
169+
Header: header,
170+
Data: data,
171+
}
172+
173+
return &payload, nil
160174
}

0 commit comments

Comments
 (0)