-
Notifications
You must be signed in to change notification settings - Fork 12
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
Add new version of transactionPermissionContract with gasprice support #60
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, assuming that it compiles. That said, we really really really need a test suite and CI.
ethcore/src/tx_filter.rs
Outdated
@@ -109,6 +111,17 @@ impl TransactionFilter { | |||
(tx_permissions::NONE, true) | |||
}) | |||
}, | |||
0xfffffffffffffffe => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you split it into 16-bit half-words for readability like so: 0xffff_ffff_ffff_fffe
? Also, why is it not 3, for example? If you wanted an arbitrary difficult to come up with version number, you could have something more random looking. Maybe hexspeak? Like 0xdeadbeefbaadf00d
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention was to make it easier to pull from upstream. If parity introduces a new version of permissions contract, they will most likely pick number 3
. So I chose a number from the opposite end of the scale (0xfffffffffffffffe == u64(-2)
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean something like
let data_decoder = match version_u64 {
2 => Some(transact_acl::functions::allowed_tx_types::call(sender, to, value)),
-1 => Some(transact_acl_gas_price::functions::allowed_tx_types::call(sender, to, value, gas_price)),
_ => None,
};
if let Some(data, decoder) = data_decoder {
client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) ... // etc
} else {
(tx_permissions::NONE, true)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to have the same problem, this time in form
error[E0308]: match arms have incompatible types
...
expected struct `tx_filter::transact_acl::functions::allowed_tx_types::Decoder`, found struct `tx_filter::transact_acl_gas_price::functions::allowed_tx_types::Decoder`
I tried a couple of other variants but they all don't work because of incompatible types.
Sorry if I'm missing something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. There is a problem with the dynamic type of the [decoder function] (https://github.com/paritytech/ethabi/blob/c300678e0fa8b42bc3d54d876f2e85f37b9a4983/derive/src/function.rs#L166) derived by use_contract
. Even though Decoder
types in both branches implement FunctionOutputDecoder<Output = (U256, bool)>
, the latter is a trait. Returning trait objects from match
would require heap allocation because the compiler doesn't allow returning unwrapped trait objects.
It's better to return the result of the decoder function of type (U256, bool)
from match
. This is closer to what you already implemented.
0xfffffffffffffffe => { | ||
trace!(target: "tx_filter", "Using filter with gas price"); | ||
let (data, decoder) = transact_acl_gas_price::functions::allowed_tx_types::call(sender, to, value, gas_price); | ||
client.call_contract(BlockId::Hash(*parent_hash), contract_address, data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is too much repetition with the 2
branch. You might get (data, decoder)
first by matching on the version, and then call client.call_contract
of that pair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please expand on this, I'm not sure how to do it. So, to do this, I'd need to put client.call_contract(...)
into either a new function or a new closure, right? In both cases I need to specify type for decoder
, but their types are different in different branches of match
(for v2 it's tx_filter::transact_acl::functions::allowed_tx_types::Decoder
and for the new version it's tx_filter::transact_acl_gas_price::functions::allowed_tx_types::Decoder
). Should I declare a new trait to do this? If so, wouldn't that be an overkill?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above. I replied in a different thread by mistake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some repetition could be avoided in the match clauses.
The |
Should I set the version number to |
I think so. It should be the same as the version in |
I fixed some of the duplication. |
61c0c23
to
a62d812
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Closes #57
Add new possible
transactionPermissionContract.contractVersion() == 0xfffffffffffffffe
that supports filtering txs based on gas price by calling contract's methodallowedTxTypes
with the following signatureThe meaning of the returned value is the same as in the current version (
2
) oftransactionPermissionContract
:uint32
part contains permission bits described in wiki;bool
part tells if returned value can be cached based solely onsender
(in our case this should probably befalse
).