Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding a restriction to proposers and challenger 🤌 #550

Merged
merged 14 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 4 additions & 18 deletions common-files/utils/web3.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import Web3 from 'web3';
import config from 'config';
import logger from './logger.mjs';

const { INFURA_PROJECT_SECRET } = process.env;

export default {
connection() {
if (!this.web3) this.connect();
Expand All @@ -20,22 +18,10 @@ export default {

logger.info('Blockchain Connecting ...');

let provider;
if (config.USE_INFURA) {
if (!INFURA_PROJECT_SECRET) throw Error('env INFURA_PROJECT_SECRET not set');

provider = new Web3.providers.WebsocketProvider(config.BLOCKCHAIN_URL, {
...config.WEB3_PROVIDER_OPTIONS,
headers: {
authorization: `Basic ${Buffer.from(`:${INFURA_PROJECT_SECRET}`).toString('base64')}`,
},
});
} else {
provider = new Web3.providers.WebsocketProvider(
config.BLOCKCHAIN_URL,
config.WEB3_PROVIDER_OPTIONS,
);
}
const provider = new Web3.providers.WebsocketProvider(
config.BLOCKCHAIN_URL,
config.WEB3_PROVIDER_OPTIONS,
);

provider.on('error', err => logger.error(`web3 error: ${err}`));
provider.on('connect', () => logger.info('Blockchain Connected ...'));
Expand Down
102 changes: 52 additions & 50 deletions config/default.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-nested-ternary */
const { DOMAIN_NAME = '' } = process.env;

module.exports = {
Expand Down Expand Up @@ -32,7 +33,6 @@ module.exports = {
BLOCKCHAIN_URL:
process.env.BLOCKCHAIN_URL ||
`ws://${process.env.BLOCKCHAIN_WS_HOST}:${process.env.BLOCKCHAIN_PORT}`,
USE_INFURA: process.env.USE_INFURA === 'true',
ETH_PRIVATE_KEY: process.env.ETH_PRIVATE_KEY, // owner's/deployer's private key
ETH_ADDRESS: process.env.ETH_ADDRESS,
OPTIMIST_HOST: process.env.OPTIMIST_HOST || 'optimist',
Expand All @@ -41,43 +41,6 @@ module.exports = {
// Define Urls and Url format (http/ws vs https/wss, with vs without port) depending on whether a DOMAIN_NAME has been defined.
// In production and staging environements, we require https/wss and no port, as traffic will be routed to the correct service
// given a URL.
optimistBaseUrl:
DOMAIN_NAME === ''
? `http://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_HTTP_PORT}`
: `https://${process.env.OPTIMIST_HTTP_HOST}`,
optimistWsUrl:
DOMAIN_NAME === ''
? `ws://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_WS_PORT}`
: `wss://${process.env.OPTIMIST_HOST}`,
web3WsUrl:
DOMAIN_NAME === ''
? `ws://${process.env.BLOCKCHAIN_WS_HOST}:${process.env.BLOCKCHAIN_PORT}`
: `wss://${process.env.BLOCKCHAIN_WS_HOST}`,
userEthereumSigningKey:
process.env.USER_ETHEREUM_SIGNING_KEY ||
'0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e', // if changed, change associated userEthereumAddresses
userAddress: process.env.USER_ADDRESS,
UserEthereumAddresses: process.env.USER_ETHEREUM_ADDRESSES
? process.env.USER_ETHEREUM_ADDRESSES.split(',')
: [
'0x9c8b2276d490141ae1440da660e470e7c0349c63',
// '0x4ca4902a6f456b488947074ad4140317c7e21996', // 0xb0fa8745bd6e77a67ec6a27e701971d659937140cc3159d9f85210da3444eb45
// '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9', // 0xd42905d0582c476c4b74757be6576ec323d715a0c7dcff231b6348b7ab0190eb
],
zkpMnemonic:
process.env.ZKP_MNEMONIC ||
'hurt labor ketchup seven scan swap dirt brown brush path goat together',
proposerEthereumSigningKey:
process.env.PROPOSER_ETHEREUM_SIGNING_KEY ||
'0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69d',
user1Pkd: process.env.RECIPIENT_PKD || [
'0x193a37cd7973373aceae05d133f3d69ab6e7ef2f4321461173871ec7611244e2',
'0x27234a8721e73c9aa160154ee63d2470101fc5fd841221eeb675a91ec2d66e78',
],
user2Pkd: process.env.RECIPIENT_PKD || [
'0x105651c0c5bb97582b3270e0f5a07ca81410ffd1920e86697efddaec03dccef8',
'0x1ac3b61ecba1448e697b23d37efe290fb86554b2f905aaca3a6df59805eca366',
],
WEB3_OPTIONS: {
gas: process.env.GAS || 8000000,
gasPrice: process.env.GAS_PRICE || '20000000000',
Expand Down Expand Up @@ -170,12 +133,28 @@ module.exports = {
localhost: {
name: 'Localhost',
chainId: 4378921,
clientApiUrl: 'http://localhost:8080',
optimistApiUrl: 'http://localhost:8081',
optimistWsUrl: 'ws://localhost:8082',
clientApiUrl: process.env.CLIENT_HOST
? DOMAIN_NAME === ''
? `http://${process.env.CLIENT_HOST}:${process.env.CLIENT_PORT}`
: `https://${process.env.CLIENT_HOST}`
: 'http://localhost:8080',
optimistApiUrl: process.env.OPTIMIST_HOST
? DOMAIN_NAME === ''
? `http://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_PORT}`
: `https://${process.env.OPTIMIST_HOST}`
: 'http://localhost:8081',
optimistWsUrl: process.env.OPTIMIST_HOST
? DOMAIN_NAME === ''
? `ws://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_WS_PORT}`
: `wss://${process.env.OPTIMIST_HOST}`
: 'ws://localhost:8082',
adversarialOptimistApiUrl: 'http://localhost:8088',
adversarialOptimistWsUrl: 'ws://localhost:8089',
web3WsUrl: 'ws://localhost:8546',
web3WsUrl: process.env.BLOCKCHAIN_WS_HOST
? DOMAIN_NAME === ''
? `ws://${process.env.BLOCKCHAIN_WS_HOST}:${process.env.BLOCKCHAIN_PORT}`
: `wss://${process.env.BLOCKCHAIN_WS_HOST}`
: 'ws://localhost:8546',
},
},
TEST_OPTIONS: {
Expand All @@ -189,11 +168,11 @@ module.exports = {
// this is the etherum private key for accounts[0]
privateKey: '0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e',
gas: 10000000,
gasCosts: 15000000000000000,
gasCosts: 80000000000000000,
fee: 1,
BLOCK_STAKE: 1, // 1 wei
bond: 10, // 10 wei
txPerBlock: 2,
txPerBlock: process.env.TRANSACTIONS_PER_BLOCK || 2,
signingKeys: {
walletTest: '0xd42905d0582c476c4b74757be6576ec323d715a0c7dcff231b6348b7ab0190eb',
user1: '0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e',
Expand All @@ -204,6 +183,19 @@ module.exports = {
challenger: '0xd42905d0582c476c4b74757be6576ec323d715a0c7dcff231b6348b7ab0190eb',
liquidityProvider: '0xfbc1ee1c7332e2e5a76a99956f50b3ba2639aff73d56477e877ef8390c41e0c6',
},
addresses: {
walletTest: '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9',
user1: '0x9C8B2276D490141Ae1440Da660E470E7C0349C63',
user2: '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9',
proposer1: '0xfeEDA3882Dd44aeb394caEEf941386E7ed88e0E0',
proposer2: '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9',
proposer3: '0x4789FD18D5d71982045d85d5218493fD69F55AC4',
challenger: '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9',
liquidityProvider: '0x4789FD18D5d71982045d85d5218493fD69F55AC4',
},
pkds: {
user1: '0x1ac3b61ecba1448e697b23d37efe290fb86554b2f905aaca3a6df59805eca366',
},
mnemonics: {
user1: 'trip differ bamboo bundle bonus luxury strike mad merry muffin nose auction',
user2: 'control series album tribe category saddle prosper enforce moon eternal talk fame',
Expand All @@ -215,13 +207,23 @@ module.exports = {
erc20default: 2000,
},
},
RESTRICTIONS: [
{
name: 'MockERC20',
address: '0xB5Acbe9a0F1F8B98F3fC04471F7fE5d2c222cB44',
amount: 200,
RESTRICTIONS: {
signingKeys: {
bootProposerKey: '0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69d',
bootChallengerKey: '0xd42905d0582c476c4b74757be6576ec323d715a0c7dcff231b6348b7ab0190eb',
},
],
addresses: {
bootProposer: '0xfeEDA3882Dd44aeb394caEEf941386E7ed88e0E0',
bootChallenger: '0xfCb059A4dB5B961d3e48706fAC91a55Bad0035C9',
},
tokens: [
{
name: 'MockERC20',
address: '0xB5Acbe9a0F1F8B98F3fC04471F7fE5d2c222cB44',
amount: 200,
},
],
},

// for Browser use
proposerUrl:
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.ganache.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ services:
image: trufflesuite/ganache-cli:v6.12.1
ports:
- 8546:8546
command:
command:
ganache-cli --accounts=10 --defaultBalanceEther=1000 --gasLimit=0x3B9ACA00 --deterministic -i 4378921 -p 8546 -b 1
--account="0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69e,10000000000000000000000"
--account="0x4775af73d6dc84a0ae76f8726bda4b9ecf187c377229cb39e1afa7a18236a69d,10000000000000000000000"
Expand Down
43 changes: 0 additions & 43 deletions docker-compose.infura.yml

This file was deleted.

2 changes: 1 addition & 1 deletion nightfall-client/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ mongod --dbpath /app/mongodb/ --fork --logpath /var/log/mongodb/mongod.log --bin
while ! nc -z localhost 27017; do sleep 3; done
echo 'mongodb started'

if [ -z "${USE_INFURA}" ] && [ -z "${USE_ROPSTEN_NODE}" ];
if [ -z "${USE_ROPSTEN_NODE}" ];
then
# wait until there's a blockchain client up
while ! nc -z ${BLOCKCHAIN_WS_HOST} ${BLOCKCHAIN_PORT}; do sleep 3; done
Expand Down
20 changes: 10 additions & 10 deletions nightfall-deployer/contracts/Challenges.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ contract Challenges is Stateful, Key_Registry, Config {
uint256 blockNumberL2,
Transaction[] memory transactions,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
// check if the block hash is correct and the block hash exists for the block and prior block
state.isBlockReal(priorBlockL2, priorBlockTransactions, blockNumberL2 - 1);
Expand Down Expand Up @@ -73,7 +73,7 @@ contract Challenges is Stateful, Key_Registry, Config {
uint256 blockNumberL2,
Transaction[] memory transactions,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
// check if the block hash is correct and the block hash exists for the block and prior block
state.isBlockReal(priorBlockL2, priorBlockTransactions, blockNumberL2 - 1);
Expand Down Expand Up @@ -104,7 +104,7 @@ contract Challenges is Stateful, Key_Registry, Config {
uint256 transactionIndex1,
uint256 transactionIndex2,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
// first, check we have real, in-train, contiguous blocks
state.isBlockReal(block1, transactions1, block1NumberL2);
Expand Down Expand Up @@ -132,7 +132,7 @@ contract Challenges is Stateful, Key_Registry, Config {
Transaction[] memory transactions,
uint256 transactionIndex,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
state.isBlockReal(blockL2, transactions, blockNumberL2);
ChallengesUtil.libChallengeTransactionType(transactions[transactionIndex]);
Expand All @@ -148,7 +148,7 @@ contract Challenges is Stateful, Key_Registry, Config {
uint256 transactionIndex,
uint256[8] memory uncompressedProof,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
state.isBlockReal(blockL2, transactions, blockNumberL2);
// now we need to check that the proof is correct
Expand Down Expand Up @@ -176,7 +176,7 @@ contract Challenges is Stateful, Key_Registry, Config {
Transaction[] memory transactionsOfblockL2ContainingHistoricRoot,
uint256[8] memory uncompressedProof,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
state.isBlockReal(blockL2, transactions, blockNumberL2);
state.isBlockReal(
Expand Down Expand Up @@ -215,7 +215,7 @@ contract Challenges is Stateful, Key_Registry, Config {
Transaction[] memory transactionsOfblockL2ContainingHistoricRoot2,
uint256[8] memory uncompressedProof,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
state.isBlockReal(blockL2, transactions, blockNumberL2);
state.isBlockReal(
Expand Down Expand Up @@ -266,7 +266,7 @@ contract Challenges is Stateful, Key_Registry, Config {
uint256 transactionIndex2,
uint256 nullifierIndex2,
bytes32 salt
) public {
) public onlyBootChallenger {
checkCommit(msg.data);
ChallengesUtil.libChallengeNullifier(
txs1[transactionIndex1],
Expand Down Expand Up @@ -297,7 +297,7 @@ contract Challenges is Stateful, Key_Registry, Config {
Transaction[] memory transactions,
uint256 transactionIndex,
bytes32 salt
) external {
) external onlyBootChallenger {
checkCommit(msg.data);
state.isBlockReal(blockL2, transactions, blockNumberL2);
if (
Expand Down Expand Up @@ -367,7 +367,7 @@ contract Challenges is Stateful, Key_Registry, Config {
}

//To prevent frontrunning, we need to commit to a challenge before we send it
function commitToChallenge(bytes32 commitHash) external {
function commitToChallenge(bytes32 commitHash) external onlyBootChallenger {
require(committers[commitHash] == address(0), 'Hash is already committed to');
committers[commitHash] = msg.sender;
emit CommittedToChallenge(commitHash, msg.sender);
Expand Down
31 changes: 31 additions & 0 deletions nightfall-deployer/contracts/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,43 @@ contract Config is Ownable {
uint256 constant COOLING_OFF_PERIOD = 1 weeks;
bytes32 constant ZERO = bytes32(0);

address bootProposer;
address bootChallenger;
mapping(address => uint256) erc20limit;

function initialize() public virtual override initializer {
Ownable.initialize();
}

// restricting proposers
modifier onlyBootProposer() {
require(msg.sender == bootProposer, 'You are not the boot proposer');
_;
}

function setBootProposer(address proposer) external onlyOwner {
Copy link
Contributor

@Westlad Westlad Mar 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this approach we can only have one challenger and one proposer address, unless I've misunderstood. Whilst, initially we want to restrict who can propose and who can challenge, I can image that quite early on we would want to add additional proposers and challengers, if only for resilience (e.g. to guard against a proposer running out of money or getting banned). We can of course upgrade the contract to make such a change but would it be good to start with a mapping of allowed proposers and challengers, so that the owner can add and remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I agree with you, but I think the next step will be to just remove all this, as we're definitely only gonna have one proposer and challenger. But I'll tag @ChaitanyaKonda to decide if it's worth to make it a mapping or if we can leave it as just one proposer and challenger

bootProposer = proposer;
}

function getBootProposer() external view returns (address) {
return bootProposer;
}

// restricting challengers
modifier onlyBootChallenger() {
require(msg.sender == bootChallenger, 'You are not the boot challenger');
_;
}

function setBootChallenger(address challenger) external onlyOwner {
bootChallenger = challenger;
}

function getBootChallenger() external view returns (address) {
return bootChallenger;
}

// restricting tokens
function getRestriction(address tokenAddr) public view returns (uint256) {
return erc20limit[tokenAddr];
}
Expand Down
Loading