<commit_before>use libc;

use glib_sys;
use glib::translate::*;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;
use std::str::FromStr;

use attributes::Attribute;

pub struct PropertyBag<'a>(HashMap<&'a CStr, (Attribute, &'a CStr)>);

pub struct OwnedPropertyBag(HashMap<CString, (Attribute, CString)>);

pub struct PropertyBagIter<'a>(PropertyBagCStrIter<'a>);

pub struct PropertyBagCStrIter<'a>(hash_map::Iter<'a, &'a CStr, (Attribute, &'a CStr)>);

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    // We silently drop unknown attributes.  New attributes should be added in
                    // build.rs.
                    if let Ok(attr) = Attribute::from_str(key_str.to_str().unwrap()) {
                        map.insert(key_str, (attr, val_str));
                    }
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, &(a, ref v)) in &owned.0 {
            map.insert(k.deref(), (a, v.deref()));
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, (Attribute, CString)>::new();

        for (k, &(a, v)) in &self.0 {
            map.insert((*k).to_owned(), (a, (*v).to_owned()));
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter(self.cstr_iter())
    }

    pub fn cstr_iter(&self) -> PropertyBagCStrIter {
        PropertyBagCStrIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, Attribute, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, a, v)| (k.to_str().unwrap(), a, v.to_str().unwrap()))
    }
}

impl<'a> Iterator for PropertyBagCStrIter<'a> {
    type Item = (&'a CStr, Attribute, &'a CStr);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, &(a, v))| (*k, a, v))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_begin(pbag: *const PropertyBag) -> *mut PropertyBagCStrIter {
    assert!(!pbag.is_null());
    let pbag = unsafe { &*pbag };

    Box::into_raw(Box::new(pbag.cstr_iter()))
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_next(iter: *mut PropertyBagCStrIter,
                                          out_key: *mut *const libc::c_char,
                                          out_attr: *mut Attribute,
                                          out_value: *mut *const libc::c_char)
                                          -> glib_sys::gboolean
{
    assert!(!iter.is_null());
    let iter = unsafe { &mut *iter };

    if let Some((key, attr, val)) = iter.next() {
        unsafe {
            *out_key = key.as_ptr();
            *out_attr = attr;
            *out_value = val.as_ptr();
        }
        true.to_glib()
    } else {
        unsafe {
            *out_key = ptr::null();
            *out_value = ptr::null();
        }
        false.to_glib()
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_end(iter: *mut PropertyBagCStrIter) {
    assert!(!iter.is_null());

    unsafe { Box::from_raw(iter) };
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::ffi::CString;
    use std::mem;

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_iters() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        for (k, a, v) in pbag.iter() {
            if k == "rx" {
                assert!(a == Attribute::Rx);
                assert!(v == "1");
                had_rx = true;
            } else if k == "ry" {
                assert!(a == Attribute::Ry);
                assert!(v == "2");
                had_ry = true;
            } else {
                unreachable!();
            }
        }

        assert!(had_rx);
        assert!(had_ry);
    }

    #[test]
    fn property_bag_can_iterate_from_c() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        let iter = rsvg_property_bag_iter_begin(&pbag as *const PropertyBag);

        let mut key = unsafe { mem::uninitialized() };
        let mut att = unsafe { mem::uninitialized() };
        let mut val = unsafe { mem::uninitialized() };

        while from_glib(rsvg_property_bag_iter_next(iter,
                                                    &mut key as *mut _,
                                                    &mut att as *mut _,
                                                    &mut val as *mut _)) {
            let k = unsafe { CStr::from_ptr(key).to_str().unwrap() };
            let v = unsafe { CStr::from_ptr(val).to_str().unwrap() };

            if k == "rx" {
                assert!(att == Attribute::Rx);
                assert!(v == "1");
                had_rx = true;
            } else if k == "ry" {
                assert!(att == Attribute::Ry);
                assert!(v == "2");
                had_ry = true;
            }
        }

        rsvg_property_bag_iter_end(iter);

        assert!(had_rx);
        assert!(had_ry);
    }
}
<commit_msg>PropertyBag: Don't do redundant UTF-8 validation when generating Rust strings<commit_after>use libc;

use glib_sys;
use glib::translate::*;

use std::collections::HashMap;
use std::collections::hash_map;
use std::ffi::{CStr, CString};
use std::ops::Deref;
use std::ptr;
use std::str::{self, FromStr};

use attributes::Attribute;

pub struct PropertyBag<'a>(HashMap<&'a CStr, (Attribute, &'a CStr)>);

pub struct OwnedPropertyBag(HashMap<CString, (Attribute, CString)>);

pub struct PropertyBagIter<'a>(PropertyBagCStrIter<'a>);

pub struct PropertyBagCStrIter<'a>(hash_map::Iter<'a, &'a CStr, (Attribute, &'a CStr)>);

trait Utf8CStrToStr {
    fn to_str_utf8(&self) -> &str;
}

impl Utf8CStrToStr for CStr {
    fn to_str_utf8(&self) -> &str {
        // We can *only* do this when the CStr comes from a C string that was validated
        // as UTF-8 on the C side of things.  In our case, the C strings from libxml2 and
        // are valid UTF-8.
        unsafe { str::from_utf8_unchecked(self.to_bytes()) }
    }
}

impl<'a> PropertyBag<'a> {
    pub unsafe fn new_from_key_value_pairs(pairs: *const *const libc::c_char) -> PropertyBag<'a> {
        let mut map = HashMap::new();

        if !pairs.is_null() {
            let mut i = 0;
            loop {
                let key = *pairs.offset(i);
                if !key.is_null() {
                    let val = *pairs.offset(i + 1);
                    assert!(!val.is_null());

                    let key_str = CStr::from_ptr(key);
                    let val_str = CStr::from_ptr(val);

                    // We silently drop unknown attributes.  New attributes should be added in
                    // build.rs.
                    if let Ok(attr) = Attribute::from_str(key_str.to_str_utf8()) {
                        map.insert(key_str, (attr, val_str));
                    }
                } else {
                    break;
                }

                i += 2;
            }
        }

        PropertyBag(map)
    }

    pub fn from_owned(owned: &OwnedPropertyBag) -> PropertyBag {
        let mut map = HashMap::new();

        for (k, &(a, ref v)) in &owned.0 {
            map.insert(k.deref(), (a, v.deref()));
        }

        PropertyBag(map)
    }

    pub fn to_owned(&self) -> OwnedPropertyBag {
        let mut map = HashMap::<CString, (Attribute, CString)>::new();

        for (k, &(a, v)) in &self.0 {
            map.insert((*k).to_owned(), (a, (*v).to_owned()));
        }

        OwnedPropertyBag(map)
    }

    pub fn ffi(&self) -> *const PropertyBag {
        self as *const PropertyBag
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    pub fn iter(&self) -> PropertyBagIter {
        PropertyBagIter(self.cstr_iter())
    }

    pub fn cstr_iter(&self) -> PropertyBagCStrIter {
        PropertyBagCStrIter(self.0.iter())
    }
}

impl<'a> Iterator for PropertyBagIter<'a> {
    type Item = (&'a str, Attribute, &'a str);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, a, v)| (k.to_str_utf8(), a, v.to_str_utf8()))
    }
}

impl<'a> Iterator for PropertyBagCStrIter<'a> {
    type Item = (&'a CStr, Attribute, &'a CStr);

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next().map(|(k, &(a, v))| (*k, a, v))
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_new<'a>(atts: *const *const libc::c_char) -> *const PropertyBag<'a> {
    let pbag = unsafe { PropertyBag::new_from_key_value_pairs(atts) };
    Box::into_raw(Box::new(pbag))
}

#[no_mangle]
pub extern fn rsvg_property_bag_free(pbag: *mut PropertyBag) {
    unsafe {
        let _ = Box::from_raw(pbag);
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_begin(pbag: *const PropertyBag) -> *mut PropertyBagCStrIter {
    assert!(!pbag.is_null());
    let pbag = unsafe { &*pbag };

    Box::into_raw(Box::new(pbag.cstr_iter()))
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_next(iter: *mut PropertyBagCStrIter,
                                          out_key: *mut *const libc::c_char,
                                          out_attr: *mut Attribute,
                                          out_value: *mut *const libc::c_char)
                                          -> glib_sys::gboolean
{
    assert!(!iter.is_null());
    let iter = unsafe { &mut *iter };

    if let Some((key, attr, val)) = iter.next() {
        unsafe {
            *out_key = key.as_ptr();
            *out_attr = attr;
            *out_value = val.as_ptr();
        }
        true.to_glib()
    } else {
        unsafe {
            *out_key = ptr::null();
            *out_value = ptr::null();
        }
        false.to_glib()
    }
}

#[no_mangle]
pub extern fn rsvg_property_bag_iter_end(iter: *mut PropertyBagCStrIter) {
    assert!(!iter.is_null());

    unsafe { Box::from_raw(iter) };
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::ffi::CString;
    use std::mem;

    #[test]
    fn empty_property_bag() {
        let map = unsafe { PropertyBag::new_from_key_value_pairs(ptr::null()) };
        assert_eq!(map.len(), 0);
    }

    #[test]
    fn property_bag_iters() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        for (k, a, v) in pbag.iter() {
            if k == "rx" {
                assert!(a == Attribute::Rx);
                assert!(v == "1");
                had_rx = true;
            } else if k == "ry" {
                assert!(a == Attribute::Ry);
                assert!(v == "2");
                had_ry = true;
            } else {
                unreachable!();
            }
        }

        assert!(had_rx);
        assert!(had_ry);
    }

    #[test]
    fn property_bag_can_iterate_from_c() {
        let pairs = [
            CString::new("rx").unwrap(),
            CString::new("1").unwrap(),
            CString::new("ry").unwrap(),
            CString::new("2").unwrap(),
        ];

        let mut v = Vec::new();

        for x in &pairs {
            v.push(x.as_ptr() as *const libc::c_char);
        }

        v.push(ptr::null());

        let pbag = unsafe { PropertyBag::new_from_key_value_pairs(v.as_ptr()) };

        let mut had_rx: bool = false;
        let mut had_ry: bool = false;

        let iter = rsvg_property_bag_iter_begin(&pbag as *const PropertyBag);

        let mut key = unsafe { mem::uninitialized() };
        let mut att = unsafe { mem::uninitialized() };
        let mut val = unsafe { mem::uninitialized() };

        while from_glib(rsvg_property_bag_iter_next(iter,
                                                    &mut key as *mut _,
                                                    &mut att as *mut _,
                                                    &mut val as *mut _)) {
            let k = unsafe { CStr::from_ptr(key).to_str_utf8() };
            let v = unsafe { CStr::from_ptr(val).to_str_utf8() };

            if k == "rx" {
                assert!(att == Attribute::Rx);
                assert!(v == "1");
                had_rx = true;
            } else if k == "ry" {
                assert!(att == Attribute::Ry);
                assert!(v == "2");
                had_ry = true;
            }
        }

        rsvg_property_bag_iter_end(iter);

        assert!(had_rx);
        assert!(had_ry);
    }
}
<|endoftext|>


<commit_before>// CITA
// Copyright 2016-2018 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify 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.

// This program is distributed in the hope that it will be
// useful, 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 this program.  If not, see <http://www.gnu.org/licenses/>.

use super::helpers::*;
use crate::contracts::{
    grpc::{
        contract::{contract_creation_address, low_contract_address},
        service_registry,
    },
    native::factory::Factory as NativeFactory,
};
use crate::engines::NullEngine;
use crate::executive::Executive;
use crate::libexecutor::economical_model::EconomicalModel;
use crate::state::Substate;
use crate::trace::{ExecutiveTracer, ExecutiveVMTracer};
use cita_types::{Address, U256};
use evm;
use evm::action_params::{ActionParams, ActionValue};
use evm::env_info::EnvInfo;
use evm::{Factory, VMType};
use util::BytesRef;

mod grpc_service {
    //use contracts::permission_management::contains_resource;
    use grpc::{RequestOptions, Server, ServerBuilder, SingleResponse};
    use libproto::citacode::{InvokeRequest, InvokeResponse};
    use libproto::citacode_grpc::{
        CitacodeService as GRPCVMService, CitacodeServiceClient as GRPCVMServiceClient,
        CitacodeServiceServer as GRPCVMServiceServer,
    };
    use std::str;
    use std::sync::{Arc, Mutex};

    pub struct GRPCVMServiceImpl {
        init_count: Arc<Mutex<u8>>,
    }

    impl GRPCVMService for GRPCVMServiceImpl {
        fn init(&self, _o: RequestOptions, _p: InvokeRequest) -> SingleResponse<InvokeResponse> {
            let mut count = self.init_count.lock().unwrap();
            *count += 1;
            let mut response = InvokeResponse::new();
            response.set_message((*count).to_string());
            SingleResponse::completed(response)
        }

        fn invoke(&self, _o: RequestOptions, p: InvokeRequest) -> SingleResponse<InvokeResponse> {
            let param = p.param.into_option().unwrap();
            let command = str::from_utf8(&(param.data)).unwrap();
            let return_value: String = match command {
                "inc" => {
                    let mut count = self.init_count.lock().unwrap();
                    *count += 1;
                    (*count).to_string()
                }
                "count" => {
                    let mut count = self.init_count.lock().unwrap();
                    (*count).to_string()
                }
                "hello" => "hello".to_string(),
                _ => {
                    error!("unknown request {:}", command);
                    "".to_string()
                }
            };
            let mut response = InvokeResponse::new();
            response.set_message(return_value);
            SingleResponse::completed(response)
        }
    }

    impl GRPCVMServiceImpl {
        pub fn new() -> Self {
            GRPCVMServiceImpl {
                init_count: Arc::new(Mutex::new(0)),
            }
        }
    }

    pub fn vm_grpc_server(port: u16) -> Option<Server> {
        let mut server = ServerBuilder::new_plain();
        server.http.set_port(port);
        server.add_service(GRPCVMServiceServer::new_service_def(
            GRPCVMServiceImpl::new(),
        ));
        //    server.http.set_cpu_pool_threads(1);
        match server.build() {
            Ok(server) => Some(server),
            Err(_) => None,
        }
    }

    pub fn vm_grpc_client(port: u16) -> GRPCVMServiceClient {
        let client_conf = Default::default();
        GRPCVMServiceClient::new_plain("::1", port, client_conf).unwrap()
    }
}

fn call_vm(params: ActionParams) -> evm::Result<evm::FinalizationResult> {
    let factory = Factory::new(VMType::Interpreter, 1024 * 32);
    let native_factory = NativeFactory::default();
    let mut tracer = ExecutiveTracer::default();
    let mut vm_tracer = ExecutiveVMTracer::toplevel();

    let mut state = get_temp_state();
    let info = EnvInfo::default();
    let engine = NullEngine::default();
    let mut substate = Substate::new();
    let mut ex = Executive::new(
        &mut state,
        &info,
        &engine,
        &factory,
        &native_factory,
        false,
        EconomicalModel::Quota,
        0,
    );
    let mut out = vec![];
    ex.call(
        &params,
        &mut substate,
        BytesRef::Fixed(&mut out),
        &mut tracer,
        &mut vm_tracer,
    )
}

#[test]
fn call_grpc_contract() {
    let server = grpc_service::vm_grpc_server(0).unwrap();
    let port = server.local_addr().port().unwrap();
    let _client = grpc_service::vm_grpc_client(port);
    let sender = Address::default();
    let address: Address = low_contract_address();
    let ip = "127.0.0.1";
    let height = 0;
    // register GRPC contract
    service_registry::register_contract(address, ip, port, height);
    assert!(service_registry::find_contract(address, true).is_none());
    // enable GRPC contract
    let mut params = ActionParams::default();
    params.address = contract_creation_address();
    params.code_address = contract_creation_address();
    params.sender = sender.clone();
    params.origin = sender.clone();
    params.gas = U256::from(10000);
    params.value = ActionValue::Apparent(0.into());
    params.data = Some(address.to_vec());
    let _ = call_vm(params);
    assert!(service_registry::find_contract(address, true).is_some());
    // check count value
    let mut basic_params = ActionParams::default();
    basic_params.address = address;
    basic_params.code_address = address;
    basic_params.sender = sender.clone();
    basic_params.origin = sender.clone();
    basic_params.gas = U256::from(10000);
    basic_params.value = ActionValue::Apparent(0.into());

    let mut params = basic_params.clone();
    params.data = Some("count".as_bytes().to_vec());
    let result = call_vm(params);
    let value: u32 = String::from_utf8_lossy(&result.unwrap().return_data)
        .parse()
        .unwrap();
    assert_eq!(value, 1);
    // call it again
    let mut params = basic_params.clone();
    params.data = Some("inc".as_bytes().to_vec());
    let result = call_vm(params);
    let value: u32 = String::from_utf8_lossy(&result.unwrap().return_data)
        .parse()
        .unwrap();
    assert_eq!(value, 2);
}
<commit_msg>Fix unit test at 2018 edition. [skip travis]<commit_after>// CITA
// Copyright 2016-2019 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify 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.

// This program is distributed in the hope that it will be
// useful, 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 this program.  If not, see <http://www.gnu.org/licenses/>.

use super::helpers::*;
use crate::contracts::{
    grpc::{
        contract::{contract_creation_address, low_contract_address},
        service_registry,
    },
    native::factory::Factory as NativeFactory,
};
use crate::engines::NullEngine;
use crate::executive::Executive;
use crate::libexecutor::economical_model::EconomicalModel;
use crate::state::Substate;
use crate::trace::{ExecutiveTracer, ExecutiveVMTracer};
use cita_types::{Address, U256};
use evm;
use evm::action_params::{ActionParams, ActionValue};
use evm::env_info::EnvInfo;
use evm::{Factory, VMType};
use util::BytesRef;

mod grpc_service {
    //use contracts::permission_management::contains_resource;
    use grpc::{RequestOptions, Server, ServerBuilder, SingleResponse};
    use libproto::citacode::{InvokeRequest, InvokeResponse};
    use libproto::citacode_grpc::{
        CitacodeService as GRPCVMService, CitacodeServiceClient as GRPCVMServiceClient,
        CitacodeServiceServer as GRPCVMServiceServer,
    };
    use std::str;
    use std::sync::{Arc, Mutex};

    pub struct GRPCVMServiceImpl {
        init_count: Arc<Mutex<u8>>,
    }

    impl GRPCVMService for GRPCVMServiceImpl {
        fn init(&self, _o: RequestOptions, _p: InvokeRequest) -> SingleResponse<InvokeResponse> {
            let mut count = self.init_count.lock().unwrap();
            *count += 1;
            let mut response = InvokeResponse::new();
            response.set_message((*count).to_string());
            SingleResponse::completed(response)
        }

        fn invoke(&self, _o: RequestOptions, p: InvokeRequest) -> SingleResponse<InvokeResponse> {
            let param = p.param.into_option().unwrap();
            let command = str::from_utf8(&(param.data)).unwrap();
            let return_value: String = match command {
                "inc" => {
                    let mut count = self.init_count.lock().unwrap();
                    *count += 1;
                    (*count).to_string()
                }
                "count" => {
                    let count = self.init_count.lock().unwrap();
                    (*count).to_string()
                }
                "hello" => "hello".to_string(),
                _ => {
                    error!("unknown request {:}", command);
                    "".to_string()
                }
            };
            let mut response = InvokeResponse::new();
            response.set_message(return_value);
            SingleResponse::completed(response)
        }
    }

    impl GRPCVMServiceImpl {
        pub fn new() -> Self {
            GRPCVMServiceImpl {
                init_count: Arc::new(Mutex::new(0)),
            }
        }
    }

    pub fn vm_grpc_server(port: u16) -> Option<Server> {
        let mut server = ServerBuilder::new_plain();
        server.http.set_port(port);
        server.add_service(GRPCVMServiceServer::new_service_def(
            GRPCVMServiceImpl::new(),
        ));
        //    server.http.set_cpu_pool_threads(1);
        match server.build() {
            Ok(server) => Some(server),
            Err(_) => None,
        }
    }

    pub fn vm_grpc_client(port: u16) -> GRPCVMServiceClient {
        let client_conf = Default::default();
        GRPCVMServiceClient::new_plain("::1", port, client_conf).unwrap()
    }
}

fn call_vm(params: ActionParams) -> evm::Result<evm::FinalizationResult> {
    let factory = Factory::new(VMType::Interpreter, 1024 * 32);
    let native_factory = NativeFactory::default();
    let mut tracer = ExecutiveTracer::default();
    let mut vm_tracer = ExecutiveVMTracer::toplevel();

    let mut state = get_temp_state();
    let info = EnvInfo::default();
    let engine = NullEngine::default();
    let mut substate = Substate::new();
    let mut ex = Executive::new(
        &mut state,
        &info,
        &engine,
        &factory,
        &native_factory,
        false,
        EconomicalModel::Quota,
        0,
    );
    let mut out = vec![];
    ex.call(
        &params,
        &mut substate,
        BytesRef::Fixed(&mut out),
        &mut tracer,
        &mut vm_tracer,
    )
}

#[test]
fn call_grpc_contract() {
    let server = grpc_service::vm_grpc_server(0).unwrap();
    let port = server.local_addr().port().unwrap();
    let _client = grpc_service::vm_grpc_client(port);
    let sender = Address::default();
    let address: Address = low_contract_address();
    let ip = "127.0.0.1";
    let height = 0;
    // register GRPC contract
    service_registry::register_contract(address, ip, port, height);
    assert!(service_registry::find_contract(address, true).is_none());
    // enable GRPC contract
    let mut params = ActionParams::default();
    params.address = contract_creation_address();
    params.code_address = contract_creation_address();
    params.sender = sender.clone();
    params.origin = sender.clone();
    params.gas = U256::from(10000);
    params.value = ActionValue::Apparent(0.into());
    params.data = Some(address.to_vec());
    let _ = call_vm(params);
    assert!(service_registry::find_contract(address, true).is_some());
    // check count value
    let mut basic_params = ActionParams::default();
    basic_params.address = address;
    basic_params.code_address = address;
    basic_params.sender = sender.clone();
    basic_params.origin = sender.clone();
    basic_params.gas = U256::from(10000);
    basic_params.value = ActionValue::Apparent(0.into());

    let mut params = basic_params.clone();
    params.data = Some("count".as_bytes().to_vec());
    let result = call_vm(params);
    let value: u32 = String::from_utf8_lossy(&result.unwrap().return_data)
        .parse()
        .unwrap();
    assert_eq!(value, 1);
    // call it again
    let mut params = basic_params.clone();
    params.data = Some("inc".as_bytes().to_vec());
    let result = call_vm(params);
    let value: u32 = String::from_utf8_lossy(&result.unwrap().return_data)
        .parse()
        .unwrap();
    assert_eq!(value, 2);
}
<|endoftext|>


<commit_before>fn main() {
    // https://www.youtube.com/watch?v=uCsD3ZGzMgE
    // W(n) = 2l + 1
    println!("part 1: 1834903");
}
<commit_msg>rust day19 part2<commit_after>use std::collections::VecDeque;

fn main() {
    // https://www.youtube.com/watch?v=uCsD3ZGzMgE
    // W(n) = 2l + 1
    println!("part 1: 1834903");

    let mut elves = VecDeque::new();
    for i in 1..3014604 {
        elves.push_back(i);
    }

    while elves.len() > 1 {
        let k = elves.len()/2;
        elves.remove(k);
        let head = elves.pop_front().unwrap();
        elves.push_back(head);
    }
    println!("part 2: {}", elves[0]);
}
<|endoftext|>


<commit_before>extern crate phf;

use glib_sys;
use glib::translate::*;
use libc;
use std::mem;
use std::str::FromStr;

use util::utf8_cstr;

include!(concat!(env!("OUT_DIR"), "/attributes-codegen.rs"));

impl FromStr for Attribute {
    type Err = ();

    fn from_str(s: &str) -> Result<Attribute, ()> {
        ATTRIBUTES.get(s).cloned().ok_or(())
    }
}

#[no_mangle]
pub extern fn rsvg_attribute_from_name(raw_name: *const libc::c_char,
                                       out_attr: *mut Attribute) -> glib_sys::gboolean {
    let name = unsafe { utf8_cstr(raw_name) };

    match Attribute::from_str(name) {
        Ok(a) => {
            unsafe { *out_attr = a; }
            true.to_glib()
        },

        Err(_) => {
            false.to_glib()
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parses_attributes() {
        assert_eq!(Attribute::from_str("width"), Ok(Attribute::Width));
    }

    #[test]
    fn unknown_attribute_yields_error() {
        assert_eq!(Attribute::from_str("foobar"), Err(()));
    }

    #[test]
    fn c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("width".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(res);
        assert_eq!(a, Attribute::Width);
    }

    #[test]
    fn invalid_c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("foobar".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(!res);
    }
}
<commit_msg>fix: modules in attributes.rs<commit_after>extern crate phf;

use glib_sys;
use glib::translate::*;
use libc;
use std::str::FromStr;

use util::utf8_cstr;

include!(concat!(env!("OUT_DIR"), "/attributes-codegen.rs"));

impl FromStr for Attribute {
    type Err = ();

    fn from_str(s: &str) -> Result<Attribute, ()> {
        ATTRIBUTES.get(s).cloned().ok_or(())
    }
}

#[no_mangle]
pub extern fn rsvg_attribute_from_name(raw_name: *const libc::c_char,
                                       out_attr: *mut Attribute) -> glib_sys::gboolean {
    let name = unsafe { utf8_cstr(raw_name) };

    match Attribute::from_str(name) {
        Ok(a) => {
            unsafe { *out_attr = a; }
            true.to_glib()
        },

        Err(_) => {
            false.to_glib()
        }
    }
}

#[cfg(test)]
mod tests {
    use std::mem;
    use super::*;

    #[test]
    fn parses_attributes() {
        assert_eq!(Attribute::from_str("width"), Ok(Attribute::Width));
    }

    #[test]
    fn unknown_attribute_yields_error() {
        assert_eq!(Attribute::from_str("foobar"), Err(()));
    }

    #[test]
    fn c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("width".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(res);
        assert_eq!(a, Attribute::Width);
    }

    #[test]
    fn invalid_c_attribute_from_name() {
        let mut a: Attribute = unsafe { mem::uninitialized() };
        let res: bool = from_glib(rsvg_attribute_from_name("foobar".as_ptr() as *const libc::c_char,
                                                           &mut a as *mut Attribute));
        assert!(!res);
    }
}
<|endoftext|>


<commit_before>//
// Copyright 2018 The Project Oak Authors
//
// 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.
//

//! Functionality to help Oak Nodes interact with gRPC.

pub use crate::proto::code::Code;
use crate::{proto, wasm, Handle, OakStatus, ReadHandle, WriteHandle};
use protobuf::{Message, ProtobufEnum};

/// Result type that uses a [`proto::status::Status`] type for error values.
pub type Result<T> = std::result::Result<T, proto::status::Status>;

/// Helper to create a gRPC status object.
pub fn build_status(code: Code, msg: &str) -> proto::status::Status {
    let mut status = proto::status::Status::new();
    status.set_code(code.value());
    status.set_message(msg.to_string());
    status
}

/// Channel-holding object that encapsulates response messages into
/// `GrpcResponse` wrapper messages and writes serialized versions to a send
///  channel.
pub struct ChannelResponseWriter {
    channel: crate::io::Channel,
}

/// Indicate whether a write method should leave the current gRPC method
/// invocation open or close it.
#[derive(PartialEq, Clone, Debug)]
pub enum WriteMode {
    KeepOpen,
    Close,
}

impl ChannelResponseWriter {
    pub fn new(out_handle: crate::WriteHandle) -> Self {
        ChannelResponseWriter {
            channel: crate::io::Channel::new(out_handle),
        }
    }

    /// Write out a gRPC response and optionally close out the method
    /// invocation.  Any errors from the channel are silently dropped.
    pub fn write<T: protobuf::Message>(&mut self, rsp: T, mode: WriteMode) {
        // Put the serialized response into a GrpcResponse message wrapper and
        // serialize it into the channel.
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        let mut any = protobuf::well_known_types::Any::new();
        rsp.write_to_writer(&mut any.value).unwrap();
        grpc_rsp.set_rsp_msg(any);
        grpc_rsp.set_last(match mode {
            WriteMode::KeepOpen => false,
            WriteMode::Close => true,
        });
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        if mode == WriteMode::Close {
            let _ = self.channel.close();
        }
    }

    /// Write an empty gRPC response and optionally close out the method
    /// invocation. Any errors from the channel are silently dropped.
    pub fn write_empty(&mut self, mode: WriteMode) {
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        grpc_rsp.set_rsp_msg(protobuf::well_known_types::Any::new());
        grpc_rsp.set_last(match mode {
            WriteMode::KeepOpen => false,
            WriteMode::Close => true,
        });
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        if mode == WriteMode::Close {
            let _ = self.channel.close();
        }
    }

    /// Close out the gRPC method invocation with the given final result.
    pub fn close(&mut self, result: Result<()>) {
        // Build a final GrpcResponse message wrapper and serialize it into the
        // channel.
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        grpc_rsp.set_last(true);
        if let Err(status) = result {
            grpc_rsp.set_status(status);
        }
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        let _ = self.channel.close();
    }
}

/// Trait for Oak Nodes that act as a gRPC services.
///
/// An `OakNode` instance is normally passed to [`event_loop`], to allow
/// repeated invocation of its `invoke()` method.
pub trait OakNode {
    /// Construct the (single) instance of the node.
    ///
    /// This method may choose to initialize logging by invoking
    /// [`oak_log::init()`].
    ///
    /// [`oak_log::init()`]: ../../oak_log/fn.init.html
    fn new() -> Self
    where
        Self: Sized;

    /// Process a single gRPC method invocation.
    ///
    /// The method name is provided by `method` and the incoming serialized gRPC
    /// request is held in `req`.  Response messages should be written using
    /// `writer.write`, followed by `writer.close`.
    fn invoke(&mut self, method: &str, req: &[u8], writer: ChannelResponseWriter);
}

/// Perform a gRPC event loop for a Node.
///
/// Invoking the given `node`'s [`invoke`] method for each incoming request that
/// arrives on the inbound channel as a serialized [`GrpcRequest`] message,
/// giving the [`invoke`] method the outbound channel for encapsulated responses
/// to be written to.
///
/// [`invoke`]: OakNode::invoke
/// [`GrpcRequest`]: crate::proto::grpc_encap::GrpcRequest
pub fn event_loop<T: OakNode>(mut node: T, grpc_in_handle: ReadHandle) -> i32 {
    info!("start event loop for node with handle {:?}", grpc_in_handle);
    if grpc_in_handle.handle == 0 {
        return OakStatus::ERR_CHANNEL_CLOSED.value();
    }
    crate::set_panic_hook();

    let read_handles = vec![grpc_in_handle];
    let mut space = crate::new_handle_space(&read_handles);

    loop {
        // Block until there is a message to read on an input channel.
        crate::prep_handle_space(&mut space);
        unsafe {
            let status = wasm::wait_on_channels(space.as_mut_ptr(), read_handles.len() as u32);
            match OakStatus::from_i32(status as i32) {
                Some(OakStatus::OK) => (),
                Some(err) => return err as i32,
                None => return OakStatus::OAK_STATUS_UNSPECIFIED.value(),
            }
        }

        let mut buf = Vec::<u8>::with_capacity(1024);
        let mut handles = Vec::<Handle>::with_capacity(1);
        crate::channel_read(grpc_in_handle, &mut buf, &mut handles);
        if buf.is_empty() {
            info!("no pending message; poll again");
            continue;
        }
        if handles.is_empty() {
            panic!("no response handle received alongside gRPC request")
        }
        let req: proto::grpc_encap::GrpcRequest = protobuf::parse_from_bytes(&buf).unwrap();
        if !req.last {
            panic!("Support for streaming requests not yet implemented");
        }
        node.invoke(
            &req.method_name,
            req.get_req_msg().value.as_slice(),
            ChannelResponseWriter::new(WriteHandle { handle: handles[0] }),
        );
    }
}
<commit_msg>Add oak::grpc generic helper functions<commit_after>//
// Copyright 2018 The Project Oak Authors
//
// 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.
//

//! Functionality to help Oak Nodes interact with gRPC.

pub use crate::proto::code::Code;
use crate::{proto, wasm, Handle, OakStatus, ReadHandle, WriteHandle};
use protobuf::{Message, ProtobufEnum};

/// Result type that uses a [`proto::status::Status`] type for error values.
pub type Result<T> = std::result::Result<T, proto::status::Status>;

/// Helper to create a gRPC status object.
pub fn build_status(code: Code, msg: &str) -> proto::status::Status {
    let mut status = proto::status::Status::new();
    status.set_code(code.value());
    status.set_message(msg.to_string());
    status
}

/// Channel-holding object that encapsulates response messages into
/// `GrpcResponse` wrapper messages and writes serialized versions to a send
///  channel.
pub struct ChannelResponseWriter {
    channel: crate::io::Channel,
}

/// Indicate whether a write method should leave the current gRPC method
/// invocation open or close it.
#[derive(PartialEq, Clone, Debug)]
pub enum WriteMode {
    KeepOpen,
    Close,
}

impl ChannelResponseWriter {
    pub fn new(out_handle: crate::WriteHandle) -> Self {
        ChannelResponseWriter {
            channel: crate::io::Channel::new(out_handle),
        }
    }

    /// Write out a gRPC response and optionally close out the method
    /// invocation.  Any errors from the channel are silently dropped.
    pub fn write<T: protobuf::Message>(&mut self, rsp: T, mode: WriteMode) {
        // Put the serialized response into a GrpcResponse message wrapper and
        // serialize it into the channel.
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        let mut any = protobuf::well_known_types::Any::new();
        rsp.write_to_writer(&mut any.value).unwrap();
        grpc_rsp.set_rsp_msg(any);
        grpc_rsp.set_last(match mode {
            WriteMode::KeepOpen => false,
            WriteMode::Close => true,
        });
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        if mode == WriteMode::Close {
            let _ = self.channel.close();
        }
    }

    /// Write an empty gRPC response and optionally close out the method
    /// invocation. Any errors from the channel are silently dropped.
    pub fn write_empty(&mut self, mode: WriteMode) {
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        grpc_rsp.set_rsp_msg(protobuf::well_known_types::Any::new());
        grpc_rsp.set_last(match mode {
            WriteMode::KeepOpen => false,
            WriteMode::Close => true,
        });
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        if mode == WriteMode::Close {
            let _ = self.channel.close();
        }
    }

    /// Close out the gRPC method invocation with the given final result.
    pub fn close(&mut self, result: Result<()>) {
        // Build a final GrpcResponse message wrapper and serialize it into the
        // channel.
        let mut grpc_rsp = proto::grpc_encap::GrpcResponse::new();
        grpc_rsp.set_last(true);
        if let Err(status) = result {
            grpc_rsp.set_status(status);
        }
        let _ = grpc_rsp.write_to_writer(&mut self.channel);
        let _ = self.channel.close();
    }
}

/// Trait for Oak Nodes that act as a gRPC services.
///
/// An `OakNode` instance is normally passed to [`event_loop`], to allow
/// repeated invocation of its `invoke()` method.
pub trait OakNode {
    /// Construct the (single) instance of the node.
    ///
    /// This method may choose to initialize logging by invoking
    /// [`oak_log::init()`].
    ///
    /// [`oak_log::init()`]: ../../oak_log/fn.init.html
    fn new() -> Self
    where
        Self: Sized;

    /// Process a single gRPC method invocation.
    ///
    /// The method name is provided by `method` and the incoming serialized gRPC
    /// request is held in `req`.  Response messages should be written using
    /// `writer.write`, followed by `writer.close`.
    fn invoke(&mut self, method: &str, req: &[u8], writer: ChannelResponseWriter);
}

/// Perform a gRPC event loop for a Node.
///
/// Invoking the given `node`'s [`invoke`] method for each incoming request that
/// arrives on the inbound channel as a serialized [`GrpcRequest`] message,
/// giving the [`invoke`] method the outbound channel for encapsulated responses
/// to be written to.
///
/// [`invoke`]: OakNode::invoke
/// [`GrpcRequest`]: crate::proto::grpc_encap::GrpcRequest
pub fn event_loop<T: OakNode>(mut node: T, grpc_in_handle: ReadHandle) -> i32 {
    info!("start event loop for node with handle {:?}", grpc_in_handle);
    if grpc_in_handle.handle == 0 {
        return OakStatus::ERR_CHANNEL_CLOSED.value();
    }
    crate::set_panic_hook();

    let read_handles = vec![grpc_in_handle];
    let mut space = crate::new_handle_space(&read_handles);

    loop {
        // Block until there is a message to read on an input channel.
        crate::prep_handle_space(&mut space);
        unsafe {
            let status = wasm::wait_on_channels(space.as_mut_ptr(), read_handles.len() as u32);
            match OakStatus::from_i32(status as i32) {
                Some(OakStatus::OK) => (),
                Some(err) => return err as i32,
                None => return OakStatus::OAK_STATUS_UNSPECIFIED.value(),
            }
        }

        let mut buf = Vec::<u8>::with_capacity(1024);
        let mut handles = Vec::<Handle>::with_capacity(1);
        crate::channel_read(grpc_in_handle, &mut buf, &mut handles);
        if buf.is_empty() {
            info!("no pending message; poll again");
            continue;
        }
        if handles.is_empty() {
            panic!("no response handle received alongside gRPC request")
        }
        let req: proto::grpc_encap::GrpcRequest = protobuf::parse_from_bytes(&buf).unwrap();
        if !req.last {
            panic!("Support for streaming requests not yet implemented");
        }
        node.invoke(
            &req.method_name,
            req.get_req_msg().value.as_slice(),
            ChannelResponseWriter::new(WriteHandle { handle: handles[0] }),
        );
    }
}

pub fn handle_req_rsp<C, R, Q>(mut node_fn: C, req: &[u8], mut writer: ChannelResponseWriter)
where
    C: FnMut(R) -> Result<Q>,
    R: protobuf::Message,
    Q: protobuf::Message,
{
    let r: R = protobuf::parse_from_bytes(&req).unwrap();
    match node_fn(r) {
        Ok(rsp) => writer.write(rsp, WriteMode::Close),
        Err(status) => writer.close(Err(status)),
    }
}

pub fn handle_req_stream<C, R>(mut node_fn: C, req: &[u8], writer: ChannelResponseWriter)
where
    C: FnMut(R, ChannelResponseWriter),
    R: protobuf::Message,
{
    let r: R = protobuf::parse_from_bytes(&req).unwrap();
    node_fn(r, writer)
}

pub fn handle_stream_rsp<C, R, Q>(mut node_fn: C, req: &[u8], mut writer: ChannelResponseWriter)
where
    C: FnMut(Vec<R>) -> Result<Q>,
    R: protobuf::Message,
    Q: protobuf::Message,
{
    // TODO(#97): better client-side streaming
    let rr: Vec<R> = vec![protobuf::parse_from_bytes(&req).unwrap()];
    match node_fn(rr) {
        Ok(rsp) => writer.write(rsp, WriteMode::Close),
        Err(status) => writer.close(Err(status)),
    }
}

pub fn handle_stream_stream<C, R>(mut node_fn: C, req: &[u8], writer: ChannelResponseWriter)
where
    C: FnMut(Vec<R>, ChannelResponseWriter),
    R: protobuf::Message,
{
    // TODO(#97): better client-side streaming
    let rr: Vec<R> = vec![protobuf::parse_from_bytes(&req).unwrap()];
    node_fn(rr, writer)
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use rustc::hir::*;
use utils::{is_range_expression, match_var, span_lint_and_sugg};

/// **What it does:** Checks for fields in struct literals where shorthands
/// could be used.
///
/// **Why is this bad?** If the field and variable names are the same,
/// the field name is redundant.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let bar: u8 = 123;
///
/// struct Foo {
///     bar: u8,
/// }
///
/// let foo = Foo{ bar: bar }
/// ```
declare_lint! {
    pub REDUNDANT_FIELD_NAMES,
    Warn,
    "checks for fields in struct literals where shorthands could be used"
}

pub struct RedundantFieldNames;

impl LintPass for RedundantFieldNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(REDUNDANT_FIELD_NAMES)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        if let ExprStruct(_, ref fields, _) = expr.node {
            for field in fields {
                let name = field.name.node;

                // Do not care about range expressions.
                // They could have redundant field name when desugared to structs.
                // e.g. `start..end` is desugared to `Range { start: start, end: end }`
                if is_range_expression(expr.span) {
                    continue;
                }

                if match_var(&field.expr, name) && !field.is_shorthand {
                    span_lint_and_sugg (
                        cx,
                        REDUNDANT_FIELD_NAMES,
                        field.span,
                        "redundant field names in struct initialization",
                        "replace it with",
                        name.to_string()
                    );
                }
            }
        }
    }
}
<commit_msg>Move call of `is_range_expression()` outside of blocks<commit_after>use rustc::lint::*;
use rustc::hir::*;
use utils::{is_range_expression, match_var, span_lint_and_sugg};

/// **What it does:** Checks for fields in struct literals where shorthands
/// could be used.
///
/// **Why is this bad?** If the field and variable names are the same,
/// the field name is redundant.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let bar: u8 = 123;
///
/// struct Foo {
///     bar: u8,
/// }
///
/// let foo = Foo{ bar: bar }
/// ```
declare_lint! {
    pub REDUNDANT_FIELD_NAMES,
    Warn,
    "checks for fields in struct literals where shorthands could be used"
}

pub struct RedundantFieldNames;

impl LintPass for RedundantFieldNames {
    fn get_lints(&self) -> LintArray {
        lint_array!(REDUNDANT_FIELD_NAMES)
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
    fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
        // Do not care about range expressions.
        // They could have redundant field name when desugared to structs.
        // e.g. `start..end` is desugared to `Range { start: start, end: end }`
        if is_range_expression(expr.span) {
            return;
        }

        if let ExprStruct(_, ref fields, _) = expr.node {
            for field in fields {
                let name = field.name.node;

                if match_var(&field.expr, name) && !field.is_shorthand {
                    span_lint_and_sugg (
                        cx,
                        REDUNDANT_FIELD_NAMES,
                        field.span,
                        "redundant field names in struct initialization",
                        "replace it with",
                        name.to_string()
                    );
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ast::*;
use crate::utils::span_lint;

use cargo_metadata;
use lazy_static::lazy_static;
use semver;

/// **What it does:** Checks to see if wildcard dependencies are being used.
///
/// **Why is this bad?** [As the edition guide sais](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),
/// it is highly unlikely that you work with any possible version of your dependency,
/// and wildcard dependencies would cause unnecessary breakage in the ecosystem.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```toml
/// [dependencies]
/// regex = "*"
/// ```
declare_clippy_lint! {
    pub WILDCARD_DEPENDENCIES,
    cargo,
    "wildcard dependencies being used"
}

pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(WILDCARD_DEPENDENCIES)
    }
}

impl EarlyLintPass for Pass {
    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
        let metadata = if let Ok(metadata) = cargo_metadata::metadata(None) {
            metadata
        } else {
            span_lint(cx, WILDCARD_DEPENDENCIES, krate.span, "could not read cargo metadata");
            return;
        };

        lazy_static! {
            // VersionReq::any() does not work
            static ref WILDCARD_VERSION_REQ: semver::VersionReq = semver::VersionReq::parse("*").unwrap();
        }

        for dep in &metadata.packages[0].dependencies {
            if dep.req == *WILDCARD_VERSION_REQ {
                span_lint(
                    cx,
                    WILDCARD_DEPENDENCIES,
                    krate.span,
                    &format!("wildcard dependency for `{}`", dep.name),
                );
            }
        }
    }
}
<commit_msg>Some fixes for wildcard_dependencies<commit_after>// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
use crate::rustc::{declare_tool_lint, lint_array};
use crate::syntax::ast::*;
use crate::syntax::source_map::DUMMY_SP;
use crate::utils::span_lint;

use cargo_metadata;
use semver;

/// **What it does:** Checks for wildcard dependencies in the `Cargo.toml`.
///
/// **Why is this bad?** [As the edition guide says](https://rust-lang-nursery.github.io/edition-guide/rust-2018/cargo-and-crates-io/crates-io-disallows-wildcard-dependencies.html),
/// it is highly unlikely that you work with any possible version of your dependency,
/// and wildcard dependencies would cause unnecessary breakage in the ecosystem.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```toml
/// [dependencies]
/// regex = "*"
/// ```
declare_clippy_lint! {
    pub WILDCARD_DEPENDENCIES,
    cargo,
    "wildcard dependencies being used"
}

pub struct Pass;

impl LintPass for Pass {
    fn get_lints(&self) -> LintArray {
        lint_array!(WILDCARD_DEPENDENCIES)
    }
}

impl EarlyLintPass for Pass {
    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
        let metadata = if let Ok(metadata) = cargo_metadata::metadata(None) {
            metadata
        } else {
            span_lint(cx, WILDCARD_DEPENDENCIES, krate.span, "could not read cargo metadata");
            return;
        };

        for dep in &metadata.packages[0].dependencies {
            // VersionReq::any() does not work
            if let Ok(wildcard_ver) = semver::VersionReq::parse("*") {
                if dep.req == wildcard_ver {
                    span_lint(
                        cx,
                        WILDCARD_DEPENDENCIES,
                        DUMMY_SP,
                        &format!("wildcard dependency for `{}`", dep.name),
                    );
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::fs::File;
use std::ops::Drop;
use std::path::PathBuf;
use std::result::Result as RResult;
use std::sync::Arc;
use std::sync::{RwLock, Mutex};

use fs2::FileExt;

use entry::Entry;
use error::StoreError;

/// The Result Type returned by any interaction with the store that could fail
pub type Result<T> = RResult<T, StoreError>;

/// The Index into the Store
pub type StoreId = PathBuf;

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl<'a> IntoStoreId for &'a str {
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl<'a> IntoStoreId for &'a String{
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl IntoStoreId for String{
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        self
    }
}

impl<'a> IntoStoreId for &'a PathBuf {
    fn into_storeid(self) -> StoreId {
        self.clone()
    }
}

impl<ISI: IntoStoreId> IntoStoreId for (ISI, ISI) {
    fn into_storeid(self) -> StoreId {
        let (first, second) = self;
        let mut res : StoreId = first.into_storeid();
        res.push(second.into_storeid());
        res
    }
}

/// A store entry, depending on the option type it is either borrowed currently
/// or not.
struct StoreEntry {
    file: File,
    entry: Option<Entry>,
}

impl StoreEntry {
    /// The entry is currently borrowed, meaning that some thread is currently
    /// mutating it
    fn is_borrowed(&self) -> bool {
        self.entry.is_none()
    }

    /// Set the entry to the given one. This will also overwrite the entry
    /// and flush it to disk
    fn set_entry(&mut self, entry: Entry) -> Result<()> {
        self.entry = Some(entry);
        unimplemented!()
    }

    /// We borrow the entry
    fn get_entry(&mut self) -> Result<Entry> {
        unimplemented!()
    }
}

/// The Store itself, through this object one can interact with IMAG's entries
pub struct Store {
    location: PathBuf,

    /**
     * Internal Path->File cache map
     *
     * Caches the files, so they remain flock()ed
     *
     * Could be optimized for a threadsafe HashMap
     */
    entries: Arc<RwLock<HashMap<StoreId, StoreEntry>>>,
}

impl Store {
    /// Creates the Entry at the given location (inside the entry)
    pub fn create(&self, entry: Entry) -> Result<()> {
        unimplemented!();
    }

    /// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
    /// dropped, the new Entry is written to disk
    pub fn retrieve<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
        unimplemented!();
    }

    /// Return the `FileLockEntry` and write to disk
    pub fn update<'a>(&'a self, entry: FileLockEntry<'a>) -> Result<()> {
        unimplemented!();
    }

    /// Retrieve a copy of a given entry, this cannot be used to mutate
    /// the one on disk
    pub fn retrieve_copy(&self, id: StoreId) -> Result<Entry> {
        unimplemented!();
    }

    /// Delete an entry
    pub fn delete(&self, id: StoreId) -> Result<()> {
        unimplemented!();
    }
}

impl Drop for Store {

    /**
     * Unlock all files on drop
     *
     * TODO: Error message when file cannot be unlocked?
     */
    fn drop(&mut self) {
        self.entries.write().unwrap()
            .iter().map(|f| f.1.file.unlock());
    }

}

/// A struct that allows you to borrow an Entry
pub struct FileLockEntry<'a> {
    store: &'a Store,
    entry: Entry,
    key: StoreId,
}

impl<'a> FileLockEntry<'a, > {
    fn new(store: &'a Store, entry: Entry, key: StoreId) -> FileLockEntry<'a> {
        FileLockEntry {
            store: store,
            entry: entry,
            key: key,
        }
    }
}

impl<'a> ::std::ops::Deref for FileLockEntry<'a> {
    type Target = Entry;

    fn deref(&self) -> &Self::Target {
        &self.entry
    }
}

impl<'a> ::std::ops::DerefMut for FileLockEntry<'a> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.entry
    }
}

impl<'a> Drop for FileLockEntry<'a> {
    fn drop(&mut self) {
        let mut map = self.store.entries.write().unwrap();
        map.get_mut(&self.key).unwrap().set_entry(self.entry.clone());
    }
}

#[cfg(test)]
mod test {
    use std::path::PathBuf;
    use store::{StoreId, IntoStoreId};

    #[test]
    fn into_storeid_trait() {
        let buf = PathBuf::from("abc/def");

        let test = ("abc", "def");
        assert_eq!(buf, test.into_storeid());

        let test = "abc/def";
        assert_eq!(buf, test.into_storeid());

        let test = String::from("abc/def");
        assert_eq!(buf, test.into_storeid());

        let test = PathBuf::from("abc/def");
        assert_eq!(buf, test.into_storeid());
    }
}

<commit_msg>Replace Option with enum of presence<commit_after>use std::collections::HashMap;
use std::fs::File;
use std::ops::Drop;
use std::path::PathBuf;
use std::result::Result as RResult;
use std::sync::Arc;
use std::sync::{RwLock, Mutex};

use fs2::FileExt;

use entry::Entry;
use error::StoreError;

/// The Result Type returned by any interaction with the store that could fail
pub type Result<T> = RResult<T, StoreError>;

/// The Index into the Store
pub type StoreId = PathBuf;

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl<'a> IntoStoreId for &'a str {
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl<'a> IntoStoreId for &'a String{
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl IntoStoreId for String{
    fn into_storeid(self) -> StoreId {
        PathBuf::from(self)
    }
}

impl IntoStoreId for PathBuf {
    fn into_storeid(self) -> StoreId {
        self
    }
}

impl<'a> IntoStoreId for &'a PathBuf {
    fn into_storeid(self) -> StoreId {
        self.clone()
    }
}

impl<ISI: IntoStoreId> IntoStoreId for (ISI, ISI) {
    fn into_storeid(self) -> StoreId {
        let (first, second) = self;
        let mut res : StoreId = first.into_storeid();
        res.push(second.into_storeid());
        res
    }
}

#[derive(PartialEq)]
enum StoreEntryPresence {
    Present,
    Borrowed
}

/// A store entry, depending on the option type it is either borrowed currently
/// or not.
struct StoreEntry {
    file: File,
    entry: StoreEntryPresence
}

impl StoreEntry {
    /// The entry is currently borrowed, meaning that some thread is currently
    /// mutating it
    fn is_borrowed(&self) -> bool {
        self.entry == StoreEntryPresence::Borrowed
    }

    /// Flush the entry to disk
    fn set_entry(&mut self, entry: Entry) -> Result<()> {
        unimplemented!()
    }

    /// We borrow the entry
    fn get_entry(&mut self) -> Result<Entry> {
        unimplemented!()
    }

    /// We copy the entry
    fn copy_entry(&mut self) -> Result<Entry> {
        unimplemented!()
    }
}

/// The Store itself, through this object one can interact with IMAG's entries
pub struct Store {
    location: PathBuf,

    /**
     * Internal Path->File cache map
     *
     * Caches the files, so they remain flock()ed
     *
     * Could be optimized for a threadsafe HashMap
     */
    entries: Arc<RwLock<HashMap<StoreId, StoreEntry>>>,
}

impl Store {
    /// Creates the Entry at the given location (inside the entry)
    pub fn create(&self, entry: Entry) -> Result<()> {
        unimplemented!();
    }

    /// Borrow a given Entry. When the `FileLockEntry` is either `update`d or
    /// dropped, the new Entry is written to disk
    pub fn retrieve<'a>(&'a self, id: StoreId) -> Result<FileLockEntry<'a>> {
        unimplemented!();
    }

    /// Return the `FileLockEntry` and write to disk
    pub fn update<'a>(&'a self, entry: FileLockEntry<'a>) -> Result<()> {
        self._update(&entry)
    }

    /// Internal method to write to the filesystem store.
    ///
    /// # Assumptions
    /// This method assumes that entry is dropped _right after_ the call, hence
    /// it is not public.
    fn _update<'a>(&'a self, entry: &FileLockEntry<'a>) -> Result<()> {
        unimplemented!();
    }

    /// Retrieve a copy of a given entry, this cannot be used to mutate
    /// the one on disk
    pub fn retrieve_copy(&self, id: StoreId) -> Result<Entry> {
        unimplemented!();
    }

    /// Delete an entry
    pub fn delete(&self, id: StoreId) -> Result<()> {
        unimplemented!();
    }
}

impl Drop for Store {

    /**
     * Unlock all files on drop
     *
     * TODO: Error message when file cannot be unlocked?
     */
    fn drop(&mut self) {
        self.entries.write().unwrap()
            .iter().map(|f| f.1.file.unlock());
    }

}

/// A struct that allows you to borrow an Entry
pub struct FileLockEntry<'a> {
    store: &'a Store,
    entry: Entry,
    key: StoreId,
}

impl<'a> FileLockEntry<'a, > {
    fn new(store: &'a Store, entry: Entry, key: StoreId) -> FileLockEntry<'a> {
        FileLockEntry {
            store: store,
            entry: entry,
            key: key,
        }
    }
}

impl<'a> ::std::ops::Deref for FileLockEntry<'a> {
    type Target = Entry;

    fn deref(&self) -> &Self::Target {
        &self.entry
    }
}

impl<'a> ::std::ops::DerefMut for FileLockEntry<'a> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.entry
    }
}

impl<'a> Drop for FileLockEntry<'a> {
    fn drop(&mut self) {
        self.store._update(self).unwrap()
    }
}

#[cfg(test)]
mod test {
    use std::path::PathBuf;
    use store::{StoreId, IntoStoreId};

    #[test]
    fn into_storeid_trait() {
        let buf = PathBuf::from("abc/def");

        let test = ("abc", "def");
        assert_eq!(buf, test.into_storeid());

        let test = "abc/def";
        assert_eq!(buf, test.into_storeid());

        let test = String::from("abc/def");
        assert_eq!(buf, test.into_storeid());

        let test = PathBuf::from("abc/def");
        assert_eq!(buf, test.into_storeid());
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

mod cli;
mod config;

pub use beacon_chain;
pub use cli::cli_app;
pub use client::{Client, ClientBuilder, ClientConfig, ClientGenesis};
pub use config::{get_data_dir, get_eth2_testnet_config, get_testnet_dir};
pub use eth2_config::Eth2Config;

use beacon_chain::events::TeeEventHandler;
use beacon_chain::migrate::BackgroundMigrator;
use beacon_chain::store::LevelDB;
use beacon_chain::{
    builder::Witness, eth1_chain::CachingEth1Backend, slot_clock::SystemTimeSlotClock,
};
use clap::ArgMatches;
use config::get_config;
use environment::RuntimeContext;
use slog::{info, warn};
use std::ops::{Deref, DerefMut};
use types::EthSpec;

/// A type-alias to the tighten the definition of a production-intended `Client`.
pub type ProductionClient<E> = Client<
    Witness<
        BackgroundMigrator<E, LevelDB<E>, LevelDB<E>>,
        SystemTimeSlotClock,
        CachingEth1Backend<E>,
        E,
        TeeEventHandler<E>,
        LevelDB<E>,
        LevelDB<E>,
    >,
>;

/// The beacon node `Client` that will be used in production.
///
/// Generic over some `EthSpec`.
///
/// ## Notes:
///
/// Despite being titled `Production...`, this code is not ready for production. The name
/// demonstrates an intention, not a promise.
pub struct ProductionBeaconNode<E: EthSpec>(ProductionClient<E>);

impl<E: EthSpec> ProductionBeaconNode<E> {
    /// Starts a new beacon node `Client` in the given `environment`.
    ///
    /// Identical to `start_from_client_config`, however the `client_config` is generated from the
    /// given `matches` and potentially configuration files on the local filesystem or other
    /// configurations hosted remotely.
    pub async fn new_from_cli<'a, 'b>(
        context: RuntimeContext<E>,
        matches: &ArgMatches<'b>,
    ) -> Result<Self, String> {
        let client_config = get_config::<E>(
            &matches,
            &context.eth2_config.spec_constants,
            &context.eth2_config().spec,
            context.log().clone(),
        )?;
        Self::new(context, client_config).await
    }

    /// Starts a new beacon node `Client` in the given `environment`.
    ///
    /// Client behaviour is defined by the given `client_config`.
    pub async fn new(
        context: RuntimeContext<E>,
        mut client_config: ClientConfig,
    ) -> Result<Self, String> {
        let http_eth2_config = context.eth2_config().clone();
        let spec = context.eth2_config().spec.clone();
        let client_config_1 = client_config.clone();
        let client_genesis = client_config.genesis.clone();
        let store_config = client_config.store.clone();
        let log = context.log().clone();

        let db_path = client_config.create_db_path()?;
        let freezer_db_path_res = client_config.create_freezer_db_path();

        let executor = context.executor.clone();

        let builder = ClientBuilder::new(context.eth_spec_instance.clone())
            .runtime_context(context)
            .chain_spec(spec)
            .disk_store(&db_path, &freezer_db_path_res?, store_config)?
            .background_migrator()?;

        let builder = builder
            .beacon_chain_builder(client_genesis, client_config_1)
            .await?;
        let builder = if client_config.sync_eth1_chain && !client_config.dummy_eth1_backend {
            info!(
                log,
                "Block production enabled";
                "endpoint" => &client_config.eth1.endpoint,
                "method" => "json rpc via http"
            );
            builder.caching_eth1_backend(client_config.eth1.clone())?
        } else if client_config.dummy_eth1_backend {
            warn!(
                log,
                "Block production impaired";
                "reason" => "dummy eth1 backend is enabled"
            );
            builder.dummy_eth1_backend()?
        } else {
            info!(
                log,
                "Block production disabled";
                "reason" => "no eth1 backend configured"
            );
            builder.no_eth1_backend()?
        };

        let (builder, events) = builder
            .system_time_slot_clock()?
            .tee_event_handler(client_config.websocket_server.clone())?;

        // Inject the executor into the discv5 network config.
        client_config.network.discv5_config.executor = Some(Box::new(executor));

        let builder = builder
            .build_beacon_chain()?
            .network(&mut client_config.network)?
            .notifier()?;

        let builder = if client_config.rest_api.enabled {
            builder.http_server(&client_config, &http_eth2_config, events)?
        } else {
            builder
        };

        Ok(Self(builder.build()))
    }

    pub fn into_inner(self) -> ProductionClient<E> {
        self.0
    }
}

impl<E: EthSpec> Deref for ProductionBeaconNode<E> {
    type Target = ProductionClient<E>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<E: EthSpec> DerefMut for ProductionBeaconNode<E> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
<commit_msg>Tiny improvement: lifetime parameters (#1354)<commit_after>#[macro_use]
extern crate clap;

mod cli;
mod config;

pub use beacon_chain;
pub use cli::cli_app;
pub use client::{Client, ClientBuilder, ClientConfig, ClientGenesis};
pub use config::{get_data_dir, get_eth2_testnet_config, get_testnet_dir};
pub use eth2_config::Eth2Config;

use beacon_chain::events::TeeEventHandler;
use beacon_chain::migrate::BackgroundMigrator;
use beacon_chain::store::LevelDB;
use beacon_chain::{
    builder::Witness, eth1_chain::CachingEth1Backend, slot_clock::SystemTimeSlotClock,
};
use clap::ArgMatches;
use config::get_config;
use environment::RuntimeContext;
use slog::{info, warn};
use std::ops::{Deref, DerefMut};
use types::EthSpec;

/// A type-alias to the tighten the definition of a production-intended `Client`.
pub type ProductionClient<E> = Client<
    Witness<
        BackgroundMigrator<E, LevelDB<E>, LevelDB<E>>,
        SystemTimeSlotClock,
        CachingEth1Backend<E>,
        E,
        TeeEventHandler<E>,
        LevelDB<E>,
        LevelDB<E>,
    >,
>;

/// The beacon node `Client` that will be used in production.
///
/// Generic over some `EthSpec`.
///
/// ## Notes:
///
/// Despite being titled `Production...`, this code is not ready for production. The name
/// demonstrates an intention, not a promise.
pub struct ProductionBeaconNode<E: EthSpec>(ProductionClient<E>);

impl<E: EthSpec> ProductionBeaconNode<E> {
    /// Starts a new beacon node `Client` in the given `environment`.
    ///
    /// Identical to `start_from_client_config`, however the `client_config` is generated from the
    /// given `matches` and potentially configuration files on the local filesystem or other
    /// configurations hosted remotely.
    pub async fn new_from_cli(
        context: RuntimeContext<E>,
        matches: &ArgMatches<'_>,
    ) -> Result<Self, String> {
        let client_config = get_config::<E>(
            &matches,
            &context.eth2_config.spec_constants,
            &context.eth2_config().spec,
            context.log().clone(),
        )?;
        Self::new(context, client_config).await
    }

    /// Starts a new beacon node `Client` in the given `environment`.
    ///
    /// Client behaviour is defined by the given `client_config`.
    pub async fn new(
        context: RuntimeContext<E>,
        mut client_config: ClientConfig,
    ) -> Result<Self, String> {
        let http_eth2_config = context.eth2_config().clone();
        let spec = context.eth2_config().spec.clone();
        let client_config_1 = client_config.clone();
        let client_genesis = client_config.genesis.clone();
        let store_config = client_config.store.clone();
        let log = context.log().clone();

        let db_path = client_config.create_db_path()?;
        let freezer_db_path_res = client_config.create_freezer_db_path();

        let executor = context.executor.clone();

        let builder = ClientBuilder::new(context.eth_spec_instance.clone())
            .runtime_context(context)
            .chain_spec(spec)
            .disk_store(&db_path, &freezer_db_path_res?, store_config)?
            .background_migrator()?;

        let builder = builder
            .beacon_chain_builder(client_genesis, client_config_1)
            .await?;
        let builder = if client_config.sync_eth1_chain && !client_config.dummy_eth1_backend {
            info!(
                log,
                "Block production enabled";
                "endpoint" => &client_config.eth1.endpoint,
                "method" => "json rpc via http"
            );
            builder.caching_eth1_backend(client_config.eth1.clone())?
        } else if client_config.dummy_eth1_backend {
            warn!(
                log,
                "Block production impaired";
                "reason" => "dummy eth1 backend is enabled"
            );
            builder.dummy_eth1_backend()?
        } else {
            info!(
                log,
                "Block production disabled";
                "reason" => "no eth1 backend configured"
            );
            builder.no_eth1_backend()?
        };

        let (builder, events) = builder
            .system_time_slot_clock()?
            .tee_event_handler(client_config.websocket_server.clone())?;

        // Inject the executor into the discv5 network config.
        client_config.network.discv5_config.executor = Some(Box::new(executor));

        let builder = builder
            .build_beacon_chain()?
            .network(&mut client_config.network)?
            .notifier()?;

        let builder = if client_config.rest_api.enabled {
            builder.http_server(&client_config, &http_eth2_config, events)?
        } else {
            builder
        };

        Ok(Self(builder.build()))
    }

    pub fn into_inner(self) -> ProductionClient<E> {
        self.0
    }
}

impl<E: EthSpec> Deref for ProductionBeaconNode<E> {
    type Target = ProductionClient<E>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<E: EthSpec> DerefMut for ProductionBeaconNode<E> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}
<|endoftext|>