Skip to content

Commit

Permalink
merged in work from other branches:
Browse files Browse the repository at this point in the history
mine and stake routes work;
WS disconnect seems to be fixed with reconnect.auto: true;
wobbly checkbox fixed;
migrated to production - DO NOT make more contract changes before demo- gas is super tight!
const environment back to context-dependent;
all tested on mainnet
  • Loading branch information
morkeltry committed Jul 13, 2020
2 parents 7dfb147 + ac5ea4c commit 44d5201
Show file tree
Hide file tree
Showing 19 changed files with 33,147 additions and 33,472 deletions.
114 changes: 92 additions & 22 deletions app/src/Web3/accessChain.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,31 @@ if (envVars.length>2)



// const environment = 'production';
const environment = process.env.REACT_APP_NODE_ENV || process.env.NODE_ENV || 'production';
const environment = 'production';
// const environment = process.env.REACT_APP_NODE_ENV || process.env.NODE_ENV || 'production';
let authWeb3Type = environment==='production' ? 'browser' : 'local';

let providerUrl = {
development : 'ws://127.0.0.1:8545',
production: 'wss://mainnet-ws.thundercore.com/:8545'
}[environment];
let wsRetries=2;
// NB there is a lot of pastarific async (mixed with sync) code to attempt to detect and fix WS disconnects.
// If options.reconnect.auto works, may as well remove it bit by bit...
let wsRetries=2; //for manual retry
const wsProviderOptions = {
timeout: 4800000,
reconnect: {
auto: true,
delay: 750,
maxAttempts: 5,
onTimeout: false
}
}


let web3;
let authWeb3;
let wsProvider = new Web3.providers.WebsocketProvider(providerUrl,{timeout: 4800000} );
let wsProvider = new Web3.providers.WebsocketProvider(providerUrl, wsProviderOptions );
let wpUp = true;
let awaitAccess;

Expand All @@ -38,27 +51,28 @@ if (environment!== 'production'){
if (providerUrl.indexOf('127.0.0.1')>-1)
web3.isReliable = true;

const reconnect = (wp = wsProvider)=> {
console.log(`${time(d)}.${ms(d)}: Attempting to reconnect...`);
const reconnect = (wp = wsProvider)=> new Promise( (resolve, reject)=> {
console.log(`${exactTime()}: Attempting to reconnect...`);
wp = new Web3.providers.WebsocketProvider(providerUrl);

wp.on('connect', function () {
let d=new Date();
console.log(`${time(d)}.${ms(d)}: WSS Reconnected`);
console.log(`${exactTime()}: WSS Reconnected`);
web3.setProvider(wp);
wpUp = true;
resolve();
});
web3.setProvider(wp);
wpUp = true;
}
})

wsProvider.on('error', e => {
wpUp = false;
console.log(`${time(d)}.${ms(d)}: WS Error`, e);
console.log(`${exactTime()}: WS Error`, e);
reconnect(wsProvider);
// retry!
});
wsProvider.on('end', e => {
wpUp = false;
console.log(`${time(new Date())}.${ms(d)}: WS closed`);
console.log(`${exactTime()}: WS closed`);
reconnect(wsProvider);
});

Expand Down Expand Up @@ -98,17 +112,23 @@ let OWN_ADDRESS;

let d;
const time = d=> d.toTimeString().slice(0,8);
const ms = d=> (d%1000).toFixed(0);
const ms = d=> (d%1000).toFixed(0).padStart(3,'0');
const exactTime = ()=> `${time(new Date())}.${ms(new Date())}`

const wpIsUp = async (timeout)=> new Promise ((resolve, reject)=> {
// this is caching, or forming a closure or some other confusing thing!!
console.log(`${exactTime()}: web3 is ${ wpUp ? 'UP' : 'DOWN' }`);
if (wpUp)
resolve();
let t2;
let t = setInterval(()=>{
if (wpUp) {
clearTimeout(t2);
clearInterval(t);
console.log(`${exactTime()}: web3 is UP - wpIsUp will resolve`);
resolve();
} else {
console.log(`${exactTime()}: web3 is DOWN`);
}
}, 199);
if (timeout)
Expand Down Expand Up @@ -253,6 +273,25 @@ export function getImplementationAddress() {
}


export const runConstructorManuallyFfs = ()=> {
callTransaction('getInitialisedValues')
.then(response=> {
console.log('constructor should have set', response);
if (!Object.values(response).some(el=> el || Number(el))) {
console.log(`but apparently it didn't`);
sendTransaction('fakeConstructor')
.then(response=> {
console.log('constructor values were set manually.');
})
.catch(e => {
console.log('could not manually set constructor values:', e);
})
}
})
.catch(e=>{ console.log('FFS:',e); })
}


export async function updateKnownPolls( options ) {
// returns the list of events that are in the latest version of the contract
// const { setWatchers } = options;
Expand Down Expand Up @@ -306,7 +345,7 @@ export async function getImplementationEvents(options={ setWatchers:false }, eve
const withErrLog = (eventName, actionFn)=> {
const errFn= actionFn.errFn || (err=>{
if (err.message!=='CONNECTION ERROR: The connection closed unexpectedly')
console.log(time(new Date()),err, err.stack);
console.log(time(new Date()), 'event error', err, err.stack);
});
return (err, result)=>
err
Expand Down Expand Up @@ -510,19 +549,47 @@ export function callTransaction(functionName, args) {
if (!web3.isReliable)
await wpIsUp();
attempt = IMPLEMENTATION_INSTANCE.methods[functionName](...rv)
.call({from: OWN_ADDRESS});
attempt
.call({from: OWN_ADDRESS})
// 1. .call returns its own Promise which needs a catch
// 2. Why even break up attempt here- doesn;t seem to make sense!
// attempt
.then(result => {
console.log(functionName,': chain responded:', result);
unpackRVs (result, outputs);
i=0;
resolve(result);
})
.catch(err=> {
if (err.message==='CONNECTION ERROR: The connection closed unexpectedly')
reconnect();
console.log(`${functionName} fail:`,err); reject(err)
});
// did the error message change??
// (this bit untested as probably now redundant)
if (err.message==='(call) CONNECTION ERROR: The connection closed unexpectedly') {
wpUp = false;
console.log('attempting reconnect');
reconnect()
// wpIsUp.then didn;t work..
.then(()=> {
console.log('WS seems to have reconnected. Retrying...');
callTransaction(functionName, args)
.then( resolve )
.catch(e=> { console.log('oh, this is bad', e); });
})
.catch(e2=> {
console.log('multiple errors :(');
console.log(`First: `, err);
console.log(`then: `, e2);
reject(err)
reject(e2)
}) ;

}
console.log(`${exactTime()}: (call) ${functionName} fail:`,err);
console.log(`${ wpUp ? 'but WS had not fired "end" or "error"' : 'natch - as wp is down' }`);
// wpIsUp just for the LOGZZ
wpIsUp()
// pass through notification of the error (catch in React and render in state)
reject(err)
}) ;

}
})
.catch(err => {
Expand All @@ -543,6 +610,7 @@ export function sendTransaction(functionName, args) {
.then(({rv, outputs}) => {
let gas;
console.log(`Send to (${functionName}):`,IMPLEMENTATION_INSTANCE_FOR_SEND);
console.log(args);
console.log('got back from checkFF ready to send:',{rv, outputs});
IMPLEMENTATION_INSTANCE_FOR_SEND.methods[functionName](...rv)
.estimateGas({from: OWN_ADDRESS})
Expand All @@ -561,10 +629,12 @@ export function sendTransaction(functionName, args) {
resolve(result);
})
})
.catch(e=>{console.log(`${functionName} fail:`,e); reject(e)});
.catch( e=> {
console.log(`(send) ${functionName} fail:`,e);
});
})
.catch(err => {
console.log(`Bad format for ${functionName}`, err);
console.log(`(send) Bad format for ${functionName}`, err);
reject(err);
});
});
Expand Down
92 changes: 57 additions & 35 deletions app/src/components/LiveTing.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import "../App.scss";
import './checkInView.css';

import { connectToWeb3, refetchOwnAddress, getDeets, setOwnAddyforAuthWeb3,
getImplementationFunctions, getImplementationEvents,
getImplementationFunctions, getImplementationEvents, runConstructorManuallyFfs,
callTransaction, sendTransaction, getFromStorage,
myAccounts, } from "../Web3/accessChain";
import { getPrice } from "../helpers/priceFeed.js";
Expand Down Expand Up @@ -77,6 +77,11 @@ const LiveEvent = props => {
= [setCheckInClosesRaw, setVenueCostRaw, setVenuePotRaw, setYouPaidForVenueRaw, setRepStakedRaw, setRepEverStakedRaw, setRepWasRaw, setRepMultiplierRaw, setMaxRepRaw, setUpdatedRepRaw ]
.map(setter=> response=> { setter(Number(response)); });

const setOwnProofFromArray= proofsList=> {
const newProof = stakers.map((staker, idx)=> stakers.indexOf(staker) > -1 );
setOwnProof(newProof);
}

// TODO: setRepWas setInfoModalResult

clearInterval(t)
Expand Down Expand Up @@ -178,29 +183,17 @@ const LiveEvent = props => {
.then(response=>{
console.log('getproofsAsAddresses', response);
setProofs(response.filter(proof=>proof.length));
if (response.some(proof=>proof.includes(freshAddy)))
setCheckedIn(true);

// INCORRECT!!

// if (response.some(proof=>proof.includes(freshAddy)))
// setCheckedIn(true);
})
.catch(err=>{console.log(err);});

// Instead get proof(OwnAddy) from storage
callTransaction('getStakerAddresses', {_poll : pollUrl})
.then(response=>{
console.log('getStakerAddresses', response);
setStakers (response);
if (response.indexOf(freshAddy || ownAddress)>-1)
callTransaction('getStakersProof', {_poll : pollUrl, _staker : freshAddy || ownAddress })
.then(response=>{
console.log('expecting array representing own proof:',response);
if (response.length) {
setOwnProof(response);
setCheckedIn(true);
} else
setCheckedIn(false);
})
.catch(err=>{console.log(err);});
})
.catch(err=>{console.log(err);});
fetchAndUpdateStakerStatus(freshAddy);

callTransaction('totalRepStaked', {_poll : pollUrl, _staker : freshAddy || ownAddress })
.then(response=>{
console.log('totalRepStaked', response);
Expand Down Expand Up @@ -294,10 +287,32 @@ const LiveEvent = props => {
.catch(err=>{ console.log(`getRep failed`, err); reject(err); });
})


// ----------------------- chain access functions (other than those above for useEffect)

const fetchAndUpdateStakerStatus = (freshAddy)=> {
callTransaction('getStakerAddresses', {_poll : pollUrl})
.then(response=>{
console.log('getStakerAddresses', response);
setStakers (response);
if (response.indexOf(freshAddy || ownAddress)>-1)
callTransaction('getStakersProof', {_poll : pollUrl, _staker : freshAddy || ownAddress })
.then(response=>{
console.log('expecting array representing own proof:',response);
if (response.length) {
setOwnProofFromArray(response);
setCheckedIn(true);
} else
setCheckedIn(false);
})
.catch(err=>{console.log(err);});
})
.catch(err=>{console.log(err);});
}


const addProofBitByBit = async (args)=>{
// NB data structure changed - this should still work as structure of _newProof should be the same by the time we reach here
const remaining = args._newProof.splice(1);
return await sendTransaction('addProof', args) // ownAddy is hack for demo - validator will be more complex than this!
.then(async (resp)=>{
Expand All @@ -314,21 +329,27 @@ const LiveEvent = props => {
// NB proof (_newProof) will eventually be more complex than an addy;
// NB _impersonatedStaker is a temporary expedient for testing which will be removed
const submitProof = ()=> {
const _newProof = ownProof;
const _impersonatedStaker = ownAddress;
const args = {_poll: pollUrl, _newProof: ownProof, _impersonatedStaker } ;
const args = {
_poll: pollUrl,
_newProof: ownProof.map((tick, stakerNo)=> tick && stakers[stakerNo] ).filter(Boolean),
_impersonatedStaker
};
let getproofsAsAddressesIsOK = true;

setModalView(null);
console.log('\n\n\n\n\n\n\n');
if (args._newProof.length)
console.log('args OK', args, ownProof, args._newProof)
else
console.log('args NOT OK:', args, ownProof, args._newProof);
sendTransaction('addProof', args) // ownAddy is hack for demo - validator will be more complex than this!
.then(response=>{
if (getproofsAsAddressesIsOK)
callTransaction('getproofsAsAddresses', {_poll : pollUrl})
.then(response=>{
console.log('setting CheckedIn');
fetchAndUpdateStakerStatus(ownAddress);
setProofs(response.filter(proof=>proof.length));
// setProofs(response); // Cheekily accept the uninitilised empty proofs ;)
setCheckedIn(true);
})
.catch(err=>{ console.log(`getproofsAsAddresses failed`, err); });
})
Expand All @@ -339,10 +360,9 @@ const LiveEvent = props => {
if (getproofsAsAddressesIsOK)
callTransaction('getproofsAsAddresses', {_poll : pollUrl})
.then(response=>{
console.log('setting CheckedIn');
fetchAndUpdateStakerStatus(ownAddress);
setProofs(response.filter(proof=>proof.length));
// setProofs(response); // Cheekily accept the uninitilised empty proofs ;)
setCheckedIn(true);
})
.catch(err=>{ console.log(`getproofsAsAddresses failed`, err); });
})
Expand All @@ -355,7 +375,7 @@ const LiveEvent = props => {
sendTransaction('closeProofsWindow', { poll : pollUrl })
.then(response=>{
console.log('closeProofsWindow',response);
callTransaction('isProofsWindowClosed', { poll : pollUrl })
callTransaction('isProofsWindowClosed', { _poll : pollUrl })
.then(response=>{
console.log('isProofsWindowClosed: pollData(pollUrl)',response);
setCheckInIsClosed(response);
Expand Down Expand Up @@ -420,6 +440,7 @@ const LiveEvent = props => {
console.log(`\n\nsetOwnAddy(${addressObj.OWN_ADDRESS})\nis done. New ownAddy=${ownAddress} \n`);
// setContractAddy(addressObj.IMPLEMENTATION_ADDRESS);
setAvailableAccounts(addressObj.availableAccounts);
runConstructorManuallyFfs();
return addressObj.OWN_ADDRESS
}).then(addy=> {
fetchAndUpdate(addy);
Expand All @@ -428,6 +449,8 @@ const LiveEvent = props => {
// we should be catching here: 105: reject (new Error('no web3 provider'));
console.log('\n\nconnectToWeb3 FAILED\n\n');
console.log('fetchAndUpdate gave',err);

// VV this is incorrect - that error can also signify WS disconnected
if (err.message==='connection not open on send()' || err instanceof ConnectionError)
setNoChainError(true)
else {
Expand Down Expand Up @@ -702,14 +725,13 @@ return(<>
<input
type="checkbox"
className="modal-checkbox w20r"
selected= { ownProof[stakerNo] }
checked= { ownProof[stakerNo] }
onClick= {()=>{
let choice = !ownProof[stakerNo];
if (choice)
setOwnProof (ownProof.concat(stakers[stakerNo]))
else
setOwnProof( ownProof.map((tick,idx)=> (idx===stakerNo ? choice : tick) && stakers[stakerNo] ).filter(Boolean) );
console.log('Setting:', choice, stakerNo, stakers[stakerNo], ownProof, ownProof.concat(stakers[stakerNo]), ownProof.map((tick,idx)=> (idx===stakerNo ? choice : tick) && stakers[stakerNo] ) );
const newProof = [...ownProof];
newProof[stakerNo]= !ownProof[stakerNo];
console.log('Current:', ownProof[stakerNo] );
setOwnProof( newProof );
console.log('Setting:', newProof[stakerNo] );
}}
/>
</div>
Expand Down
Loading

0 comments on commit 44d5201

Please sign in to comment.