6 Star 44 Fork 25

Hyperledger / fabric

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
validation_logic.go 7.09 KB
一键复制 编辑 原始数据 按行查看 历史
Danny Cao 提交于 2019-11-21 14:07 . [FAB-17123] Revert FAB-17038
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package v20
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/peer"
commonerrors "github.com/hyperledger/fabric/common/errors"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/core/common/validation/statebased"
vc "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities"
vi "github.com/hyperledger/fabric/core/handlers/validation/api/identities"
vp "github.com/hyperledger/fabric/core/handlers/validation/api/policies"
vs "github.com/hyperledger/fabric/core/handlers/validation/api/state"
"github.com/hyperledger/fabric/protoutil"
"github.com/pkg/errors"
)
var logger = flogging.MustGetLogger("vscc")
//go:generate mockery -dir . -name IdentityDeserializer -case underscore -output mocks/
// IdentityDeserializer is the local interface that used to generate mocks for foreign interface.
type IdentityDeserializer interface {
vi.IdentityDeserializer
}
//go:generate mockery -dir . -name CollectionResources -case underscore -output mocks/
// CollectionResources is the local interface that used to generate mocks for foreign interface.
type CollectionResources interface {
statebased.CollectionResources
}
//go:generate mockery -dir . -name StateBasedValidator -case underscore -output mocks/
// toApplicationPolicyTranslator implements statebased.PolicyTranslator
// by translating SignaturePolicyEnvelope policies into ApplicationPolicy
// ones; this is required because the 2.0 validator is supplied with a
// policy evaluator that can only understand ApplicationPolicy policies.
type toApplicationPolicyTranslator struct{}
func (n *toApplicationPolicyTranslator) Translate(b []byte) ([]byte, error) {
if len(b) == 0 {
return b, nil
}
spe := &common.SignaturePolicyEnvelope{}
err := proto.Unmarshal(b, spe)
if err != nil {
return nil, errors.Wrap(err, "could not unmarshal signature policy envelope")
}
return protoutil.MarshalOrPanic(&peer.ApplicationPolicy{
Type: &peer.ApplicationPolicy_SignaturePolicy{
SignaturePolicy: spe,
},
}), nil
}
// New creates a new instance of the default VSCC
// Typically this will only be invoked once per peer
func New(c vc.Capabilities, s vs.StateFetcher, d vi.IdentityDeserializer, pe vp.PolicyEvaluator, cor statebased.CollectionResources) *Validator {
vpmgr := &statebased.KeyLevelValidationParameterManagerImpl{
StateFetcher: s,
PolicyTranslator: &toApplicationPolicyTranslator{},
}
eval := statebased.NewV20Evaluator(vpmgr, pe, cor, s)
sbv := statebased.NewKeyLevelValidator(eval, vpmgr)
return &Validator{
capabilities: c,
stateFetcher: s,
deserializer: d,
policyEvaluator: pe,
stateBasedValidator: sbv,
}
}
// Validator implements the default transaction validation policy,
// which is to check the correctness of the read-write set and the endorsement
// signatures against an endorsement policy that is supplied as argument to
// every invoke
type Validator struct {
deserializer vi.IdentityDeserializer
capabilities vc.Capabilities
stateFetcher vs.StateFetcher
policyEvaluator vp.PolicyEvaluator
stateBasedValidator StateBasedValidator
}
type validationArtifacts struct {
rwset []byte
prp []byte
endorsements []*peer.Endorsement
chdr *common.ChannelHeader
env *common.Envelope
payl *common.Payload
cap *peer.ChaincodeActionPayload
}
func (vscc *Validator) extractValidationArtifacts(
block *common.Block,
txPosition int,
actionPosition int,
) (*validationArtifacts, error) {
// get the envelope...
env, err := protoutil.GetEnvelopeFromBlock(block.Data.Data[txPosition])
if err != nil {
logger.Errorf("VSCC error: GetEnvelope failed, err %s", err)
return nil, err
}
// ...and the payload...
payl, err := protoutil.UnmarshalPayload(env.Payload)
if err != nil {
logger.Errorf("VSCC error: GetPayload failed, err %s", err)
return nil, err
}
chdr, err := protoutil.UnmarshalChannelHeader(payl.Header.ChannelHeader)
if err != nil {
return nil, err
}
// validate the payload type
if common.HeaderType(chdr.Type) != common.HeaderType_ENDORSER_TRANSACTION {
logger.Errorf("Only Endorser Transactions are supported, provided type %d", chdr.Type)
err = fmt.Errorf("Only Endorser Transactions are supported, provided type %d", chdr.Type)
return nil, err
}
// ...and the transaction...
tx, err := protoutil.UnmarshalTransaction(payl.Data)
if err != nil {
logger.Errorf("VSCC error: GetTransaction failed, err %s", err)
return nil, err
}
cap, err := protoutil.UnmarshalChaincodeActionPayload(tx.Actions[actionPosition].Payload)
if err != nil {
logger.Errorf("VSCC error: GetChaincodeActionPayload failed, err %s", err)
return nil, err
}
pRespPayload, err := protoutil.UnmarshalProposalResponsePayload(cap.Action.ProposalResponsePayload)
if err != nil {
err = fmt.Errorf("GetProposalResponsePayload error %s", err)
return nil, err
}
if pRespPayload.Extension == nil {
err = fmt.Errorf("nil pRespPayload.Extension")
return nil, err
}
respPayload, err := protoutil.UnmarshalChaincodeAction(pRespPayload.Extension)
if err != nil {
err = fmt.Errorf("GetChaincodeAction error %s", err)
return nil, err
}
return &validationArtifacts{
rwset: respPayload.Results,
prp: cap.Action.ProposalResponsePayload,
endorsements: cap.Action.Endorsements,
chdr: chdr,
env: env,
payl: payl,
cap: cap,
}, nil
}
// Validate validates the given envelope corresponding to a transaction with an endorsement
// policy as given in its serialized form.
// Note that in the case of dependencies in a block, such as tx_n modifying the endorsement policy
// for key a and tx_n+1 modifying the value of key a, Validate(tx_n+1) will block until Validate(tx_n)
// has been resolved. If working with a limited number of goroutines for parallel validation, ensure
// that they are allocated to transactions in ascending order.
func (vscc *Validator) Validate(
block *common.Block,
namespace string,
txPosition int,
actionPosition int,
policyBytes []byte,
) commonerrors.TxValidationError {
vscc.stateBasedValidator.PreValidate(uint64(txPosition), block)
va, err := vscc.extractValidationArtifacts(block, txPosition, actionPosition)
if err != nil {
vscc.stateBasedValidator.PostValidate(namespace, block.Header.Number, uint64(txPosition), err)
return policyErr(err)
}
txverr := vscc.stateBasedValidator.Validate(
namespace,
block.Header.Number,
uint64(txPosition),
va.rwset,
va.prp,
policyBytes,
va.endorsements,
)
if txverr != nil {
logger.Errorf("VSCC error: stateBasedValidator.Validate failed, err %s", txverr)
vscc.stateBasedValidator.PostValidate(namespace, block.Header.Number, uint64(txPosition), txverr)
return txverr
}
vscc.stateBasedValidator.PostValidate(namespace, block.Header.Number, uint64(txPosition), nil)
return nil
}
func policyErr(err error) *commonerrors.VSCCEndorsementPolicyError {
return &commonerrors.VSCCEndorsementPolicyError{
Err: err,
}
}
1
https://gitee.com/hyperledger/fabric.git
git@gitee.com:hyperledger/fabric.git
hyperledger
fabric
fabric
v2.1.1

搜索帮助