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 }