-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Tx permission contract improvement #8400
Changes from 1 commit
234e582
1b393c0
5927a72
985937a
555fba0
caf8b89
f47cab5
e0d5b42
2759b9a
22aa033
b9bfff2
94e2ea5
77727ef
d6d53ff
0256d2b
89b90b8
b7a0f3c
4619b30
d03dce4
bcd4ee9
7ce99cf
d0a903c
a08069c
b009127
9ca84a8
23a7dba
e53f33b
8088ebe
7e9466a
47103c4
a855ab9
18815ba
7df760c
3678106
a50672a
d838357
32129b6
ee49212
596200b
1b48864
c1a534b
eb9fcbe
e54666b
74f0482
c7a02e5
50a4643
c94f1be
f47c533
bde4bf5
f58dc73
e5832e4
e01028f
4ddf13a
066378b
314e279
22f691c
1f736e4
401bfe2
6046ca6
7d3f279
2f84096
387e037
44d3c90
f196dc4
e952e0f
63f2b4c
29acdb7
fe42ec9
a22ff24
eadd68b
5a2a756
51cddaa
816e68b
26c518b
ad3de86
f2eaafd
596dc1c
a5669ae
9748b53
152a5b8
455eead
7701b64
17e2a25
5c65cab
3ec9cde
03ea13d
83ded35
6d99bcb
ce5525f
b9b4fd9
5f28e2e
474468c
fcca7ad
11228b9
30393d9
eacfacc
345db57
7de2a13
1666cab
9bceb6d
ea74e51
1426d3b
5adf993
0ddc685
295d81b
555103c
d4683d1
e9c602b
54c0fed
d4cbedc
fdfbe7b
72edf75
c514180
3697a05
027504c
87d8359
c6f9c65
84e10d4
71b7bca
6c0307a
c832c4f
c9ea220
2a962df
0a5298f
4a35764
1f2b646
8f0997e
c048ed9
df39c50
710c06e
79046ed
769e9e9
413664b
423fa2f
666d8cf
30f86ae
f5e3d0a
f0adec1
267ee39
450c2f4
0b15818
f8f2345
47141bc
2a4035b
54cc717
e300472
f852531
cb75517
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
[ { "constant": true, "inputs": [], "name": "contractNameHash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractName", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractVersion", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "sender", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "allowedTxTypes", "outputs": [ { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" } ] | ||
[ { "constant": true, "inputs": [], "name": "contractNameHash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractName", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contractVersion", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "sender", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "allowedTxTypes", "outputs": [ { "name": "", "type": "uint32" }, { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,7 @@ | |
|
||
//! Smart contract based transaction filter. | ||
|
||
use ethereum_types::{H256, U256, Address}; | ||
use ethereum_types::{H256, Address}; | ||
use lru_cache::LruCache; | ||
|
||
use client::{BlockInfo, CallContract, BlockId}; | ||
|
@@ -44,7 +44,7 @@ pub struct TransactionFilter { | |
contract_deprecated: transact_acl_deprecated::TransactAclDeprecated, | ||
contract: transact_acl::TransactAcl, | ||
contract_address: Address, | ||
permission_cache: Mutex<LruCache<(H256, Address, Address, U256), u32>>, | ||
permission_cache: Mutex<LruCache<(H256, Address), u32>>, | ||
} | ||
|
||
impl TransactionFilter { | ||
|
@@ -74,7 +74,7 @@ impl TransactionFilter { | |
|
||
let sender = transaction.sender(); | ||
let value = transaction.value; | ||
let key = (*parent_hash, sender, to, value); | ||
let key = (*parent_hash, sender); | ||
|
||
if let Some(permissions) = cache.get_mut(&key) { | ||
return *permissions & tx_type != 0; | ||
|
@@ -83,24 +83,26 @@ impl TransactionFilter { | |
let contract_address = self.contract_address; | ||
|
||
// Check permissions in smart contracts | ||
let permissions = self.contract.functions() | ||
let (permissions, filter_only_sender) = self.contract.functions() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should keep caching for performance reasons, so I came up with an idea to have 2nd return value in the contract function, which will define whether filtering depends on to address and value in ether and if not, sender address will be cached which will increase performance. |
||
.allowed_tx_types() | ||
.call(sender, to, value, &|data| client.call_contract(BlockId::Hash(*parent_hash), contract_address, data)) | ||
.map(|p| p.low_u32()) | ||
.map(|(p, f)| (p.low_u32(), f)) | ||
.unwrap_or_else(|_e| { | ||
// If failed, first check deprecated contract | ||
trace!(target: "tx_filter", "Fallback to the deprecated version of tx permission contract"); | ||
self.contract_deprecated.functions() | ||
(self.contract_deprecated.functions() | ||
.allowed_tx_types() | ||
.call(sender, &|data| client.call_contract(BlockId::Hash(*parent_hash), contract_address, data)) | ||
.map(|p| p.low_u32()) | ||
.unwrap_or_else(|e| { | ||
error!(target: "tx_filter", "Error calling tx permissions contract: {:?}", e); | ||
tx_permissions::NONE | ||
}) | ||
}), true) | ||
}); | ||
|
||
cache.insert((*parent_hash, sender, to, value), permissions); | ||
println!("{:?}, {:?}", permissions, filter_only_sender); | ||
if filter_only_sender { | ||
cache.insert((*parent_hash, sender), permissions); | ||
} | ||
trace!(target: "tx_filter", | ||
"Given transaction data: sender: {:?} to: {:?} value: {}. Permissions required: {:X}, got: {:X}", | ||
sender, to, value, tx_type, permissions | ||
|
@@ -122,7 +124,7 @@ mod test { | |
use transaction::{Transaction, Action}; | ||
use tempdir::TempDir; | ||
|
||
/// Contract code: https://gist.github.com/VladLupashevskyi/a157d8162db85de67de522eeb7c8ee85 | ||
/// Contract code: https://gist.github.com/VladLupashevskyi/84f18eabb1e4afadf572cf92af3e7e7f | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"Caching" also seems a bit too harmless for this for me. We should emphasize that if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @tomusdrw I agree the explanation was too confusing. I updated gist where flag description is more clarified. |
||
#[test] | ||
fn transaction_filter() { | ||
let spec_data = r#" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are trying to move such string data into external resources and use in the code via: let spec_data = include_str!("../res/filename.json"); |
||
|
@@ -165,7 +167,7 @@ mod test { | |
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, | ||
"0000000000000000000000000000000000000005": { | ||
"balance": "1", | ||
"constructor": "608060405234801561001057600080fd5b506104c3806100206000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063469ab1e31461006757806375d0c0dc1461009a578063a0a8e4601461012a578063d4b03ee014610155575b600080fd5b34801561007357600080fd5b5061007c6101e2565b60405180826000191660001916815260200191505060405180910390f35b3480156100a657600080fd5b506100af610253565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100ef5780820151818401526020810190506100d4565b50505050905090810190601f16801561011c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013657600080fd5b5061013f610290565b6040518082815260200191505060405180910390f35b34801561016157600080fd5b506101c0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610299565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b60006101ec610253565b6040518082805190602001908083835b60208310151561022157805182526020820191506020810190506020830392506101fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b60606040805190810160405280601681526020017f54585f5045524d495353494f4e5f434f4e545241435400000000000000000000815250905090565b60006002905090565b6000737e5f4552091a69125d5dfcb7b8c2659029395bdf8473ffffffffffffffffffffffffffffffffffffffff1614156102d95763ffffffff9050610490565b732b5ad5c4795c026514f8317c7a215e218dccd6cf8473ffffffffffffffffffffffffffffffffffffffff1614156103175760026001179050610490565b736813eb9362372eef6200f3b1dbc3f819671cba698473ffffffffffffffffffffffffffffffffffffffff1614156103525760019050610490565b73e1ab8145f7e55dc933d51a18c793f901a3a0b2768473ffffffffffffffffffffffffffffffffffffffff1614801561038b5750600082145b1561039c5763ffffffff9050610490565b73e57bfe9f44b819898f47bf37e5af72a0783e11418473ffffffffffffffffffffffffffffffffffffffff161480156103fe575073d41c057fd1c78805aac12b0a94a405c0461a6fbb8373ffffffffffffffffffffffffffffffffffffffff16145b1561040c5760019050610490565b73d41c057fd1c78805aac12b0a94a405c0461a6fbb8473ffffffffffffffffffffffffffffffffffffffff1614801561046e575073e57bfe9f44b819898f47bf37e5af72a0783e11418373ffffffffffffffffffffffffffffffffffffffff16145b801561047a5750600082145b1561048b5763ffffffff9050610490565b600090505b93925050505600a165627a7a72305820ea35352692061875f689bdefc5e0d0ec86be33cdcf729bb0908f76b1da038b560029" | ||
"constructor": "608060405234801561001057600080fd5b506104eb806100206000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063469ab1e31461006757806375d0c0dc1461009a578063a0a8e4601461012a578063d4b03ee014610155575b600080fd5b34801561007357600080fd5b5061007c6101ed565b60405180826000191660001916815260200191505060405180910390f35b3480156100a657600080fd5b506100af61025e565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100ef5780820151818401526020810190506100d4565b50505050905090810190601f16801561011c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013657600080fd5b5061013f61029b565b6040518082815260200191505060405180910390f35b34801561016157600080fd5b506101c0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506102a4565b604051808363ffffffff1663ffffffff168152602001821515151581526020019250505060405180910390f35b60006101f761025e565b6040518082805190602001908083835b60208310151561022c5780518252602082019150602081019050602083039250610207565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b60606040805190810160405280601681526020017f54585f5045524d495353494f4e5f434f4e545241435400000000000000000000815250905090565b60006002905090565b600080737e5f4552091a69125d5dfcb7b8c2659029395bdf8573ffffffffffffffffffffffffffffffffffffffff1614156102e95763ffffffff6001915091506104b7565b732b5ad5c4795c026514f8317c7a215e218dccd6cf8573ffffffffffffffffffffffffffffffffffffffff16141561032b5760026001176001915091506104b7565b736813eb9362372eef6200f3b1dbc3f819671cba698573ffffffffffffffffffffffffffffffffffffffff16141561036957600180915091506104b7565b73e1ab8145f7e55dc933d51a18c793f901a3a0b2768573ffffffffffffffffffffffffffffffffffffffff161480156103a25750600083145b156103b75763ffffffff6000915091506104b7565b73e57bfe9f44b819898f47bf37e5af72a0783e11418573ffffffffffffffffffffffffffffffffffffffff16148015610419575073d41c057fd1c78805aac12b0a94a405c0461a6fbb8473ffffffffffffffffffffffffffffffffffffffff16145b1561042b5760016000915091506104b7565b73d41c057fd1c78805aac12b0a94a405c0461a6fbb8573ffffffffffffffffffffffffffffffffffffffff1614801561048d575073e57bfe9f44b819898f47bf37e5af72a0783e11418473ffffffffffffffffffffffffffffffffffffffff16145b80156104995750600083145b156104ae5763ffffffff6000915091506104b7565b60006001915091505b9350939150505600a165627a7a723058204982adea2aa10a7b8328ec3829472ee17c62a86957ef6737f2eb729b2c3faf910029" | ||
} | ||
} | ||
} | ||
|
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.
Can we mention here (or somewhere, where it's appropriate), that ABI of the contract with version=2 is used? Ideally is to add explicit check of the version in the code and force the next person, who will modify this code, to rely on contract's version. But perhaps at least some comment will be also helpful. PS. May be the fallback to the deprecated contract in case, when version is not retrieved, also will be looking more logically