Skip to content

Commit

Permalink
CodeCmn Modify:只读跨链调用缓存问题参考v3.11流程修改,调用跨链合约invoke 加上fee,会走缓存,不加invoke…
Browse files Browse the repository at this point in the history
…不会,预执行中未找到缓存代码
  • Loading branch information
CodeCmn authored and springrain committed Nov 16, 2021
1 parent e70263c commit 30ca9b3
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 64 deletions.
19 changes: 17 additions & 2 deletions bcs/ledger/xledger/state/tx_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}()
Expand Down Expand Up @@ -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(),
Expand Down
19 changes: 10 additions & 9 deletions kernel/contract/sandbox/cross_query_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,34 +38,35 @@ 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
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")
}
// Call endorsor for responce
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")
Expand Down
109 changes: 56 additions & 53 deletions kernel/contract/sandbox/xmcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions kernel/contract/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 30ca9b3

Please sign in to comment.