github.com/turingchain2020/turingchain@v1.1.21/executor/plugin_addrindex.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  	dbm "github.com/turingchain2020/turingchain/common/db"
     9  	drivers "github.com/turingchain2020/turingchain/system/dapp"
    10  	"github.com/turingchain2020/turingchain/types"
    11  )
    12  
    13  func init() {
    14  	RegisterPlugin("addrindex", &addrindexPlugin{})
    15  }
    16  
    17  type addrindexPlugin struct {
    18  	pluginBase
    19  }
    20  
    21  func (p *addrindexPlugin) CheckEnable(executor *executor, enable bool) (kvs []*types.KeyValue, ok bool, err error) {
    22  	return nil, enable, nil
    23  }
    24  
    25  func (p *addrindexPlugin) ExecLocal(executor *executor, data *types.BlockDetail) ([]*types.KeyValue, error) {
    26  	b := data.Block
    27  	var set types.LocalDBSet
    28  	for i := 0; i < len(b.Txs); i++ {
    29  		tx := b.Txs[i]
    30  		receipt := data.Receipts[i]
    31  		txindex := getTxIndex(executor, tx, receipt, i)
    32  		txinfobyte := types.Encode(txindex.index)
    33  		if len(txindex.from) != 0 {
    34  			fromkey1 := types.CalcTxAddrDirHashKey(txindex.from, drivers.TxIndexFrom, txindex.heightstr)
    35  			fromkey2 := types.CalcTxAddrHashKey(txindex.from, txindex.heightstr)
    36  			set.KV = append(set.KV, &types.KeyValue{Key: fromkey1, Value: txinfobyte})
    37  			set.KV = append(set.KV, &types.KeyValue{Key: fromkey2, Value: txinfobyte})
    38  			types.AssertConfig(executor.api)
    39  			kv, err := updateAddrTxsCount(executor.api.GetConfig(), executor.localDB, txindex.from, 1, true)
    40  			if err == nil && kv != nil {
    41  				set.KV = append(set.KV, kv)
    42  			}
    43  		}
    44  		if len(txindex.to) != 0 {
    45  			tokey1 := types.CalcTxAddrDirHashKey(txindex.to, drivers.TxIndexTo, txindex.heightstr)
    46  			tokey2 := types.CalcTxAddrHashKey(txindex.to, txindex.heightstr)
    47  			set.KV = append(set.KV, &types.KeyValue{Key: tokey1, Value: txinfobyte})
    48  			set.KV = append(set.KV, &types.KeyValue{Key: tokey2, Value: txinfobyte})
    49  			types.AssertConfig(executor.api)
    50  			kv, err := updateAddrTxsCount(executor.api.GetConfig(), executor.localDB, txindex.to, 1, true)
    51  			if err == nil && kv != nil {
    52  				set.KV = append(set.KV, kv)
    53  			}
    54  		}
    55  	}
    56  	return set.KV, nil
    57  }
    58  
    59  func (p *addrindexPlugin) ExecDelLocal(executor *executor, data *types.BlockDetail) ([]*types.KeyValue, error) {
    60  	b := data.Block
    61  	var set types.LocalDBSet
    62  	for i := 0; i < len(b.Txs); i++ {
    63  		tx := b.Txs[i]
    64  		receipt := data.Receipts[i]
    65  		//del: addr index
    66  		txindex := getTxIndex(executor, tx, receipt, i)
    67  		if len(txindex.from) != 0 {
    68  			fromkey1 := types.CalcTxAddrDirHashKey(txindex.from, drivers.TxIndexFrom, txindex.heightstr)
    69  			fromkey2 := types.CalcTxAddrHashKey(txindex.from, txindex.heightstr)
    70  			set.KV = append(set.KV, &types.KeyValue{Key: fromkey1, Value: nil})
    71  			set.KV = append(set.KV, &types.KeyValue{Key: fromkey2, Value: nil})
    72  			kv, err := updateAddrTxsCount(executor.api.GetConfig(), executor.localDB, txindex.from, 1, false)
    73  			if err == nil && kv != nil {
    74  				set.KV = append(set.KV, kv)
    75  			}
    76  		}
    77  		if len(txindex.to) != 0 {
    78  			tokey1 := types.CalcTxAddrDirHashKey(txindex.to, drivers.TxIndexTo, txindex.heightstr)
    79  			tokey2 := types.CalcTxAddrHashKey(txindex.to, txindex.heightstr)
    80  			set.KV = append(set.KV, &types.KeyValue{Key: tokey1, Value: nil})
    81  			set.KV = append(set.KV, &types.KeyValue{Key: tokey2, Value: nil})
    82  			kv, err := updateAddrTxsCount(executor.api.GetConfig(), executor.localDB, txindex.to, 1, false)
    83  			if err == nil && kv != nil {
    84  				set.KV = append(set.KV, kv)
    85  			}
    86  		}
    87  	}
    88  	return set.KV, nil
    89  }
    90  
    91  func getAddrTxsCountKV(addr string, count int64) *types.KeyValue {
    92  	counts := &types.Int64{Data: count}
    93  	countbytes := types.Encode(counts)
    94  	kv := &types.KeyValue{Key: types.CalcAddrTxsCountKey(addr), Value: countbytes}
    95  	return kv
    96  }
    97  
    98  func getAddrTxsCount(db dbm.KVDB, addr string) (int64, error) {
    99  	count := types.Int64{}
   100  	TxsCount, err := db.Get(types.CalcAddrTxsCountKey(addr))
   101  	if err != nil && err != types.ErrNotFound {
   102  		return 0, err
   103  	}
   104  	if len(TxsCount) == 0 {
   105  		return 0, nil
   106  	}
   107  	err = types.Decode(TxsCount, &count)
   108  	if err != nil {
   109  		return 0, err
   110  	}
   111  	return count.Data, nil
   112  }
   113  
   114  func setAddrTxsCount(db dbm.KVDB, addr string, count int64) error {
   115  	kv := getAddrTxsCountKV(addr, count)
   116  	return db.Set(kv.Key, kv.Value)
   117  }
   118  
   119  func updateAddrTxsCount(cfg *types.TuringchainConfig, cachedb dbm.KVDB, addr string, amount int64, isadd bool) (*types.KeyValue, error) {
   120  	//blockchaindb 数据库0版本不支持此功能
   121  	ver := cfg.GInt("dbversion")
   122  	if ver == 0 {
   123  		return nil, types.ErrNotFound
   124  	}
   125  	txscount, err := getAddrTxsCount(cachedb, addr)
   126  	if err != nil && err != types.ErrNotFound {
   127  		return nil, err
   128  	}
   129  	if isadd {
   130  		txscount += amount
   131  	} else {
   132  		txscount -= amount
   133  	}
   134  	err = setAddrTxsCount(cachedb, addr, txscount)
   135  	if err != nil {
   136  		return nil, err
   137  	}
   138  	//keyvalue
   139  	return getAddrTxsCountKV(addr, txscount), nil
   140  }