Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Integration with zgp whitelist contract #4215

Merged
merged 7 commits into from Jan 22, 2017
Merged

Integration with zgp whitelist contract #4215

merged 7 commits into from Jan 22, 2017

Conversation

svyatonik
Copy link
Collaborator

Currently deployed on testnet: 0x4154A2671b7474883286a4493B97848f116395C6 - to be deployed on mainnet

closes #4132

@@ -614,12 +615,19 @@ impl Miner {
}
}).unwrap_or(default_origin);

// try to install zgp-checker before appending transactions
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There are 2 concerns about this:

  1. set_zero_gas_price_checker() must be called on Miner() initialization + on new blocks, but when Miner is initialized, Client (which is used by OnChainZeroGasPriceChecker::from_chain) is not yet ready => I placed it here
  2. as I understand, registry can be updated => address can be changed => possibly this condition if !transaction_queue.is_zero_gas_price_checker_set() is unnecessary. But I have checked how updater works:
    https://github.com/ethcore/parity/blob/master/updater/src/updater.rs#L242
    it works the same way. So maybe I'm wrong && it is ok to have single initialization.

Copy link
Contributor

Choose a reason for hiding this comment

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

it's highly unlikely that it will ever be changed once set. if it is, then it is not unreasonable to expect miners to restart in order to get the "correct" ZGP addresses. as such i don't see it as a huge problem.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's better to make sure you're using correct one, otherwise you can try to do some attacks on the syncing node (like feeding a chain with different ZGP contract, that will be re-organized later, but the ZGP contract stays the same)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@gavofyork @tomusdrw I personally agree with @tomusdrw , but I think maybe you both could reach a consensus in this question :)

@@ -39,14 +42,15 @@ function convertContract(name, json, prefs) {
return `${prefs._pub ? "pub " : ""}struct ${name} {
contract: ethabi::Contract,
address: util::Address,
do_call: Box<Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send ${prefs._sync ? "+ Sync " : ""}+ 'static>,
${prefs._explicit_do_call ? "" : `do_call: Box<Fn(util::Address, Vec<u8>) -> Result<Vec<u8>, String> + Send${prefs._sync ? " + Sync " : ""}+ 'static>,`}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The idea of _explicit_do_call is to pass do_call to contract' methods, instead of constructor. That's because Miner() don't have Arc, but &Client is passed to its methods => I can construct closure when calling a contract' method, but can't make a persistent closure.

let jsonabi = [{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"}],"payable":false,"type":"function"}];

let out = makeContractFile("Contract", jsonabi, {"_pub": true, "_": {"_client": {"string": true}, "_platform": {"string": true}}, "_sync": true});
// parse command line options
for (let i = 1; i < process.argv.length; ++i) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just added some command line arguments parsing, as it is seems more convenient to me.

if !client_id.starts_with("Parity/v") {
return false;
}
let ver: Vec<u32> = client_id[8..].split('.')
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Don't know if checking Parity' version is necessary - seems like current Parity version doesn't drop connection, event when zgp-transaction is received => maybe this is an optional check

tx.gas_price,
self.minimal_gas_price
);
if origin != TransactionOrigin::Local && tx.gas_price < self.minimal_gas_price {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As I understand from the code, local transactions were always accepted, even if gas_price was too low => added zgp-checks for non-local transactions only.

@svyatonik svyatonik added the A0-pleasereview 🤓 Pull request needs code review. label Jan 19, 2017
@keorn
Copy link

keorn commented Jan 19, 2017

So right now the only way to disable it is to change/remove the "registrar" from the Ethereum spec?


impl OnChainZeroGasPriceChecker {
/// Try to create instance, reading contract address from given chain.
pub fn from_chain(chain: &MiningBlockChainClient) -> Option<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

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

i would rename chain to client since it is, in fact, a Client, not a Blockchain.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done


impl ZeroGasPriceChecker for OnChainZeroGasPriceChecker {
/// Check if we can append zgp-transaction to the transaction queue
fn check(&self, chain: Option<&MiningBlockChainClient>, tx: &SignedTransaction) -> Result<bool, String> {
Copy link
Contributor

Choose a reason for hiding this comment

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

chain -> maybe_client?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done


chain.ok_or("Client not set".to_owned())
.and_then(|chain| {
let do_call = |a, d| chain.call_contract(a, d);
Copy link
Contributor

Choose a reason for hiding this comment

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

chain -> client

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@svyatonik
Copy link
Collaborator Author

@keorn Will update this PR with cli-option

@svyatonik svyatonik added A3-inprogress ⏳ Pull request is in progress. No review needed at this stage. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jan 19, 2017
Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Looks good, apart from grumble regarding MiningBlockChainClient

}

mod provider {
// Autogenerated from JSON contract definition using Rust contract convertor.
Copy link
Collaborator

Choose a reason for hiding this comment

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

IMHO we should turn the generator into macro sometime soon, it's producing A LOT of difficult to maintain code.

Copy link
Contributor

@rphmeier rphmeier Jan 19, 2017

Choose a reason for hiding this comment

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

yes, I have no idea why we're checking in autogenerated code. we should check in the contract ABIs and generate rust bindings at build time.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That would be ideal, as a compromise (short-term solution) a macro like this:

contract_client! {
  impl ContactName {
    abi = include!("./contract_name.json");

    fn set_owner=setOwner(new: &Address) as -> Result<(), String>;
    fn address=getAddress(who: &Address, field: &str) -> Result<Address, String>;
    fn revoke(who: &Address) -> Result<(), String>
  }
}

should be fairly easy to implement.

if !client_id.starts_with("Parity/v") {
return false;
}
let ver: Vec<u32> = client_id[8..].split('.')
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this would be cleaner:

let prefix = "Parity/v"
if !client_id.starts_with(prefix) {
  return false;
}
let ver: Vec<u32> = client_id[prefix.len()..].split('.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done

@@ -78,6 +79,7 @@ impl BanningTransactionQueue {
/// May reject transaction because of the banlist.
pub fn add_with_banlist<F, G>(
&mut self,
chain: Option<&MiningBlockChainClient>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

IMHO it would be better to avoid passing whole Client to transaction queue, I was trying to abstract out parts that are needed. Seems that with ZeroGasPriceChecker it could also play nicely (you get get rid of couple of Option and Box)

pub fn add_with_banlist<F, G, H>(
  &mut self,
  transaction: SignedTransaction,
  time: QueingInstant,
  account_details: &F,
  gas_estimator: &G,
  zgp_checker: &H,
) -> ... where
  F: Fn(&Address) -> AccountDetails,
  G: Fn(&SignedTransaction) -> U256,
  H: Fn(&Address) -> bool/Result<(), String>
{
}

In such case you don't need neither Option<&MiningBlockChainClient> nor Option<Box<GasPriceChecker>>

Since we already have 3 generic functions, probably it could be further refactored to a single trait returning all those details.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done, but maybe you have a better name for this trait (currently it is TransactionDetailsProvider) :)

@rphmeier rphmeier added the M4-core ⛓ Core client code / Rust. label Jan 19, 2017
impl ServiceTransactionChecker {
/// Try to create instance, reading contract address from given chain client.
pub fn update_from_chain_client(&self, client: &MiningBlockChainClient) {
let mut contract = self.contract.lock();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't it be easier to construct provider::Contract on each call without memoizing it?
You could probably just memoize the parsed ABI and then construct provider::Contract - in such case explicit_do_call would be unecessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, or perhaps a lazy_static! contract would suffice as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes - I can construct provider::Contract on each call, but I need to store contract_address here (or in Miner, but I want to avoid it) anyway => so the code will stay almost the same, except that I'll break provider::Contract initialization to 2 steps (parse ABI once, then pass result to the Contract::new). Not sure if that is better than it is now :) But feel free to insist, if you're sure this is required

@svyatonik svyatonik added A0-pleasereview 🤓 Pull request needs code review. and removed A3-inprogress ⏳ Pull request is in progress. No review needed at this stage. labels Jan 19, 2017
@coveralls
Copy link

Coverage Status

Changes Unknown when pulling 2b9462e on zgp_checker into ** on master**.

@gavofyork gavofyork added A8-looksgood 🦄 Pull request is reviewed well. A7-looksgoodcantmerge 🙄 Pull request is reviewed well, but cannot be merged due to conflicts. and removed A0-pleasereview 🤓 Pull request needs code review. A8-looksgood 🦄 Pull request is reviewed well. labels Jan 20, 2017
@gavofyork
Copy link
Contributor

conflicts

@svyatonik svyatonik added A0-pleasereview 🤓 Pull request needs code review. and removed A7-looksgoodcantmerge 🙄 Pull request is reviewed well, but cannot be merged due to conflicts. labels Jan 20, 2017
@gavofyork gavofyork added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jan 21, 2017
@gavofyork gavofyork merged commit 092e24b into master Jan 22, 2017
@gavofyork gavofyork deleted the zgp_checker branch January 22, 2017 15:15
@gavofyork
Copy link
Contributor

should be backported to 1.4 & 1.5

@gavofyork gavofyork added the B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. label Jan 24, 2017
arkpar pushed a commit that referenced this pull request Feb 3, 2017
* zgp-transactions checker

* polishing

* rename + refactor

* refuse-service-transactions cl option

* fixed tests compilation
gavofyork pushed a commit that referenced this pull request Feb 3, 2017
* v1.5.1

* Disable notifications (#4243)

* Fix wrong token handling (#4254)

* Fixing wrong token displayed

* Linting

* Revert filtering out

* Revert the revert

* Don't panic on uknown git commit hash (#4231)

* Additional logs for own transactions (#4278)

* Integration with zgp whitelist contract (#4215)

* zgp-transactions checker

* polishing

* rename + refactor

* refuse-service-transactions cl option

* fixed tests compilation

* Renaming signAndSendTransaction to sendTransaction (#4351)

* Fixed deadlock in external_url (#4354)

* Fixing web3 in console (#4382)

* Fixing estimate gas in case histogram is not available (#4387)

* Restarting fetch client every now and then (#4399)
@5chdn 5chdn mentioned this pull request Jul 5, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ZGP whitelist contract
6 participants