/
cert.go
168 lines (147 loc) · 4.14 KB
/
cert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/cert/authority"
ct "github.com/33cn/plugin/plugin/dapp/cert/types"
)
var clog = log.New("module", "execs.cert")
var driverName = ct.CertX
// Init 初始化
func Init(name string, cfg *types.Chain33Config, sub []byte) {
driverName = name
var scfg ct.Authority
if sub != nil {
types.MustDecode(sub, &scfg)
}
err := authority.Author.Init(&scfg)
if err != nil {
clog.Error("error to initialize authority", "error", err)
return
}
drivers.Register(cfg, driverName, newCert, cfg.GetDappFork(driverName, "Enable"))
InitExecType()
}
// InitExecType Init Exec Type
func InitExecType() {
ety := types.LoadExecutorType(driverName)
ety.InitFuncList(types.ListMethod(&Cert{}))
}
// GetName 获取cert执行器名
func GetName() string {
return newCert().GetName()
}
// Cert cert执行器
type Cert struct {
drivers.DriverBase
}
func newCert() drivers.Driver {
c := &Cert{}
c.SetChild(c)
c.SetIsFree(true)
c.SetExecutorType(types.LoadExecutorType(driverName))
return c
}
// GetDriverName 获取cert执行器名
func (c *Cert) GetDriverName() string {
return driverName
}
// CheckTx cert执行器tx证书校验
func (c *Cert) CheckTx(tx *types.Transaction, index int) error {
// 基类检查
err := c.DriverBase.CheckTx(tx, index)
if err != nil {
return err
}
// auth模块关闭则返回
if !authority.IsAuthEnable {
clog.Error("Authority is not available. Please check the authority config or authority initialize error logs.")
return ct.ErrInitializeAuthority
}
// 重启
if authority.Author.HistoryCertCache.CurHeight == -1 {
err := c.loadHistoryByPrefix()
if err != nil {
return err
}
}
// 当前区块<上次证书变更区块,cert回滚
if c.GetHeight() <= authority.Author.HistoryCertCache.CurHeight {
err := c.loadHistoryByPrefix()
if err != nil {
return err
}
}
// 当前区块>上次变更下一区块,下一区块不为-1,即非最新证书变更记录,用于cert回滚时判断是否到了下一变更记录
nxtHeight := authority.Author.HistoryCertCache.NxtHeight
if nxtHeight != -1 && c.GetHeight() > nxtHeight {
err := c.loadHistoryByHeight()
if err != nil {
return err
}
}
// auth校验
return authority.Author.Validate(tx.GetSignature())
}
/**
根据前缀查找证书变更记录,cert回滚、重启、同步用到
*/
func (c *Cert) loadHistoryByPrefix() error {
parm := &types.LocalDBList{
Prefix: []byte("LODB-cert-"),
Key: nil,
Direction: 0,
Count: 0,
}
result, err := c.DriverBase.GetAPI().LocalList(parm)
if err != nil {
return err
}
// 数据库没有变更记录,说明创世区块开始cert校验
if len(result.Values) == 0 {
authority.Author.HistoryCertCache.CurHeight = 0
return nil
}
// 寻找当前高度使用的证书区间
var historyData types.HistoryCertStore
for _, v := range result.Values {
err := types.Decode(v, &historyData)
if err != nil {
return err
}
if historyData.CurHeigth < c.GetHeight() && (historyData.NxtHeight >= c.GetHeight() || historyData.NxtHeight == -1) {
return authority.Author.ReloadCert(&historyData)
}
}
return ct.ErrGetHistoryCertData
}
/**
根据具体高度查找变更记录,cert回滚用到
*/
func (c *Cert) loadHistoryByHeight() error {
key := calcCertHeightKey(c.GetHeight())
parm := &types.LocalDBGet{Keys: [][]byte{key}}
result, err := c.DriverBase.GetAPI().LocalGet(parm)
if err != nil {
return err
}
var historyData types.HistoryCertStore
for _, v := range result.Values {
err := types.Decode(v, &historyData)
if err != nil {
return err
}
if historyData.CurHeigth < c.GetHeight() && historyData.NxtHeight >= c.GetHeight() {
return authority.Author.ReloadCert(&historyData)
}
}
return ct.ErrGetHistoryCertData
}
// CheckReceiptExecOk return true to check if receipt ty is ok
func (c *Cert) CheckReceiptExecOk() bool {
return true
}