grin/api/src/handlers.rs
Yeastplume 1609b041b1
Master merge 2.0.0 (#2927)
* create 2.0.0 branch

* fix humansize version

* update grin.yml version

* PoW HardFork (#2866)

* allow version 2 blocks for next 6 months

* add cuckarood.rs with working tests

* switch cuckaroo to cuckarood at right heights

* reorder to reduce conditions

* remove _ prefix on used args; fix typo

* Make Valid Header Version dependant on ChainType

* Rustfmt

* Add tests, uncomment header v2

* Rustfmt

* Add FLOONET_FIRST_HARD_FORK height and simplify logic

* assume floonet stays closer to avg 60s block time

* move floonet hf forward by half a day

* update version in new block when previous no longer valid

* my next commit:-)

* micro optimization

* Support new Bulletproof rewind scheme (#2848)

* Update keychain with new rewind scheme

* Refactor: proof builder trait

* Update tests, cleanup

* rustfmt

* Move conversion of SwitchCommitmentType

* Add proof build trait to tx builders

* Cache hashes in proof builders

* Proof builder tests

* Add ViewKey struct

* Fix some warnings

* Zeroize proof builder secrets on drop

* Modify mine_block to use wallet V2 API (#2892)

* update mine_block to use V2 wallet API

* rustfmt

* Add version endpoint to node API, rename pool/push (#2897)

* add node version API, tweak pool/push parameter

* rustfmt

* Upate version api call (#2899)

* Update version number for next (potential) release

* zeroize: Upgrade to v0.9 (#2914)

* zeroize: Upgrade to v0.9

* missed Cargo.lock

* [PENDING APPROVAL] put phase outs of C32 and beyond on hold (#2714)

* put phase outs of C32 and beyond on hold

* update tests for phaseouts on hold

* Don't wait for p2p-server thread (#2917)

Currently p2p.stop() stops and wait for all peers to exit, that's
basically all we need. However we also run a TCP listener in this thread
which is blocked on `accept` most of the time. We do an attempt to stop
it but it would work only if we get an incoming connection during the
shutdown, which is a week guarantee.

This fix remove joining to p2p-server thread, it stops all peers and
makes an attempt to stop the listener.

Fixes [#2906]

* rustfmt
2019-06-27 09:19:17 +01:00

186 lines
6.3 KiB
Rust

// Copyright 2018 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
mod blocks_api;
mod chain_api;
mod peers_api;
mod pool_api;
mod server_api;
mod transactions_api;
mod utils;
mod version_api;
use self::blocks_api::BlockHandler;
use self::blocks_api::HeaderHandler;
use self::chain_api::ChainCompactHandler;
use self::chain_api::ChainHandler;
use self::chain_api::ChainValidationHandler;
use self::chain_api::OutputHandler;
use self::peers_api::PeerHandler;
use self::peers_api::PeersAllHandler;
use self::peers_api::PeersConnectedHandler;
use self::pool_api::PoolInfoHandler;
use self::pool_api::PoolPushHandler;
use self::server_api::IndexHandler;
use self::server_api::KernelDownloadHandler;
use self::server_api::StatusHandler;
use self::transactions_api::TxHashSetHandler;
use self::version_api::VersionHandler;
use crate::auth::{BasicAuthMiddleware, GRIN_BASIC_REALM};
use crate::chain;
use crate::p2p;
use crate::pool;
use crate::rest::*;
use crate::router::{Router, RouterError};
use crate::util;
use crate::util::RwLock;
use std::net::SocketAddr;
use std::sync::Arc;
/// Start all server HTTP handlers. Register all of them with Router
/// and runs the corresponding HTTP server.
///
/// Hyper currently has a bug that prevents clean shutdown. In order
/// to avoid having references kept forever by handlers, we only pass
/// weak references. Note that this likely means a crash if the handlers are
/// used after a server shutdown (which should normally never happen,
/// except during tests).
pub fn start_rest_apis(
addr: String,
chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: Arc<p2p::Peers>,
api_secret: Option<String>,
tls_config: Option<TLSConfig>,
) -> bool {
let mut apis = ApiServer::new();
let mut router = build_router(chain, tx_pool, peers).expect("unable to build API router");
if let Some(api_secret) = api_secret {
let api_basic_auth = format!("Basic {}", util::to_base64(&format!("grin:{}", api_secret)));
let basic_auth_middleware =
Arc::new(BasicAuthMiddleware::new(api_basic_auth, &GRIN_BASIC_REALM));
router.add_middleware(basic_auth_middleware);
}
info!("Starting HTTP API server at {}.", addr);
let socket_addr: SocketAddr = addr.parse().expect("unable to parse socket address");
let res = apis.start(socket_addr, router, tls_config);
match res {
Ok(_) => true,
Err(e) => {
error!("HTTP API server failed to start. Err: {}", e);
false
}
}
}
pub fn build_router(
chain: Arc<chain::Chain>,
tx_pool: Arc<RwLock<pool::TransactionPool>>,
peers: Arc<p2p::Peers>,
) -> Result<Router, RouterError> {
let route_list = vec![
"get blocks".to_string(),
"get headers".to_string(),
"get chain".to_string(),
"post chain/compact".to_string(),
"get chain/validate".to_string(),
"get chain/outputs/byids?id=xxx,yyy,zzz".to_string(),
"get chain/outputs/byheight?start_height=101&end_height=200".to_string(),
"get status".to_string(),
"get txhashset/roots".to_string(),
"get txhashset/lastoutputs?n=10".to_string(),
"get txhashset/lastrangeproofs".to_string(),
"get txhashset/lastkernels".to_string(),
"get txhashset/outputs?start_index=1&max=100".to_string(),
"get txhashset/merkleproof?n=1".to_string(),
"get pool".to_string(),
"post pool/push_tx".to_string(),
"post peers/a.b.c.d:p/ban".to_string(),
"post peers/a.b.c.d:p/unban".to_string(),
"get peers/all".to_string(),
"get peers/connected".to_string(),
"get peers/a.b.c.d".to_string(),
"get version".to_string(),
];
let index_handler = IndexHandler { list: route_list };
let output_handler = OutputHandler {
chain: Arc::downgrade(&chain),
};
let block_handler = BlockHandler {
chain: Arc::downgrade(&chain),
};
let header_handler = HeaderHandler {
chain: Arc::downgrade(&chain),
};
let chain_tip_handler = ChainHandler {
chain: Arc::downgrade(&chain),
};
let chain_compact_handler = ChainCompactHandler {
chain: Arc::downgrade(&chain),
};
let chain_validation_handler = ChainValidationHandler {
chain: Arc::downgrade(&chain),
};
let status_handler = StatusHandler {
chain: Arc::downgrade(&chain),
peers: Arc::downgrade(&peers),
};
let kernel_download_handler = KernelDownloadHandler {
peers: Arc::downgrade(&peers),
};
let txhashset_handler = TxHashSetHandler {
chain: Arc::downgrade(&chain),
};
let pool_info_handler = PoolInfoHandler {
tx_pool: Arc::downgrade(&tx_pool),
};
let pool_push_handler = PoolPushHandler {
tx_pool: Arc::downgrade(&tx_pool),
};
let peers_all_handler = PeersAllHandler {
peers: Arc::downgrade(&peers),
};
let peers_connected_handler = PeersConnectedHandler {
peers: Arc::downgrade(&peers),
};
let peer_handler = PeerHandler {
peers: Arc::downgrade(&peers),
};
let version_handler = VersionHandler {
chain: Arc::downgrade(&chain),
};
let mut router = Router::new();
router.add_route("/v1/", Arc::new(index_handler))?;
router.add_route("/v1/blocks/*", Arc::new(block_handler))?;
router.add_route("/v1/headers/*", Arc::new(header_handler))?;
router.add_route("/v1/chain", Arc::new(chain_tip_handler))?;
router.add_route("/v1/chain/outputs/*", Arc::new(output_handler))?;
router.add_route("/v1/chain/compact", Arc::new(chain_compact_handler))?;
router.add_route("/v1/chain/validate", Arc::new(chain_validation_handler))?;
router.add_route("/v1/txhashset/*", Arc::new(txhashset_handler))?;
router.add_route("/v1/status", Arc::new(status_handler))?;
router.add_route("/v1/kerneldownload", Arc::new(kernel_download_handler))?;
router.add_route("/v1/pool", Arc::new(pool_info_handler))?;
router.add_route("/v1/pool/push_tx", Arc::new(pool_push_handler))?;
router.add_route("/v1/peers/all", Arc::new(peers_all_handler))?;
router.add_route("/v1/peers/connected", Arc::new(peers_connected_handler))?;
router.add_route("/v1/peers/**", Arc::new(peer_handler))?;
router.add_route("/v1/version", Arc::new(version_handler))?;
Ok(router)
}