/
verify.go
160 lines (145 loc) · 5.13 KB
/
verify.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
package signer
import (
"encoding/json"
"math/big"
"sync"
"github.com/rs/zerolog"
"github.com/mantlenetworkio/mantle/l2geth/common/hexutil"
"github.com/mantlenetworkio/mantle/l2geth/core/types"
"github.com/mantlenetworkio/mantle/tss/common"
tdtypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
)
func (p *Processor) Verify() {
defer p.wg.Done()
logger := p.logger.With().Str("step", "verify event").Logger()
logger.Info().Msg("start to verify events ")
go func() {
defer func() {
logger.Info().Msg("exit verify event process")
}()
for {
select {
case <-p.stopChan:
return
case req := <-p.askRequestChan:
var askRequest common.SignStateRequest
var RpcResponse tdtypes.RPCResponse
if err := json.Unmarshal(req.Params, &askRequest); err != nil {
logger.Error().Msg("failed to unmarshal ask request")
RpcResponse = tdtypes.NewRPCErrorResponse(req.ID, 201, "failed to unmarshal ", err.Error())
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
continue
}
if askRequest.StartBlock == nil ||
askRequest.OffsetStartsAtIndex == nil ||
askRequest.StartBlock.Cmp(big.NewInt(0)) < 0 ||
askRequest.OffsetStartsAtIndex.Cmp(big.NewInt(0)) < 0 {
logger.Error().Msg("StartBlock and OffsetStartsAtIndex must not be nil or negative")
RpcResponse = tdtypes.NewRPCErrorResponse(req.ID, 201, "invalid askRequest", "StartBlock and OffsetStartsAtIndex must not be nil or negative")
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
return
}
var resId = req.ID
var size = len(askRequest.StateRoots)
logger.Info().Msgf("stateroots size %d ", size)
if len(askRequest.StateRoots) == 0 {
logger.Error().Msg("stateroots size is empty")
RpcResponse = tdtypes.NewRPCErrorResponse(req.ID, 201, "stateroots size is empty ", "do not need to sign")
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
continue
} else {
wg := &sync.WaitGroup{}
wg.Add(1)
result, err := p.verify(askRequest.StartBlock, size-1, askRequest.StateRoots[size-1], logger, wg)
if !result {
if err != nil {
logger.Error().Msgf("failed to verify block %s", err.Error())
RpcResponse = tdtypes.NewRPCErrorResponse(req.ID, 201, "get error when verify ", err.Error())
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
continue
}
} else {
hash, err := signMsgToHash(askRequest)
if err != nil {
logger.Err(err).Msg("failed to conv msg to hash")
RpcResponse = tdtypes.NewRPCErrorResponse(req.ID, 201, "failed to conv msg to hash", err.Error())
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
continue
} else {
hashStr := hexutil.Encode(hash)
p.UpdateWaitSignEvents(hashStr, askRequest)
}
}
askResponse := common.AskResponse{
Result: result,
}
RpcResponse = tdtypes.NewRPCSuccessResponse(resId, askResponse)
if err := p.wsClient.SendMsg(RpcResponse); err != nil {
logger.Error().Err(err).Msg("failed to send msg to manager")
}
}
}
}
}()
}
func (p *Processor) verify(start *big.Int, index int, stateRoot [32]byte, logger zerolog.Logger, wg *sync.WaitGroup) (bool, error) {
defer wg.Done()
offset := new(big.Int).SetInt64(int64(index))
blockNumber := offset.Add(offset, start)
logger.Info().Msgf("start to query block by number %d", blockNumber)
value, ok := p.GetVerify(blockNumber.String())
if ok {
if value {
return value, nil
}
}
var block *types.Block
var err error
for i := 0; i < 3; i++ {
block, err = p.l2Client.BlockByNumber(p.ctx, blockNumber)
if err == nil {
break
} else {
logger.Info().Msgf("retry to query block by number %d, times %d", blockNumber, i)
}
}
if err != nil {
logger.Err(err).Msgf("failed to get block by (%d) ", blockNumber)
return false, err
} else {
if hexutil.Encode(stateRoot[:]) != block.Root().String() {
logger.Info().Msgf("block number (%d) state root doesn't same, state root (%s) , block root (%s)", blockNumber, hexutil.Encode(stateRoot[:]), block.Root().String())
p.CacheVerify(blockNumber.String(), false)
return false, nil
} else {
logger.Info().Msgf("block number (%d) verify success", blockNumber)
p.CacheVerify(blockNumber.String(), true)
return true, nil
}
}
}
func (p *Processor) UpdateWaitSignEvents(uniqueId string, msg common.SignStateRequest) {
p.waitSignLock.Lock()
defer p.waitSignLock.Unlock()
p.waitSignMsgs[uniqueId] = msg
}
func (p *Processor) CacheVerify(key string, value bool) bool {
p.cacheVerifyLock.Lock()
defer p.cacheVerifyLock.Unlock()
return p.cacheVerify.Set(key, value)
}
func (p *Processor) GetVerify(key string) (bool, bool) {
p.cacheVerifyLock.RLock()
defer p.cacheVerifyLock.RUnlock()
return p.cacheVerify.Get(key)
}