@@ -11,14 +11,19 @@ import (
11
11
"encoding/json"
12
12
"fmt"
13
13
14
+ "github.com/golang/protobuf/proto"
15
+
16
+ "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/common/channelconfig"
14
17
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/common/tools/protolator"
15
18
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/protoutil"
16
19
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/sdkinternal/configtxgen/encoder"
20
+ "github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/sdkinternal/configtxlator/update"
17
21
"github.com/pkg/errors"
18
22
19
23
"github.com/hyperledger/fabric-sdk-go/internal/github.com/hyperledger/fabric/sdkinternal/configtxgen/localconfig"
20
24
21
25
"github.com/hyperledger/fabric-sdk-go/pkg/fab/resource/genesisconfig"
26
+ "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
22
27
cb "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/protos/common"
23
28
)
24
29
@@ -38,14 +43,19 @@ func CreateGenesisBlock(config *genesisconfig.Profile, channelID string) ([]byte
38
43
if config .Orderer == nil {
39
44
return nil , errors .Errorf ("refusing to generate block which is missing orderer section" )
40
45
}
41
- if config .Consortiums == nil {
42
- logger .Warn ("Genesis block does not contain a consortiums group definition. This block cannot be used for orderer bootstrap." )
43
- }
44
46
genesisBlock := pgen .GenesisBlockForChannel (channelID )
45
47
logger .Debug ("Writing genesis block" )
46
48
return protoutil .Marshal (genesisBlock )
47
49
}
48
50
51
+ // CreateGenesisBlock creates a genesis block for a channel
52
+ func CreateGenesisBlockForOrderer (config * genesisconfig.Profile , channelID string ) ([]byte , error ) {
53
+ if config .Consortiums == nil {
54
+ return nil , errors .Errorf ("Genesis block does not contain a consortiums group definition. This block cannot be used for orderer bootstrap." )
55
+ }
56
+ return CreateGenesisBlock (config , channelID )
57
+ }
58
+
49
59
func genesisToLocalConfig (config * genesisconfig.Profile ) (* localconfig.Profile , error ) {
50
60
b , err := json .Marshal (config )
51
61
if err != nil {
@@ -59,8 +69,11 @@ func genesisToLocalConfig(config *genesisconfig.Profile) (*localconfig.Profile,
59
69
return c , nil
60
70
}
61
71
62
- // InspectGenesisBlock inspects a block
63
- func InspectGenesisBlock (data []byte ) (string , error ) {
72
+ // InspectBlock inspects a block
73
+ func InspectBlock (data []byte ) (string , error ) {
74
+ if len (data ) == 0 {
75
+ return "" , fmt .Errorf ("missing block" )
76
+ }
64
77
logger .Debug ("Parsing genesis block" )
65
78
block , err := protoutil .UnmarshalBlock (data )
66
79
if err != nil {
@@ -115,3 +128,52 @@ func InspectChannelCreateTx(data []byte) (string, error) {
115
128
}
116
129
return buf .String (), nil
117
130
}
131
+
132
+ // CreateAnchorPeersUpdate creates an anchor peers update transaction
133
+ func CreateAnchorPeersUpdate (conf * genesisconfig.Profile , channelID string , asOrg string ) (* common.Envelope , error ) {
134
+ logger .Debug ("Generating anchor peer update" )
135
+ if asOrg == "" {
136
+ return nil , fmt .Errorf ("Must specify an organization to update the anchor peer for" )
137
+ }
138
+
139
+ if conf .Application == nil {
140
+ return nil , fmt .Errorf ("Cannot update anchor peers without an application section" )
141
+ }
142
+
143
+ localConf , err := genesisToLocalConfig (conf )
144
+ if err != nil {
145
+ return nil , err
146
+ }
147
+
148
+ original , err := encoder .NewChannelGroup (localConf )
149
+ if err != nil {
150
+ return nil , errors .WithMessage (err , "error parsing profile as channel group" )
151
+ }
152
+ original .Groups [channelconfig .ApplicationGroupKey ].Version = 1
153
+
154
+ updated := proto .Clone (original ).(* cb.ConfigGroup )
155
+
156
+ originalOrg , ok := original .Groups [channelconfig .ApplicationGroupKey ].Groups [asOrg ]
157
+ if ! ok {
158
+ return nil , errors .Errorf ("org with name '%s' does not exist in config" , asOrg )
159
+ }
160
+
161
+ if _ , ok = originalOrg .Values [channelconfig .AnchorPeersKey ]; ! ok {
162
+ return nil , errors .Errorf ("org '%s' does not have any anchor peers defined" , asOrg )
163
+ }
164
+
165
+ delete (originalOrg .Values , channelconfig .AnchorPeersKey )
166
+
167
+ updt , err := update .Compute (& cb.Config {ChannelGroup : original }, & cb.Config {ChannelGroup : updated })
168
+ if err != nil {
169
+ return nil , errors .WithMessage (err , "could not compute update" )
170
+ }
171
+ updt .ChannelId = channelID
172
+
173
+ newConfigUpdateEnv := & cb.ConfigUpdateEnvelope {
174
+ ConfigUpdate : protoutil .MarshalOrPanic (updt ),
175
+ }
176
+
177
+ return protoutil .CreateSignedEnvelope (cb .HeaderType_CONFIG_UPDATE , channelID , nil , newConfigUpdateEnv , 0 , 0 )
178
+
179
+ }
0 commit comments