diff --git a/bcs/ledger/xledger/state/tx_verification.go b/bcs/ledger/xledger/state/tx_verification.go index b39b8cfe..899594c3 100644 --- a/bcs/ledger/xledger/state/tx_verification.go +++ b/bcs/ledger/xledger/state/tx_verification.go @@ -43,7 +43,7 @@ import ( func (t *State) ImmediateVerifyTx(tx *pb.Transaction, isRootTx bool) (bool, error) { beginTime := time.Now() code := "InvalidTx" - defer func(){ + defer func() { metrics.CallMethodCounter.WithLabelValues(t.sctx.BCName, "ImmediateVerifyTx", code).Inc() metrics.CallMethodHistogram.WithLabelValues(t.sctx.BCName, "ImmediateVerifyTx").Observe(time.Since(beginTime).Seconds()) }() @@ -585,16 +585,31 @@ func (t *State) verifyTxRWSets(tx *pb.Transaction) (bool, error) { XMReader: reader, UTXOReader: utxoReader, } + sandBox, err := t.sctx.ContractMgr.NewStateSandbox(sandBoxConfig) if err != nil { return false, nil } - transContractName, transAmount, err := txn.ParseContractTransferRequest(req) + // 构建CrossQueryCache 依据xuperchain v3.10的流程添加 + // 1.ParseCrossQuery() + crossQueries, err := sandbox.ParseCrossQuery(tx) if err != nil { + t.log.Warn("PrepareEnv ParseCrossQuery error", "err", err.Error()) return false, err } + // 2.IsCrossQueryEffective() + if ok := sandbox.IsCrossQueryEffective(crossQueries, tx); !ok { + t.log.Warn("PrepareEnv IsCrossQueryEffective error") + return false, errors.New("PrepareEnv CheckCrossQueryEffective error") + } + // 3.crossQueries 缓存赋值到 XMCache 中 + sandBox.CrossQueryCache(crossQueries) + transContractName, transAmount, err := txn.ParseContractTransferRequest(req) + if err != nil { + return false, err + } contextConfig := &contract.ContextConfig{ State: sandBox, Initiator: tx.GetInitiator(), diff --git a/kernel/contract/sandbox/cross_query_cache.go b/kernel/contract/sandbox/cross_query_cache.go index 80c0610d..2a187a4b 100644 --- a/kernel/contract/sandbox/cross_query_cache.go +++ b/kernel/contract/sandbox/cross_query_cache.go @@ -38,11 +38,16 @@ func NewCrossQueryCache() *CrossQueryCache { } // NewCrossQueryCacheWithData return CrossQuery instance while posttx -func NewCrossQueryCacheWithData(crossQueries []*pb.CrossQueryInfo) *CrossQueryCache { - return &CrossQueryCache{ - crossQueryCaches: crossQueries, - isPenetrate: false, - } +// func NewCrossQueryCacheWithData(crossQueries []*pb.CrossQueryInfo) *CrossQueryCache { +// return &CrossQueryCache{ +// crossQueryCaches: crossQueries, +// isPenetrate: false, +// } +// } + +func (cqc *CrossQueryCache) CrossQueryCache(crossQueries []*pb.CrossQueryInfo) { + cqc.crossQueryCaches = crossQueries + cqc.isPenetrate = false } // CrossQuery query contract from otherchain @@ -50,8 +55,6 @@ func (cqc *CrossQueryCache) CrossQuery( crossQueryRequest *pb.CrossQueryRequest, queryMeta *pb.CrossQueryMeta) (*pb.ContractResponse, error) { - //log.Info("Receive CrossQuery", "crossQueryRequest", crossQueryRequest, "queryMeta", queryMeta) - if !isQueryMetaValid(queryMeta) { return nil, fmt.Errorf("isQueryParamValid check failed") } @@ -59,13 +62,11 @@ func (cqc *CrossQueryCache) CrossQuery( if cqc.isPenetrate { queryInfo, err := crossQueryFromEndorsor(crossQueryRequest, queryMeta) if err != nil { - //log.Info("crossQueryFromEndorsor error", "error", err.Error()) return nil, err } cqc.crossQueryCaches = append(cqc.crossQueryCaches, queryInfo) return queryInfo.GetResponse().GetResponse(), nil } - // 验证背书规则、参数有效性、时间戳有效性 if cqc.crossQueryIdx > len(cqc.crossQueryCaches)-1 { return nil, fmt.Errorf("len of crossQueryCaches not match the contract") diff --git a/kernel/contract/sandbox/xmcache.go b/kernel/contract/sandbox/xmcache.go index 5356d2a1..61140830 100644 --- a/kernel/contract/sandbox/xmcache.go +++ b/kernel/contract/sandbox/xmcache.go @@ -57,11 +57,10 @@ type XMCache struct { // NewXModelCache new an instance of XModel Cache func NewXModelCache(cfg *contract.SandboxConfig) *XMCache { return &XMCache{ - model: cfg.XMReader, - inputsCache: NewMemXModel(), - outputsCache: NewMemXModel(), - utxoSandbox: utxo.NewUTXOSandbox(cfg), - + model: cfg.XMReader, + inputsCache: NewMemXModel(), + outputsCache: NewMemXModel(), + utxoSandbox: utxo.NewUTXOSandbox(cfg), crossQueryCache: NewCrossQueryCache(), } } @@ -377,57 +376,61 @@ func (xc *XMCache) CrossQuery(crossQueryRequest *pb.CrossQueryRequest, queryMeta return xc.crossQueryCache.CrossQuery(crossQueryRequest, queryMeta) } +func (xc *XMCache) CrossQueryCache(crossQueries []*pb.CrossQueryInfo) { + xc.crossQueryCache.CrossQueryCache(crossQueries) +} + // ParseCrossQuery parse cross query from tx -//func ParseCrossQuery(tx *pb.Transaction) ([]*pb.CrossQueryInfo, error) { -// var ( -// crossQueryInfos []*pb.CrossQueryInfo -// queryInfos []byte -// ) -// for _, out := range tx.GetTxOutputsExt() { -// if out.GetBucket() != TransientBucket { -// continue -// } -// if bytes.Equal(out.GetKey(), crossQueryInfosKey) { -// queryInfos = out.GetValue() -// } -// } -// if queryInfos != nil { -// err := UnmsarshalMessages(queryInfos, &crossQueryInfos) -// if err != nil { -// return nil, err -// } -// } -// return crossQueryInfos, nil -//} +func ParseCrossQuery(tx *lpb.Transaction) ([]*pb.CrossQueryInfo, error) { + var ( + crossQueryInfos []*pb.CrossQueryInfo + queryInfos []byte + ) + for _, out := range tx.GetTxOutputsExt() { + if out.GetBucket() != TransientBucket { + continue + } + if bytes.Equal(out.GetKey(), crossQueryInfosKey) { + queryInfos = out.GetValue() + } + } + if queryInfos != nil { + err := UnmsarshalMessages(queryInfos, &crossQueryInfos) + if err != nil { + return nil, err + } + } + return crossQueryInfos, nil +} // IsCrossQueryEffective check if crossQueryInfos effective // TODO: zq -//func IsCrossQueryEffective(cqi []*pb.CrossQueryInfo, tx *pb.Transaction) bool { -// return true -//} +func IsCrossQueryEffective(cqi []*pb.CrossQueryInfo, tx *lpb.Transaction) bool { + return true +} // PutCrossQueries put queryInfos to db -//func (xc *XMCache) putCrossQueries(queryInfos []*pb.CrossQueryInfo) error { -// var qi []byte -// var err error -// if len(queryInfos) != 0 { -// qi, err = MarshalMessages(queryInfos) -// if err != nil { -// return err -// } -// } -// if qi != nil { -// err = xc.Put(TransientBucket, crossQueryInfosKey, qi) -// if err != nil { -// return err -// } -// } -// return nil -//} +func (xc *XMCache) putCrossQueries(queryInfos []*pb.CrossQueryInfo) error { + var qi []byte + var err error + if len(queryInfos) != 0 { + qi, err = MarshalMessages(queryInfos) + if err != nil { + return err + } + } + if qi != nil { + err = xc.Put(TransientBucket, crossQueryInfosKey, qi) + if err != nil { + return err + } + } + return nil +} -//func (xc *XMCache) writeCrossQueriesRWSet() error { -// return xc.putCrossQueries(xc.crossQueryCache.GetCrossQueryRWSets()) -//} +func (xc *XMCache) writeCrossQueriesRWSet() error { + return xc.putCrossQueries(xc.crossQueryCache.GetCrossQueryRWSets()) +} // ParseContractEvents parse contract events from tx func ParseContractEvents(tx *lpb.Transaction) ([]*protos.ContractEvent, error) { @@ -474,10 +477,10 @@ func (xc *XMCache) Flush() error { return err } - // err = xc.writeCrossQueriesRWSet() - // if err != nil { - // return err - // } + err = xc.writeCrossQueriesRWSet() + if err != nil { + return err + } err = xc.writeEventRWSet() if err != nil { diff --git a/kernel/contract/state.go b/kernel/contract/state.go index c6f22ace..f59c2906 100644 --- a/kernel/contract/state.go +++ b/kernel/contract/state.go @@ -44,6 +44,7 @@ type UTXOState interface { // CrossQueryState 对XuperBridge暴露对跨链只读合约的操作能力 type CrossQueryState interface { CrossQuery(crossQueryRequest *pb.CrossQueryRequest, queryMeta *pb.CrossQueryMeta) (*pb.ContractResponse, error) + CrossQueryCache(crossQueries []*pb.CrossQueryInfo) } type ContractEventState interface {