@@ -14,6 +14,7 @@ import { useStateProvider } from '../state/StateProvider'
14
14
import { signatureToVRS , packSignatures } from '../utils/signatures'
15
15
import { getSuccessExecutionData } from '../utils/getFinalizationEvent'
16
16
import { TransactionReceipt } from 'web3-eth'
17
+ import { useValidatorContract } from '../hooks/useValidatorContract'
17
18
18
19
const ActionButton = styled . button `
19
20
color: var(--button-color);
@@ -32,20 +33,90 @@ interface ManualExecutionButtonParams {
32
33
setExecutionData : Function
33
34
signatureCollected : string [ ]
34
35
setPendingExecution : Function
36
+ setError : Function
35
37
}
36
38
37
39
export const ManualExecutionButton = ( {
38
40
safeExecutionAvailable,
39
41
messageData,
40
42
setExecutionData,
41
43
signatureCollected,
42
- setPendingExecution
44
+ setPendingExecution,
45
+ setError
43
46
} : ManualExecutionButtonParams ) => {
44
- const { foreign, setError } = useStateProvider ( )
47
+ const { foreign } = useStateProvider ( )
45
48
const { library, activate, account, active } = useWeb3React ( )
46
49
const [ manualExecution , setManualExecution ] = useState ( false )
47
50
const [ allowFailures , setAllowFailures ] = useState ( false )
48
- const notReady = ! foreign . bridgeContract || ! signatureCollected || ! signatureCollected . length
51
+ const [ ready , setReady ] = useState ( false )
52
+ const [ title , setTitle ] = useState ( 'Loading' )
53
+ const [ validSignatures , setValidSignatures ] = useState < string [ ] > ( [ ] )
54
+
55
+ const { requiredSignatures, validatorList } = useValidatorContract ( false , 'latest' )
56
+
57
+ useEffect (
58
+ ( ) => {
59
+ if (
60
+ ! foreign . bridgeContract ||
61
+ ! foreign . web3 ||
62
+ ! signatureCollected ||
63
+ ! signatureCollected . length ||
64
+ ! requiredSignatures ||
65
+ ! validatorList ||
66
+ ! validatorList . length
67
+ )
68
+ return
69
+
70
+ const signatures = [ ]
71
+ const remainingValidators = Object . fromEntries ( validatorList . map ( validator => [ validator , true ] ) )
72
+ for ( let i = 0 ; i < signatureCollected . length && signatures . length < requiredSignatures ; i ++ ) {
73
+ const { v, r, s } = signatureToVRS ( signatureCollected [ i ] )
74
+ const signer = foreign . web3 . eth . accounts . recover ( messageData , `0x${ v } ` , `0x${ r } ` , `0x${ s } ` )
75
+ if ( validatorList . includes ( signer ) ) {
76
+ delete remainingValidators [ signer ]
77
+ signatures . push ( signatureCollected [ i ] )
78
+ }
79
+ }
80
+
81
+ if ( signatures . length < requiredSignatures ) {
82
+ console . log ( 'On-chain collected signatures are not enough for message execution' )
83
+ const manualValidators = Object . keys ( remainingValidators )
84
+ const msgHash = foreign . web3 . utils . sha3 ( messageData ) !
85
+ for ( let i = 0 ; i < manualValidators . length && signatures . length < requiredSignatures ; i ++ ) {
86
+ try {
87
+ const overrideSignatures : {
88
+ [ key : string ] : string
89
+ } = require ( `../snapshots/signatures_${ manualValidators [ i ] } .json` )
90
+ if ( overrideSignatures [ msgHash ] ) {
91
+ console . log ( `Adding manual signature from ${ manualValidators [ i ] } ` )
92
+ signatures . push ( overrideSignatures [ msgHash ] )
93
+ } else {
94
+ console . log ( `No manual signature from ${ manualValidators [ i ] } was found` )
95
+ }
96
+ } catch ( e ) {
97
+ console . log ( `Signatures overrides are not present for ${ manualValidators [ i ] } ` )
98
+ }
99
+ }
100
+ }
101
+
102
+ if ( signatures . length >= requiredSignatures ) {
103
+ setValidSignatures ( signatures )
104
+ setTitle ( 'Execute' )
105
+ setReady ( true )
106
+ } else {
107
+ setTitle ( 'Unavailable' )
108
+ }
109
+ } ,
110
+ [
111
+ foreign . bridgeContract ,
112
+ foreign . web3 ,
113
+ signatureCollected ,
114
+ validatorList ,
115
+ requiredSignatures ,
116
+ messageData ,
117
+ setValidSignatures
118
+ ]
119
+ )
49
120
50
121
useEffect (
51
122
( ) => {
@@ -73,9 +144,9 @@ export const ManualExecutionButton = ({
73
144
return
74
145
}
75
146
76
- if ( ! library || ! foreign . bridgeContract || ! signatureCollected || ! signatureCollected . length ) return
147
+ if ( ! library || ! foreign . bridgeContract || ! foreign . web3 || ! validSignatures || ! validSignatures . length ) return
77
148
78
- const signatures = packSignatures ( signatureCollected . map ( signatureToVRS ) )
149
+ const signatures = packSignatures ( validSignatures . map ( signatureToVRS ) )
79
150
const messageId = messageData . slice ( 0 , 66 )
80
151
const bridge = foreign . bridgeContract
81
152
const executeMethod =
@@ -140,19 +211,20 @@ export const ManualExecutionButton = ({
140
211
foreign . bridgeContract ,
141
212
setError ,
142
213
messageData ,
143
- signatureCollected ,
144
214
setExecutionData ,
145
215
setPendingExecution ,
146
216
safeExecutionAvailable ,
147
- allowFailures
217
+ allowFailures ,
218
+ foreign . web3 ,
219
+ validSignatures
148
220
]
149
221
)
150
222
151
223
return (
152
224
< div >
153
225
< div className = "is-center" >
154
- < ActionButton disabled = { notReady } className = "button outline" onClick = { ( ) => setManualExecution ( true ) } >
155
- Execute
226
+ < ActionButton disabled = { ! ready } className = "button outline" onClick = { ( ) => setManualExecution ( true ) } >
227
+ { title }
156
228
</ ActionButton >
157
229
</ div >
158
230
{ safeExecutionAvailable && (
0 commit comments