@@ -26,19 +26,30 @@ import (
26
26
"github.com/hyperledger/fabric/core/common/validation"
27
27
"github.com/hyperledger/fabric/core/ledger"
28
28
ledgerUtil "github.com/hyperledger/fabric/core/ledger/util"
29
- "github.com/hyperledger/fabric/core/peer/msp"
30
29
"github.com/hyperledger/fabric/msp"
31
30
"github.com/hyperledger/fabric/protos/common"
32
31
"github.com/hyperledger/fabric/protos/utils"
33
32
"github.com/op/go-logging"
34
33
"github.com/syndtr/goleveldb/leveldb/errors"
35
34
)
36
35
36
+ // Support provides all of the needed to evaluate the VSCC
37
+ type Support interface {
38
+ // Ledger returns the ledger associated with this validator
39
+ Ledger () ledger.PeerLedger
40
+
41
+ // MSPManager returns the MSP manager for this chain
42
+ MSPManager () msp.MSPManager
43
+
44
+ // Apply attempts to apply a configtx to become the new configuration
45
+ Apply (configtx * common.ConfigurationEnvelope ) error
46
+ }
47
+
37
48
//Validator interface which defines API to validate block transactions
38
49
// and return the bit array mask indicating invalid transactions which
39
50
// didn't pass validation.
40
51
type Validator interface {
41
- Validate (block * common.Block )
52
+ Validate (block * common.Block ) error
42
53
}
43
54
44
55
// private interface to decouple tx validator
@@ -51,16 +62,16 @@ type vsccValidator interface {
51
62
// vsccValidator implementation which used to call
52
63
// vscc chaincode and validate block transactions
53
64
type vsccValidatorImpl struct {
54
- ledger ledger. PeerLedger
65
+ support Support
55
66
ccprovider ccprovider.ChaincodeProvider
56
67
}
57
68
58
69
// implementation of Validator interface, keeps
59
70
// reference to the ledger to enable tx simulation
60
71
// and execution of vscc
61
72
type txValidator struct {
62
- ledger ledger. PeerLedger
63
- vscc vsccValidator
73
+ support Support
74
+ vscc vsccValidator
64
75
}
65
76
66
77
var logger * logging.Logger // package-level logger
@@ -71,17 +82,17 @@ func init() {
71
82
}
72
83
73
84
// NewTxValidator creates new transactions validator
74
- func NewTxValidator (ledger ledger. PeerLedger ) Validator {
85
+ func NewTxValidator (support Support ) Validator {
75
86
// Encapsulates interface implementation
76
- return & txValidator {ledger , & vsccValidatorImpl {ledger : ledger , ccprovider : ccprovider .GetChaincodeProvider ()}}
87
+ return & txValidator {support , & vsccValidatorImpl {support : support , ccprovider : ccprovider .GetChaincodeProvider ()}}
77
88
}
78
89
79
90
func (v * txValidator ) chainExists (chain string ) bool {
80
91
// TODO: implement this function!
81
92
return true
82
93
}
83
94
84
- func (v * txValidator ) Validate (block * common.Block ) {
95
+ func (v * txValidator ) Validate (block * common.Block ) error {
85
96
logger .Debug ("START Block Validation" )
86
97
defer logger .Debug ("END Block Validation" )
87
98
txsfltr := ledgerUtil .NewFilterBitArray (uint (len (block .Data .Data )))
@@ -117,7 +128,7 @@ func (v *txValidator) Validate(block *common.Block) {
117
128
if common .HeaderType (payload .Header .ChainHeader .Type ) == common .HeaderType_ENDORSER_TRANSACTION {
118
129
// Check duplicate transactions
119
130
txID := payload .Header .ChainHeader .TxID
120
- if _ , err := v .ledger .GetTransactionByID (txID ); err == nil {
131
+ if _ , err := v .support . Ledger () .GetTransactionByID (txID ); err == nil {
121
132
logger .Warning ("Duplicate transaction found, " , txID , ", skipping" )
122
133
continue
123
134
}
@@ -130,13 +141,19 @@ func (v *txValidator) Validate(block *common.Block) {
130
141
continue
131
142
}
132
143
} else if common .HeaderType (payload .Header .ChainHeader .Type ) == common .HeaderType_CONFIGURATION_TRANSACTION {
133
- // TODO: here we should call CSCC and pass it the config tx
134
- // note that there is quite a bit more validation necessary
135
- // on this tx, namely, validation that each config item has
136
- // signature matching the policy required for the item from
137
- // the existing configuration; this is taken care of nicely
138
- // by configtx.Manager (see fabric/common/configtx).
139
- logger .Debug ("config transaction received for chain %s" , chain )
144
+ configEnvelope , err := utils .UnmarshalConfigurationEnvelope (payload .Data )
145
+ if err != nil {
146
+ err := fmt .Errorf ("Error unmarshaling configuration which passed initial validity checks: %s" , err )
147
+ logger .Critical (err )
148
+ return err
149
+ }
150
+
151
+ if err := v .support .Apply (configEnvelope ); err != nil {
152
+ err := fmt .Errorf ("Error validating configuration which passed initial validity checks: %s" , err )
153
+ logger .Critical (err )
154
+ return err
155
+ }
156
+ logger .Debugf ("config transaction received for chain %s" , chain )
140
157
}
141
158
142
159
if _ , err := proto .Marshal (env ); err != nil {
@@ -155,16 +172,17 @@ func (v *txValidator) Validate(block *common.Block) {
155
172
utils .InitBlockMetadata (block )
156
173
// Serialize invalid transaction bit array into block metadata field
157
174
block .Metadata .Metadata [common .BlockMetadataIndex_TRANSACTIONS_FILTER ] = txsfltr .ToBytes ()
175
+
176
+ return nil
158
177
}
159
178
160
- // getHardcodedPolicy returns a policy that requests
179
+ // getSemiHardcodedPolicy returns a policy that requests
161
180
// one valid signature from the first MSP in this
162
181
// chain's MSP manager
163
182
// FIXME: this needs to be removed as soon as we extract the policy from LCCC
164
- func getHardcodedPolicy (chainID string ) ([]byte , error ) {
183
+ func getSemiHardcodedPolicy (chainID string , mspMgr msp. MSPManager ) ([]byte , error ) {
165
184
// 1) determine the MSP identifier for the first MSP in this chain
166
185
var msp msp.MSP
167
- mspMgr := mspmgmt .GetManagerForChain (chainID )
168
186
msps , err := mspMgr .GetMSPs ()
169
187
if err != nil {
170
188
return nil , fmt .Errorf ("Could not retrieve the MSPs for the chain manager, err %s" , err )
@@ -215,7 +233,7 @@ func (v *vsccValidatorImpl) VSCCValidateTx(payload *common.Payload, envBytes []b
215
233
// by the deployer and can be retrieved via LCCC: we create
216
234
// a policy that requests 1 valid signature from this chain's
217
235
// MSP
218
- policy , err := getHardcodedPolicy (chainID )
236
+ policy , err := getSemiHardcodedPolicy (chainID , v . support . MSPManager () )
219
237
if err != nil {
220
238
return err
221
239
}
@@ -226,7 +244,7 @@ func (v *vsccValidatorImpl) VSCCValidateTx(payload *common.Payload, envBytes []b
226
244
// args[2] - serialized policy
227
245
args := [][]byte {[]byte ("" ), envBytes , policy }
228
246
229
- ctxt , err := v .ccprovider .GetContext (v .ledger )
247
+ ctxt , err := v .ccprovider .GetContext (v .support . Ledger () )
230
248
if err != nil {
231
249
logger .Errorf ("Cannot obtain context for txid=%s, err %s" , txid , err )
232
250
return err
0 commit comments