github.com/turingchain2020/turingchain@v1.1.21/executor/plugin.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package executor
     6  
     7  import (
     8  	"sync"
     9  
    10  	dbm "github.com/turingchain2020/turingchain/common/db"
    11  	"github.com/turingchain2020/turingchain/types"
    12  )
    13  
    14  //plugin 主要用于处理 execlocal 和 execdellocal 时候的全局kv的处理
    15  //每个插件都有插件是否开启这个插件的判断,如果不开启,执行的时候会被忽略
    16  
    17  type plugin interface {
    18  	CheckEnable(executor *executor, enable bool) (kvs []*types.KeyValue, ok bool, err error)
    19  	ExecLocal(executor *executor, data *types.BlockDetail) ([]*types.KeyValue, error)
    20  	ExecDelLocal(executor *executor, data *types.BlockDetail) ([]*types.KeyValue, error)
    21  }
    22  
    23  var globalPlugins = make(map[string]plugin)
    24  
    25  // RegisterPlugin register plugin
    26  func RegisterPlugin(name string, p plugin) {
    27  	if _, ok := globalPlugins[name]; ok {
    28  		panic("plugin exist " + name)
    29  	}
    30  	globalPlugins[name] = p
    31  }
    32  
    33  type pluginBase struct {
    34  	flag int64
    35  	mu   sync.Mutex
    36  }
    37  
    38  func (base *pluginBase) checkFlag(executor *executor, flagKey []byte, enable bool) (kvset []*types.KeyValue, ok bool, err error) {
    39  	if !enable {
    40  		return nil, false, nil
    41  	}
    42  	base.mu.Lock()
    43  	defer base.mu.Unlock()
    44  	if base.flag == 0 {
    45  		flag, err := loadFlag(executor.localDB, flagKey)
    46  		if err != nil {
    47  			return nil, false, err
    48  		}
    49  		base.flag = flag
    50  	}
    51  	if executor.height != 0 && base.flag == 0 {
    52  		return nil, false, types.ErrDBFlag
    53  	}
    54  	if executor.height == 0 {
    55  		base.flag = 1
    56  		kvset = append(kvset, types.FlagKV(flagKey, base.flag))
    57  	}
    58  	return kvset, true, nil
    59  }
    60  
    61  func loadFlag(localDB dbm.KVDB, key []byte) (int64, error) {
    62  	flag := &types.Int64{}
    63  	flagBytes, err := localDB.Get(key)
    64  	if err == nil {
    65  		err = types.Decode(flagBytes, flag)
    66  		if err != nil {
    67  			return 0, err
    68  		}
    69  		return flag.GetData(), nil
    70  	} else if err == types.ErrNotFound {
    71  		return 0, nil
    72  	}
    73  	return 0, err
    74  }