openethereum/ethcore/node-filter/src/lib.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

145 lines
5.2 KiB
Rust
Raw Normal View History

// Copyright 2015-2019 Parity Technologies (UK) Ltd.
// This file is part of Parity Ethereum.
2017-08-29 14:38:01 +02:00
// Parity Ethereum is free software: you can redistribute it and/or modify
2017-08-29 14:38:01 +02:00
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity Ethereum is distributed in the hope that it will be useful,
2017-08-29 14:38:01 +02:00
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
2017-08-29 14:38:01 +02:00
//! Smart contract based node filter.
extern crate ethabi;
2017-08-29 14:38:01 +02:00
extern crate ethcore;
extern crate ethcore_network as network;
extern crate ethcore_network_devp2p as devp2p;
extern crate ethereum_types;
extern crate lru_cache;
extern crate parking_lot;
#[macro_use]
extern crate ethabi_derive;
#[macro_use]
extern crate ethabi_contract;
#[cfg(test)]
extern crate ethcore_io as io;
#[cfg(test)]
extern crate kvdb_memorydb;
#[cfg(test)]
extern crate tempdir;
#[macro_use]
extern crate log;
2017-08-29 14:38:01 +02:00
use std::sync::Weak;
use devp2p::NodeId;
use ethabi::FunctionOutputDecoder;
use ethcore::client::{BlockChainClient, BlockId};
use ethereum_types::{Address, H256};
2017-08-29 14:38:01 +02:00
use network::{ConnectionDirection, ConnectionFilter};
use_contract!(peer_set, "res/peer_set.json");
2017-08-29 14:38:01 +02:00
/// Connection filter that uses a contract to manage permissions.
pub struct NodeFilter {
2020-07-29 10:36:15 +02:00
client: Weak<dyn BlockChainClient>,
2017-08-29 14:38:01 +02:00
contract_address: Address,
}
impl NodeFilter {
/// Create a new instance. Accepts a contract address.
2020-07-29 10:36:15 +02:00
pub fn new(client: Weak<dyn BlockChainClient>, contract_address: Address) -> NodeFilter {
2017-08-29 14:38:01 +02:00
NodeFilter {
client,
contract_address,
2017-08-29 14:38:01 +02:00
}
}
}
impl ConnectionFilter for NodeFilter {
fn connection_allowed(
&self,
own_id: &NodeId,
connecting_id: &NodeId,
_direction: ConnectionDirection,
) -> bool {
let client = match self.client.upgrade() {
Some(client) => client,
None => return false,
};
2020-08-05 06:08:03 +02:00
let address = self.contract_address;
let own_low = H256::from_slice(&own_id[0..32]);
let own_high = H256::from_slice(&own_id[32..64]);
let id_low = H256::from_slice(&connecting_id[0..32]);
let id_high = H256::from_slice(&connecting_id[32..64]);
2020-08-05 06:08:03 +02:00
let (data, decoder) =
peer_set::functions::connection_allowed::call(own_low, own_high, id_low, id_high);
let allowed = client
.call_contract(BlockId::Latest, address, data)
.and_then(|value| decoder.decode(&value).map_err(|e| e.to_string()))
.unwrap_or_else(|e| {
debug!("Error callling peer set contract: {:?}", e);
false
});
2020-08-05 06:08:03 +02:00
2017-08-29 14:38:01 +02:00
allowed
}
}
#[cfg(test)]
mod test {
use super::NodeFilter;
use ethcore::{
client::{BlockChainClient, Client, ClientConfig},
miner::Miner,
spec::Spec,
test_helpers,
2020-08-05 06:08:03 +02:00
};
use io::IoChannel;
2017-08-29 14:38:01 +02:00
use network::{ConnectionDirection, ConnectionFilter, NodeId};
use std::sync::{Arc, Weak};
use tempdir::TempDir;
2020-08-05 06:08:03 +02:00
2017-08-29 14:38:01 +02:00
/// Contract code: https://gist.github.com/arkpar/467dbcc73cbb85b0997a7a10ffa0695f
#[test]
fn node_filter() {
let contract_addr = "0000000000000000000000000000000000000005".into();
2017-08-29 14:38:01 +02:00
let data = include_bytes!("../res/node_filter.json");
let tempdir = TempDir::new("").unwrap();
let spec = Spec::load(&tempdir.path(), &data[..]).unwrap();
let client_db = test_helpers::new_db();
2020-08-05 06:08:03 +02:00
2017-08-29 14:38:01 +02:00
let client = Client::new(
ClientConfig::default(),
&spec,
client_db,
New Transaction Queue implementation (#8074) * Implementation of Verifier, Scoring and Ready. * Queue in progress. * TransactionPool. * Prepare for txpool release. * Miner refactor [WiP] * WiP reworking miner. * Make it compile. * Add some docs. * Split blockchain access to a separate file. * Work on miner API. * Fix ethcore tests. * Refactor miner interface for sealing/work packages. * Implement next nonce. * RPC compiles. * Implement couple of missing methdods for RPC. * Add transaction queue listeners. * Compiles! * Clean-up and parallelize. * Get rid of RefCell in header. * Revert "Get rid of RefCell in header." This reverts commit 0f2424c9b7319a786e1565ea2a8a6d801a21b4fb. * Override Sync requirement. * Fix status display. * Unify logging. * Extract some cheap checks. * Measurements and optimizations. * Fix scoring bug, heap size of bug and add cache * Disable tx queueing and parallel verification. * Make ethcore and ethcore-miner compile again. * Make RPC compile again. * Bunch of txpool tests. * Migrate transaction queue tests. * Nonce Cap * Nonce cap cache and tests. * Remove stale future transactions from the queue. * Optimize scoring and write some tests. * Simple penalization. * Clean up and support for different scoring algorithms. * Add CLI parameters for the new queue. * Remove banning queue. * Disable debug build. * Change per_sender limit to be 1% instead of 5% * Avoid cloning when propagating transactions. * Remove old todo. * Post-review fixes. * Fix miner options default. * Implement back ready transactions for light client. * Get rid of from_pending_block * Pass rejection reason. * Add more details to drop. * Rollback heap size of. * Avoid cloning hashes when propagating and include more details on rejection. * Fix tests. * Introduce nonces cache. * Remove uneccessary hashes allocation. * Lower the mem limit. * Re-enable parallel verification. * Add miner log. Don't check the type if not below min_gas_price. * Add more traces, fix disabling miner. * Fix creating pending blocks twice on AuRa authorities. * Fix tests. * re-use pending blocks in AuRa * Use reseal_min_period to prevent too frequent update_sealing. * Fix log to contain hash not sender. * Optimize local transactions. * Fix aura tests. * Update locks comments. * Get rid of unsafe Sync impl. * Review fixes. * Remove excessive matches. * Fix compilation errors. * Use new pool in private transactions. * Fix private-tx test. * Fix secret store tests. * Actually use gas_floor_target * Fix config tests. * Fix pool tests. * Address grumbles.
2018-04-13 17:34:27 +02:00
Arc::new(Miner::new_for_tests(&spec, None)),
2017-08-29 14:38:01 +02:00
IoChannel::disconnected(),
)
.unwrap();
let filter = NodeFilter::new(
2020-07-29 10:36:15 +02:00
Arc::downgrade(&client) as Weak<dyn BlockChainClient>,
2017-08-29 14:38:01 +02:00
contract_addr,
);
let self1: NodeId = "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002".into();
let self2: NodeId = "00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003".into();
let node1: NodeId = "00000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000012".into();
let node2: NodeId = "00000000000000000000000000000000000000000000000000000000000000210000000000000000000000000000000000000000000000000000000000000022".into();
let nodex: NodeId = "77000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
2020-08-05 06:08:03 +02:00
2017-08-29 14:38:01 +02:00
assert!(filter.connection_allowed(&self1, &node1, ConnectionDirection::Inbound));
assert!(filter.connection_allowed(&self1, &nodex, ConnectionDirection::Inbound));
assert!(filter.connection_allowed(&self2, &node1, ConnectionDirection::Inbound));
assert!(filter.connection_allowed(&self2, &node2, ConnectionDirection::Inbound));
}
}