@@ -14,6 +14,7 @@ import { useStateProvider } from '../state/StateProvider'
1414import { signatureToVRS , packSignatures } from '../utils/signatures'
1515import { getSuccessExecutionData } from '../utils/getFinalizationEvent'
1616import { TransactionReceipt } from 'web3-eth'
17+ import { useValidatorContract } from '../hooks/useValidatorContract'
1718
1819const ActionButton = styled . button `
1920 color: var(--button-color);
@@ -32,20 +33,90 @@ interface ManualExecutionButtonParams {
3233 setExecutionData : Function
3334 signatureCollected : string [ ]
3435 setPendingExecution : Function
36+ setError : Function
3537}
3638
3739export const ManualExecutionButton = ( {
3840 safeExecutionAvailable,
3941 messageData,
4042 setExecutionData,
4143 signatureCollected,
42- setPendingExecution
44+ setPendingExecution,
45+ setError
4346} : ManualExecutionButtonParams ) => {
44- const { foreign, setError } = useStateProvider ( )
47+ const { foreign } = useStateProvider ( )
4548 const { library, activate, account, active } = useWeb3React ( )
4649 const [ manualExecution , setManualExecution ] = useState ( false )
4750 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+ )
49120
50121 useEffect (
51122 ( ) => {
@@ -73,9 +144,9 @@ export const ManualExecutionButton = ({
73144 return
74145 }
75146
76- if ( ! library || ! foreign . bridgeContract || ! signatureCollected || ! signatureCollected . length ) return
147+ if ( ! library || ! foreign . bridgeContract || ! foreign . web3 || ! validSignatures || ! validSignatures . length ) return
77148
78- const signatures = packSignatures ( signatureCollected . map ( signatureToVRS ) )
149+ const signatures = packSignatures ( validSignatures . map ( signatureToVRS ) )
79150 const messageId = messageData . slice ( 0 , 66 )
80151 const bridge = foreign . bridgeContract
81152 const executeMethod =
@@ -140,19 +211,20 @@ export const ManualExecutionButton = ({
140211 foreign . bridgeContract ,
141212 setError ,
142213 messageData ,
143- signatureCollected ,
144214 setExecutionData ,
145215 setPendingExecution ,
146216 safeExecutionAvailable ,
147- allowFailures
217+ allowFailures ,
218+ foreign . web3 ,
219+ validSignatures
148220 ]
149221 )
150222
151223 return (
152224 < div >
153225 < 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 }
156228 </ ActionButton >
157229 </ div >
158230 { safeExecutionAvailable && (
0 commit comments