<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief application endpoint server feature
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "ApplicationEndpointServer.h"

#include <openssl/err.h>

#include "Basics/delete_object.h"
#include "Basics/ssl-helper.h"
#include "Basics/RandomGenerator.h"
#include "Dispatcher/ApplicationDispatcher.h"
#include "HttpServer/HttpHandlerFactory.h"
#include "HttpServer/HttpServer.h"
#include "HttpServer/HttpsServer.h"
#include "Logger/Logger.h"
#include "Rest/OperationMode.h"
#include "Scheduler/ApplicationScheduler.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                                   private classes
// -----------------------------------------------------------------------------

namespace {
  class BIOGuard {
    public:
      BIOGuard(BIO *bio)
        : _bio(bio) {
      }

      ~BIOGuard() {
        BIO_free(_bio);
      }

    public:
      BIO *_bio;
  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Scheduler
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////

ApplicationEndpointServer::ApplicationEndpointServer (ApplicationServer* applicationServer,
                                                      ApplicationScheduler* applicationScheduler,
                                                      ApplicationDispatcher* applicationDispatcher,
                                                      std::string const& authenticationRealm,
                                                      HttpHandlerFactory::auth_fptr checkAuthentication)
  : ApplicationFeature("EndpointServer"),
    _applicationServer(applicationServer),
    _applicationScheduler(applicationScheduler),
    _applicationDispatcher(applicationDispatcher),
    _authenticationRealm(authenticationRealm),
    _checkAuthentication(checkAuthentication),
    _handlerFactory(0),
    _servers(),
    _endpointList(),
    _httpPort(),
    _endpoints(),
    _disableAuthentication(false),
    _keepAliveTimeout(300.0),
    _backlogSize(10),
    _httpsKeyfile(),
    _cafile(),
    _sslProtocol(HttpsServer::TLS_V1),
    _sslCache(false),
    _sslOptions((uint64_t) (SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_CIPHER_SERVER_PREFERENCE)),
    _sslCipherList(""),
    _sslContext(0),
    _rctx() {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////

ApplicationEndpointServer::~ApplicationEndpointServer () {

  // ..........................................................................
  // Where ever possible we should EXPLICITLY write down the type used in
  // a templated class/method etc. This makes it a lot easier to debug the
  // code. Granted however, that explicitly writing down the type for an
  // overloaded class operator is a little unwieldy.
  // ..........................................................................
  for_each(_servers.begin(), _servers.end(), triagens::basics::DeleteObjectAny());
  _servers.clear();

  if (_handlerFactory != 0) {
    delete _handlerFactory;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Scheduler
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief builds the endpoint servers
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::buildServers () {
  assert(_handlerFactory != 0);
  assert(_applicationScheduler->scheduler() != 0);

  EndpointServer* server;

  // turn off authentication
  if (_disableAuthentication) {
    _handlerFactory->setRequireAuthentication(false);
    LOGGER_INFO("Authentication is turned off");
  }

  // unencrypted endpoints
  if (_endpointList.count(Endpoint::PROTOCOL_HTTP, Endpoint::ENCRYPTION_NONE) > 0) {
    // http endpoints
    server = new HttpServer(_applicationScheduler->scheduler(),
                            _applicationDispatcher->dispatcher(),
                            _keepAliveTimeout,
                            _handlerFactory);

    server->setEndpointList(&_endpointList);
    _servers.push_back(server);
  }

  // ssl endpoints
  if (_endpointList.count(Endpoint::PROTOCOL_HTTP, Endpoint::ENCRYPTION_SSL) > 0) {
    // check the ssl context
    if (_sslContext == 0) {
      LOGGER_INFO("please use the --server.keyfile option");
      LOGGER_FATAL_AND_EXIT("no ssl context is known, cannot create https server");
    }

    // https
    server = new HttpsServer(_applicationScheduler->scheduler(),
                             _applicationDispatcher->dispatcher(),
                             _keepAliveTimeout,
                             _handlerFactory,
                             _sslContext);

    server->setEndpointList(&_endpointList);
    _servers.push_back(server);
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                        ApplicationFeature methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ApplicationServer
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::setupOptions (map<string, ProgramOptionsDescription>& options) {
  // issue #175: add deprecated hidden option for downwards compatibility
  options[ApplicationServer::OPTIONS_HIDDEN]
    ("server.http-port", &_httpPort, "http port for client requests (deprecated)")
  ;

  options[ApplicationServer::OPTIONS_SERVER]
    ("server.endpoint", &_endpoints, "endpoint for client requests")
  ;

  options[ApplicationServer::OPTIONS_SERVER + ":help-admin"]
    ("server.disable-authentication", &_disableAuthentication, "disable authentication for ALL client requests")
    ("server.keep-alive-timeout", &_keepAliveTimeout, "keep-alive timeout in seconds")
    ("server.backlog-size", &_backlogSize, "listen backlog size")
  ;

  options[ApplicationServer::OPTIONS_SERVER + ":help-ssl"]
    ("server.keyfile", &_httpsKeyfile, "keyfile for SSL connections")
    ("server.cafile", &_cafile, "file containing the CA certificates of clients")
    ("server.ssl-protocol", &_sslProtocol, "1 = SSLv2, 2 = SSLv23, 3 = SSLv3, 4 = TLSv1")
    ("server.ssl-cache", &_sslCache, "use SSL session caching")
    ("server.ssl-options", &_sslOptions, "ssl options, see OpenSSL documentation")
    ("server.ssl-cipher-list", &_sslCipherList, "ssl cipher list, see OpenSSL documentation")
  ;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::parsePhase2 (ProgramOptions& options) {
  // create the ssl context (if possible)
  bool ok = createSslContext();

  if (! ok) {
    return false;
  }

  if (_backlogSize <= 0 || _backlogSize > SOMAXCONN) {
    LOGGER_FATAL_AND_EXIT("invalid value for --server.backlog-size. maximum allowed value is " << SOMAXCONN);
  }

  if (_httpPort != "") {
    // issue #175: add hidden option --server.http-port for downwards-compatibility
    string httpEndpoint("tcp://" + _httpPort);
    _endpoints.push_back(httpEndpoint);
  }

  OperationMode::server_operation_mode_e mode = OperationMode::determineMode(options);
  if (_endpoints.empty() && mode == OperationMode::MODE_SERVER) {
    LOGGER_INFO("please use the '--server.endpoint' option");
    LOGGER_FATAL_AND_EXIT("no endpoint has been specified, giving up");
  }

  // add & validate endpoints
  for (vector<string>::const_iterator i = _endpoints.begin(); i != _endpoints.end(); ++i) {
    Endpoint* endpoint = Endpoint::serverFactory(*i, _backlogSize);

    if (endpoint == 0) {
      LOGGER_FATAL_AND_EXIT("invalid endpoint '" << *i << "'");
    }

    assert(endpoint);

    bool ok = _endpointList.addEndpoint(endpoint->getProtocol(), endpoint->getEncryption(), endpoint);
    if (! ok) {
      LOGGER_FATAL_AND_EXIT("invalid endpoint '" << *i << "'");
    }
  }

  // and return
  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::prepare () {
  // dump used endpoints for user information
  _endpointList.dump();

  _handlerFactory = new HttpHandlerFactory(_authenticationRealm, _checkAuthentication);

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::prepare2 () {
  // scheduler might be created after prepare(), so we need to use prepare2()!!
  Scheduler* scheduler = _applicationScheduler->scheduler();

  if (scheduler == 0) {
    LOGGER_FATAL_AND_EXIT("no scheduler is known, cannot create http server");

    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::open () {
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->startListening();
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::close () {
  // close all open connections
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->shutdownHandlers();
  }

  // close all listen sockets
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->stopListening();
  }
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::stop () {
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->stop();
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup HttpServer
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief creates an ssl context
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::createSslContext () {
  // check keyfile
  if (_httpsKeyfile.empty()) {
    return true;
  }

  // validate protocol
  if (_sslProtocol <= HttpsServer::SSL_UNKNOWN || _sslProtocol >= HttpsServer::SSL_LAST) {
    LOGGER_ERROR("invalid SSL protocol version specified.");
    LOGGER_INFO("please use a valid value for --server.ssl-protocol.");
    return false;
  }

  LOGGER_DEBUG("using SSL protocol version '" << HttpsServer::protocolName((HttpsServer::protocol_e) _sslProtocol) << "'");

  // create context
  _sslContext = HttpsServer::sslContext(HttpsServer::protocol_e(_sslProtocol), _httpsKeyfile);

  if (_sslContext == 0) {
    LOGGER_ERROR("failed to create SSL context, cannot create a HTTPS server");
    return false;
  }

  // set cache mode
  SSL_CTX_set_session_cache_mode(_sslContext, _sslCache ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_OFF);
  if (_sslCache) {
    LOGGER_TRACE("using SSL session caching");
  }

  // set options
  SSL_CTX_set_options(_sslContext, _sslOptions);
  LOGGER_INFO("using SSL options: " << _sslOptions);

  if (_sslCipherList.size() > 0) {
    LOGGER_INFO("using SSL cipher-list '" << _sslCipherList << "'");
    if (SSL_CTX_set_cipher_list(_sslContext, _sslCipherList.c_str()) != 1) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot set SSL cipher list '" << _sslCipherList << "'");
    }
  }

  // set ssl context
  Random::UniformCharacter r("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
  _rctx = r.random(SSL_MAX_SSL_SESSION_ID_LENGTH);

  int res = SSL_CTX_set_session_id_context(_sslContext, (unsigned char const*) _rctx.c_str(), _rctx.size());

  if (res != 1) {
    LOGGER_ERROR("ssl error: " << lastSSLError());
    LOGGER_FATAL_AND_EXIT("cannot set SSL session id context '" << _rctx << "'");
  }

  // check CA
  if (! _cafile.empty()) {
    LOGGER_TRACE("trying to load CA certificates from '" << _cafile << "'");

    int res = SSL_CTX_load_verify_locations(_sslContext, _cafile.c_str(), 0);

    if (res == 0) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot load CA certificates from '" << _cafile << "'");
    }

    STACK_OF(X509_NAME) * certNames;

    certNames = SSL_load_client_CA_file(_cafile.c_str());

    if (certNames == 0) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot load CA certificates from '" << _cafile << "'");
    }

    if (TRI_IsTraceLogging(__FILE__)) {
      for (int i = 0;  i < sk_X509_NAME_num(certNames);  ++i) {
        X509_NAME* cert = sk_X509_NAME_value(certNames, i);

        if (cert) {
          BIOGuard bout(BIO_new(BIO_s_mem()));

          X509_NAME_print_ex(bout._bio, cert, 0, (XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | ASN1_STRFLGS_UTF8_CONVERT) & ~ASN1_STRFLGS_ESC_MSB);

#ifdef TRI_ENABLE_LOGGER
          char* r;
          long len = BIO_get_mem_data(bout._bio, &r);

          LOGGER_TRACE("name: " << string(r, len));
#endif
        }
      }
    }

    SSL_CTX_set_client_CA_list(_sslContext, certNames);
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>issue #120: added examples for endpoint syntax in `arangod --help`<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief application endpoint server feature
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "ApplicationEndpointServer.h"

#include <openssl/err.h>

#include "Basics/delete_object.h"
#include "Basics/ssl-helper.h"
#include "Basics/RandomGenerator.h"
#include "Dispatcher/ApplicationDispatcher.h"
#include "HttpServer/HttpHandlerFactory.h"
#include "HttpServer/HttpServer.h"
#include "HttpServer/HttpsServer.h"
#include "Logger/Logger.h"
#include "Rest/OperationMode.h"
#include "Scheduler/ApplicationScheduler.h"

using namespace triagens::basics;
using namespace triagens::rest;
using namespace std;

// -----------------------------------------------------------------------------
// --SECTION--                                                   private classes
// -----------------------------------------------------------------------------

namespace {
  class BIOGuard {
    public:
      BIOGuard(BIO *bio)
        : _bio(bio) {
      }

      ~BIOGuard() {
        BIO_free(_bio);
      }

    public:
      BIO *_bio;
  };
}

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Scheduler
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////

ApplicationEndpointServer::ApplicationEndpointServer (ApplicationServer* applicationServer,
                                                      ApplicationScheduler* applicationScheduler,
                                                      ApplicationDispatcher* applicationDispatcher,
                                                      std::string const& authenticationRealm,
                                                      HttpHandlerFactory::auth_fptr checkAuthentication)
  : ApplicationFeature("EndpointServer"),
    _applicationServer(applicationServer),
    _applicationScheduler(applicationScheduler),
    _applicationDispatcher(applicationDispatcher),
    _authenticationRealm(authenticationRealm),
    _checkAuthentication(checkAuthentication),
    _handlerFactory(0),
    _servers(),
    _endpointList(),
    _httpPort(),
    _endpoints(),
    _disableAuthentication(false),
    _keepAliveTimeout(300.0),
    _backlogSize(10),
    _httpsKeyfile(),
    _cafile(),
    _sslProtocol(HttpsServer::TLS_V1),
    _sslCache(false),
    _sslOptions((uint64_t) (SSL_OP_TLS_ROLLBACK_BUG | SSL_OP_CIPHER_SERVER_PREFERENCE)),
    _sslCipherList(""),
    _sslContext(0),
    _rctx() {
}

////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////

ApplicationEndpointServer::~ApplicationEndpointServer () {

  // ..........................................................................
  // Where ever possible we should EXPLICITLY write down the type used in
  // a templated class/method etc. This makes it a lot easier to debug the
  // code. Granted however, that explicitly writing down the type for an
  // overloaded class operator is a little unwieldy.
  // ..........................................................................
  for_each(_servers.begin(), _servers.end(), triagens::basics::DeleteObjectAny());
  _servers.clear();

  if (_handlerFactory != 0) {
    delete _handlerFactory;
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Scheduler
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief builds the endpoint servers
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::buildServers () {
  assert(_handlerFactory != 0);
  assert(_applicationScheduler->scheduler() != 0);

  EndpointServer* server;

  // turn off authentication
  if (_disableAuthentication) {
    _handlerFactory->setRequireAuthentication(false);
    LOGGER_INFO("Authentication is turned off");
  }

  // unencrypted endpoints
  if (_endpointList.count(Endpoint::PROTOCOL_HTTP, Endpoint::ENCRYPTION_NONE) > 0) {
    // http endpoints
    server = new HttpServer(_applicationScheduler->scheduler(),
                            _applicationDispatcher->dispatcher(),
                            _keepAliveTimeout,
                            _handlerFactory);

    server->setEndpointList(&_endpointList);
    _servers.push_back(server);
  }

  // ssl endpoints
  if (_endpointList.count(Endpoint::PROTOCOL_HTTP, Endpoint::ENCRYPTION_SSL) > 0) {
    // check the ssl context
    if (_sslContext == 0) {
      LOGGER_INFO("please use the --server.keyfile option");
      LOGGER_FATAL_AND_EXIT("no ssl context is known, cannot create https server");
    }

    // https
    server = new HttpsServer(_applicationScheduler->scheduler(),
                             _applicationDispatcher->dispatcher(),
                             _keepAliveTimeout,
                             _handlerFactory,
                             _sslContext);

    server->setEndpointList(&_endpointList);
    _servers.push_back(server);
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                        ApplicationFeature methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup ApplicationServer
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::setupOptions (map<string, ProgramOptionsDescription>& options) {
  // issue #175: add deprecated hidden option for downwards compatibility
  options[ApplicationServer::OPTIONS_HIDDEN]
    ("server.http-port", &_httpPort, "http port for client requests (deprecated)")
  ;

  options[ApplicationServer::OPTIONS_SERVER]
    ("server.endpoint", &_endpoints, "endpoint for client requests (e.g. \"tcp://127.0.0.1:8529\", or \"ssl://192.168.1.1:8529\")")
  ;

  options[ApplicationServer::OPTIONS_SERVER + ":help-admin"]
    ("server.disable-authentication", &_disableAuthentication, "disable authentication for ALL client requests")
    ("server.keep-alive-timeout", &_keepAliveTimeout, "keep-alive timeout in seconds")
    ("server.backlog-size", &_backlogSize, "listen backlog size")
  ;

  options[ApplicationServer::OPTIONS_SERVER + ":help-ssl"]
    ("server.keyfile", &_httpsKeyfile, "keyfile for SSL connections")
    ("server.cafile", &_cafile, "file containing the CA certificates of clients")
    ("server.ssl-protocol", &_sslProtocol, "1 = SSLv2, 2 = SSLv23, 3 = SSLv3, 4 = TLSv1")
    ("server.ssl-cache", &_sslCache, "use SSL session caching")
    ("server.ssl-options", &_sslOptions, "ssl options, see OpenSSL documentation")
    ("server.ssl-cipher-list", &_sslCipherList, "ssl cipher list, see OpenSSL documentation")
  ;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::parsePhase2 (ProgramOptions& options) {
  // create the ssl context (if possible)
  bool ok = createSslContext();

  if (! ok) {
    return false;
  }

  if (_backlogSize <= 0 || _backlogSize > SOMAXCONN) {
    LOGGER_FATAL_AND_EXIT("invalid value for --server.backlog-size. maximum allowed value is " << SOMAXCONN);
  }

  if (_httpPort != "") {
    // issue #175: add hidden option --server.http-port for downwards-compatibility
    string httpEndpoint("tcp://" + _httpPort);
    _endpoints.push_back(httpEndpoint);
  }

  OperationMode::server_operation_mode_e mode = OperationMode::determineMode(options);
  if (_endpoints.empty() && mode == OperationMode::MODE_SERVER) {
    LOGGER_INFO("please use the '--server.endpoint' option");
    LOGGER_FATAL_AND_EXIT("no endpoint has been specified, giving up");
  }

  // add & validate endpoints
  for (vector<string>::const_iterator i = _endpoints.begin(); i != _endpoints.end(); ++i) {
    Endpoint* endpoint = Endpoint::serverFactory(*i, _backlogSize);

    if (endpoint == 0) {
      LOGGER_FATAL_AND_EXIT("invalid endpoint '" << *i << "'");
    }

    assert(endpoint);

    bool ok = _endpointList.addEndpoint(endpoint->getProtocol(), endpoint->getEncryption(), endpoint);
    if (! ok) {
      LOGGER_FATAL_AND_EXIT("invalid endpoint '" << *i << "'");
    }
  }

  // and return
  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::prepare () {
  // dump used endpoints for user information
  _endpointList.dump();

  _handlerFactory = new HttpHandlerFactory(_authenticationRealm, _checkAuthentication);

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::prepare2 () {
  // scheduler might be created after prepare(), so we need to use prepare2()!!
  Scheduler* scheduler = _applicationScheduler->scheduler();

  if (scheduler == 0) {
    LOGGER_FATAL_AND_EXIT("no scheduler is known, cannot create http server");

    return false;
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::open () {
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->startListening();
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::close () {
  // close all open connections
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->shutdownHandlers();
  }

  // close all listen sockets
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->stopListening();
  }
}

////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

void ApplicationEndpointServer::stop () {
  for (vector<EndpointServer*>::iterator i = _servers.begin();  i != _servers.end();  ++i) {
    EndpointServer* server = *i;

    server->stop();
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                   private methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup HttpServer
/// @{
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
/// @brief creates an ssl context
////////////////////////////////////////////////////////////////////////////////

bool ApplicationEndpointServer::createSslContext () {
  // check keyfile
  if (_httpsKeyfile.empty()) {
    return true;
  }

  // validate protocol
  if (_sslProtocol <= HttpsServer::SSL_UNKNOWN || _sslProtocol >= HttpsServer::SSL_LAST) {
    LOGGER_ERROR("invalid SSL protocol version specified.");
    LOGGER_INFO("please use a valid value for --server.ssl-protocol.");
    return false;
  }

  LOGGER_DEBUG("using SSL protocol version '" << HttpsServer::protocolName((HttpsServer::protocol_e) _sslProtocol) << "'");

  // create context
  _sslContext = HttpsServer::sslContext(HttpsServer::protocol_e(_sslProtocol), _httpsKeyfile);

  if (_sslContext == 0) {
    LOGGER_ERROR("failed to create SSL context, cannot create a HTTPS server");
    return false;
  }

  // set cache mode
  SSL_CTX_set_session_cache_mode(_sslContext, _sslCache ? SSL_SESS_CACHE_SERVER : SSL_SESS_CACHE_OFF);
  if (_sslCache) {
    LOGGER_TRACE("using SSL session caching");
  }

  // set options
  SSL_CTX_set_options(_sslContext, _sslOptions);
  LOGGER_INFO("using SSL options: " << _sslOptions);

  if (_sslCipherList.size() > 0) {
    LOGGER_INFO("using SSL cipher-list '" << _sslCipherList << "'");
    if (SSL_CTX_set_cipher_list(_sslContext, _sslCipherList.c_str()) != 1) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot set SSL cipher list '" << _sslCipherList << "'");
    }
  }

  // set ssl context
  Random::UniformCharacter r("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
  _rctx = r.random(SSL_MAX_SSL_SESSION_ID_LENGTH);

  int res = SSL_CTX_set_session_id_context(_sslContext, (unsigned char const*) _rctx.c_str(), _rctx.size());

  if (res != 1) {
    LOGGER_ERROR("ssl error: " << lastSSLError());
    LOGGER_FATAL_AND_EXIT("cannot set SSL session id context '" << _rctx << "'");
  }

  // check CA
  if (! _cafile.empty()) {
    LOGGER_TRACE("trying to load CA certificates from '" << _cafile << "'");

    int res = SSL_CTX_load_verify_locations(_sslContext, _cafile.c_str(), 0);

    if (res == 0) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot load CA certificates from '" << _cafile << "'");
    }

    STACK_OF(X509_NAME) * certNames;

    certNames = SSL_load_client_CA_file(_cafile.c_str());

    if (certNames == 0) {
      LOGGER_ERROR("ssl error: " << lastSSLError());
      LOGGER_FATAL_AND_EXIT("cannot load CA certificates from '" << _cafile << "'");
    }

    if (TRI_IsTraceLogging(__FILE__)) {
      for (int i = 0;  i < sk_X509_NAME_num(certNames);  ++i) {
        X509_NAME* cert = sk_X509_NAME_value(certNames, i);

        if (cert) {
          BIOGuard bout(BIO_new(BIO_s_mem()));

          X509_NAME_print_ex(bout._bio, cert, 0, (XN_FLAG_SEP_COMMA_PLUS | XN_FLAG_DN_REV | ASN1_STRFLGS_UTF8_CONVERT) & ~ASN1_STRFLGS_ESC_MSB);

#ifdef TRI_ENABLE_LOGGER
          char* r;
          long len = BIO_get_mem_data(bout._bio, &r);

          LOGGER_TRACE("name: " << string(r, len));
#endif
        }
      }
    }

    SSL_CTX_set_client_CA_list(_sslContext, certNames);
  }

  return true;
}

////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        ;

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Checkpoint at first 25-btc-reward block (210,000)<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
        ;

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
        (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
        (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
        (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1375533383, // * UNIX timestamp of last checkpoint block
        21491097,   // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1338180505,
        16341,
        300
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;
		return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;
		return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
		return 0;
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
		return NULL;
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Revert "Revert "Revert "Disable checkpoints"""<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        (193000, uint256("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317"))
        (210000, uint256("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e"))
        (216116, uint256("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e"))
        (225430, uint256("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932"))
        (250000, uint256("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1375533383, // * UNIX timestamp of last checkpoint block
        21491097,   // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1338180505,
        16341,
        300
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (  1500, uint256("0x841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967"))
        (  4032, uint256("0x9ce90e427198fc0ef05e5905ce3503725b80e26afd35a987965fd7e3d9cf0846"))
        (  8064, uint256("0xeb984353fc5190f210651f150c40b8a4bab9eeeff0b729fcb3987da694430d70"))
        ( 16128, uint256("0x602edf1859b7f9a6af809f1d9b0e6cb66fdc1d4d9dcd7a4bec03e12a1ccd153d"))
        ( 23420, uint256("0xd80fdf9ca81afd0bd2b2a90ac3a9fe547da58f2530ec874e978fce0b5101b507"))
        ( 50000, uint256("0x69dc37eb029b68f075a5012dcc0419c127672adb4f3a32882b2b3e71d07a20a6"))
        ( 80000, uint256("0x4fcb7c02f676a300503f49c764a89955a8f920b46a8cbecb4867182ecdb2e90a"))
        (120000, uint256("0xbd9d26924f05f6daa7f0155f32828ec89e8e29cee9e7121b026a7a3552ac6131"))
        (161500, uint256("0xdbe89880474f4bb4f75c227c77ba1cdc024991123b28b8418dbbf7798471ff43"))
        (179620, uint256("0x2ad9c65c990ac00426d18e446e0fd7be2ffa69e9a7dcb28358a50b2b78b9f709"))
        (240000, uint256("0x7140d1c4b4c2157ca217ee7636f24c9c73db39c4590c4e6eab2e3ea1555088aa"))
        (383640, uint256("0x2b6809f094a9215bafc65eb3f110a35127a34be94b7d0590a096c3f126c6f364"))
        (409004, uint256("0x487518d663d9f1fa08611d9395ad74d982b667fbdc0e77e9cf39b4f1355908a3"))
        (456000, uint256("0xbf34f71cc6366cd487930d06be22f897e34ca6a40501ac7d401be32456372004"))
        (541794, uint256("0x1cbccbe6920e7c258bbce1f26211084efb19764aa3224bec3f4320d77d6a2fd2"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1396366781, // * UNIX timestamp of last checkpoint block
        3854671,    // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        12000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1365458829,
        547,
        576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Litecoin: Checkpoint at block 585010<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (  1500, uint256("0x841a2965955dd288cfa707a755d05a54e45f8bd476835ec9af4402a2b59a2967"))
        (  4032, uint256("0x9ce90e427198fc0ef05e5905ce3503725b80e26afd35a987965fd7e3d9cf0846"))
        (  8064, uint256("0xeb984353fc5190f210651f150c40b8a4bab9eeeff0b729fcb3987da694430d70"))
        ( 16128, uint256("0x602edf1859b7f9a6af809f1d9b0e6cb66fdc1d4d9dcd7a4bec03e12a1ccd153d"))
        ( 23420, uint256("0xd80fdf9ca81afd0bd2b2a90ac3a9fe547da58f2530ec874e978fce0b5101b507"))
        ( 50000, uint256("0x69dc37eb029b68f075a5012dcc0419c127672adb4f3a32882b2b3e71d07a20a6"))
        ( 80000, uint256("0x4fcb7c02f676a300503f49c764a89955a8f920b46a8cbecb4867182ecdb2e90a"))
        (120000, uint256("0xbd9d26924f05f6daa7f0155f32828ec89e8e29cee9e7121b026a7a3552ac6131"))
        (161500, uint256("0xdbe89880474f4bb4f75c227c77ba1cdc024991123b28b8418dbbf7798471ff43"))
        (179620, uint256("0x2ad9c65c990ac00426d18e446e0fd7be2ffa69e9a7dcb28358a50b2b78b9f709"))
        (240000, uint256("0x7140d1c4b4c2157ca217ee7636f24c9c73db39c4590c4e6eab2e3ea1555088aa"))
        (383640, uint256("0x2b6809f094a9215bafc65eb3f110a35127a34be94b7d0590a096c3f126c6f364"))
        (409004, uint256("0x487518d663d9f1fa08611d9395ad74d982b667fbdc0e77e9cf39b4f1355908a3"))
        (456000, uint256("0xbf34f71cc6366cd487930d06be22f897e34ca6a40501ac7d401be32456372004"))
        (541794, uint256("0x1cbccbe6920e7c258bbce1f26211084efb19764aa3224bec3f4320d77d6a2fd2"))
        (585010, uint256("0xea9ea06840de20a18a66acb07c9102ee6374ad2cbafc71794e576354fea5df2d"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1402691751, // * UNIX timestamp of last checkpoint block
        4404988,    // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        10000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1365458829,
        547,
        576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014 Kryptohash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

#include <stdint.h>

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

namespace Checkpoints
{
    typedef std::map<int64_t, uint320> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64_t nTimeLastCheckpoint;
        int64_t nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    bool fEnabled = true;

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (99, uint320("00000018CE97B434F8396CB989C61190BB72B8CD2A7352C48C91AEDB2E0F8AFCE8CDB7A59334E95B"))
        (5000, uint320("0000000BC13E7BCFC9CFB664D4EA05D6732F5FB49DED407DA33E45FE351A5BD3A81F003BFC2096AC"))
        (5098, uint320("0000000853574F2FEEEE8EE642C72D8E1A40DBDFAFD01CC1B8F23EE6EBC565B16EDFF9E336B0DA0F"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        0x14A1D085120, // * UNIX timestamp of last checkpoint block
        12084,         // * total number of transactions between genesis and last checkpoint
                       //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0        // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint320(0))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        0x1488DDBA3EE,
        0,
        300.0
    };

    static MapCheckpoints mapCheckpointsRegtest =
        boost::assign::map_list_of
        ( 0, uint320(0))
        ;
    static const CCheckpointData dataRegtest = {
        &mapCheckpointsRegtest,
        0,
        0,
        0
    };

    const CCheckpointData &Checkpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET) {
            return dataTestnet;
        }
        else if (Params().NetworkID() == CChainParams::MAIN) {
            return data;
        }
        else {
            return dataRegtest;
        }
    }

    bool CheckBlock(int64_t nHeight, const uint320& hash)
    {
        if (!fEnabled) {
            return true;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) {
            return true;
        }
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
        if (pindex == NULL) {
            return 0.0;
        }
        int64_t nNow = time(NULL);

        double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkpoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int64_t GetTotalBlocksEstimate()
    {
        if (!fEnabled) {
            return 0;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint320, CBlockIndex*>& mapBlockIndex)
    {
        if (!fEnabled) {
            return NULL;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint320& hash = i.second;
            std::map<uint320, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end()) {
                return t->second;
            }
        }
        return NULL;
    }
}

namespace PIDCheckpoints
{
    typedef std::map<int64_t, CPID> MapPIDCheckpoints;

    struct CPIDCheckpointData {
        const MapPIDCheckpoints *mapPIDCheckpoints;
        int64_t nTimeLastCheckpoint;
    };

    bool fEnabled = true;

    static MapPIDCheckpoints mapPIDCheckpoints =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        ;
    static const CPIDCheckpointData data = {
        &mapPIDCheckpoints,
        0x148d455b42a // * timestamp of last PID checkpoint
    };

    static MapPIDCheckpoints mapPIDCheckpointsTestnet =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        ;
    static const CPIDCheckpointData dataTestnet = {
        &mapPIDCheckpointsTestnet,
        0x148d455b42a
    };

    static MapPIDCheckpoints mapPIDCheckpointsRegtest =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        ;
    static const CPIDCheckpointData dataRegtest = {
        &mapPIDCheckpointsRegtest,
        0
    };

    const CPIDCheckpointData &PIDCheckpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET) {
            return dataTestnet;
        }
        else if (Params().NetworkID() == CChainParams::MAIN) {
            return data;
        }
        else {
            return dataRegtest;
        }
    }

    int64_t PIDGetHeightLastCheckpoint()
    {
        if (!fEnabled) {
            return 0;
        }
        const MapPIDCheckpoints& PIDcheckpoints = *PIDCheckpoints().mapPIDCheckpoints;

        return PIDcheckpoints.rbegin()->first;
    }

    int64_t PIDGetTimeLastCheckpoint()
    {
        if (!fEnabled) {
            return 0;
        }
        const int64_t PIDcheckpointTime = PIDCheckpoints().nTimeLastCheckpoint;

        return PIDcheckpointTime;
    }

    const CPID* GetPIDCheckpoint(int64_t height)
    {
        if (!fEnabled) {
            return NULL;
        }
        const MapPIDCheckpoints& PIDcheckpoints = *PIDCheckpoints().mapPIDCheckpoints;

        BOOST_REVERSE_FOREACH(const MapPIDCheckpoints::value_type& i, PIDcheckpoints)
        {
            if (i.first <= height) {
                const CPID& PIDChkpoint = i.second;
                return &PIDChkpoint;
            }
        }
        return NULL;
    }

}
<commit_msg>New checkpoint at 5600<commit_after>// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014 Kryptohash developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

#include <stdint.h>

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

namespace Checkpoints
{
    typedef std::map<int64_t, uint320> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double SIGCHECK_VERIFICATION_FACTOR = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64_t nTimeLastCheckpoint;
        int64_t nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    bool fEnabled = true;

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (99, uint320("00000018CE97B434F8396CB989C61190BB72B8CD2A7352C48C91AEDB2E0F8AFCE8CDB7A59334E95B"))
        (5000, uint320("0000000BC13E7BCFC9CFB664D4EA05D6732F5FB49DED407DA33E45FE351A5BD3A81F003BFC2096AC"))
        (5098, uint320("0000000853574F2FEEEE8EE642C72D8E1A40DBDFAFD01CC1B8F23EE6EBC565B16EDFF9E336B0DA0F"))
        (5600, uint320("000000012A064B7393C4A6C6CCD71B52640804A5DD8ABE76FDE35AD12EF00D7FE3DCE691938535DD"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        0x14A283B4E58, // * UNIX timestamp of last checkpoint block
        13736,         // * total number of transactions between genesis and last checkpoint
                       //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0        // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint320(0))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        0x1488DDBA3EE,
        0,
        300.0
    };

    static MapCheckpoints mapCheckpointsRegtest =
        boost::assign::map_list_of
        ( 0, uint320(0))
        ;
    static const CCheckpointData dataRegtest = {
        &mapCheckpointsRegtest,
        0,
        0,
        0
    };

    const CCheckpointData &Checkpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET) {
            return dataTestnet;
        }
        else if (Params().NetworkID() == CChainParams::MAIN) {
            return data;
        }
        else {
            return dataRegtest;
        }
    }

    bool CheckBlock(int64_t nHeight, const uint320& hash)
    {
        if (!fEnabled) {
            return true;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) {
            return true;
        }
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) {
        if (pindex == NULL) {
            return 0.0;
        }
        int64_t nNow = time(NULL);

        double fSigcheckVerificationFactor = fSigchecks ? SIGCHECK_VERIFICATION_FACTOR : 1.0;
        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkpoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int64_t GetTotalBlocksEstimate()
    {
        if (!fEnabled) {
            return 0;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint320, CBlockIndex*>& mapBlockIndex)
    {
        if (!fEnabled) {
            return NULL;
        }
        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint320& hash = i.second;
            std::map<uint320, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end()) {
                return t->second;
            }
        }
        return NULL;
    }
}

namespace PIDCheckpoints
{
    typedef std::map<int64_t, CPID> MapPIDCheckpoints;

    struct CPIDCheckpointData {
        const MapPIDCheckpoints *mapPIDCheckpoints;
        int64_t nTimeLastCheckpoint;
    };

    bool fEnabled = true;

    static MapPIDCheckpoints mapPIDCheckpoints =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        (5600, CPID(180.0f, 1.0f, 0.05f, 0.1f, 0.0f, 0.0f, 0.0f, 0, 5599, 180.0f, 0x2507ffff))
        ;
    static const CPIDCheckpointData data = {
        &mapPIDCheckpoints,
        0x148d455b42a // * timestamp of last PID checkpoint
    };

    static MapPIDCheckpoints mapPIDCheckpointsTestnet =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        ;
    static const CPIDCheckpointData dataTestnet = {
        &mapPIDCheckpointsTestnet,
        0x148d455b42a
    };

    static MapPIDCheckpoints mapPIDCheckpointsRegtest =
        boost::assign::map_list_of
        (0, CPID(180.0f, 1.0f, 0.05f, 0.1f))
        ;
    static const CPIDCheckpointData dataRegtest = {
        &mapPIDCheckpointsRegtest,
        0
    };

    const CPIDCheckpointData &PIDCheckpoints() {
        if (Params().NetworkID() == CChainParams::TESTNET) {
            return dataTestnet;
        }
        else if (Params().NetworkID() == CChainParams::MAIN) {
            return data;
        }
        else {
            return dataRegtest;
        }
    }

    int64_t PIDGetHeightLastCheckpoint()
    {
        if (!fEnabled) {
            return 0;
        }
        const MapPIDCheckpoints& PIDcheckpoints = *PIDCheckpoints().mapPIDCheckpoints;

        return PIDcheckpoints.rbegin()->first;
    }

    int64_t PIDGetTimeLastCheckpoint()
    {
        if (!fEnabled) {
            return 0;
        }
        const int64_t PIDcheckpointTime = PIDCheckpoints().nTimeLastCheckpoint;

        return PIDcheckpointTime;
    }

    const CPID* GetPIDCheckpoint(int64_t height)
    {
        if (!fEnabled) {
            return NULL;
        }
        const MapPIDCheckpoints& PIDcheckpoints = *PIDCheckpoints().mapPIDCheckpoints;

        BOOST_REVERSE_FOREACH(const MapPIDCheckpoints::value_type& i, PIDcheckpoints)
        {
            if (i.first <= height) {
                const CPID& PIDChkpoint = i.second;
                return &PIDChkpoint;
            }
        }
        return NULL;
    }

}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2014 NobleCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
            (     0, uint256("0xdbf8ee8b91b5f03d7786cb1d58f2588538b2d48d8c23a7913db5aac7bb58c481"))
			(	100, uint256("0x000cedc00442c5ecb96ec2f3d81e5513c59ec31f82cdfda95d939fab5f1a7696"))
			(	150, uint256("0xc977085510cb7256d7a7b96acfe851ee34f7dba91170b102ff80e0526ec2441a"))
			(	10000, uint256("0x621cb4ceab38c59da38cfe59c5e9547f0bbf324c374de8111fc6a15f31a39452"))
			(	50000, uint256("0xe8358688715339d51e0450bd1e9e3749bd940b31d4fc90b9eaf4530b2c8ffb9b"))
			(	100000, uint256("0xdaa983f98f6cf60f98dcd3151fe82b16f7825fecc657f0c29e13ac62d0351e81"))
			(	140000, uint256("0x8b525c5c5ac84021d5aae16b8d85a3977a91461c157733423de756fe32ce1637"))
			(	170000, uint256("0x8fd23e16bc80406154df4cf083ba35fe53d876a3ead261af86f8cfbaef344919"))
			(	219718, uint256("0x0e1dd6ee774d8f30594fa40ce550e4a938449726b1d326471d7ea47c73d6c4e0"))
			(	280000, uint256("0x68146cdfca86f2c644fbdcae80a24e4fe3c2adbe922730eb8a0cb0440c12bc86"))
			;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }

        return NULL;
    }
}
<commit_msg>Update checkpoints.cpp<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2014 NobleCoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    static MapCheckpoints mapCheckpoints =
            boost::assign::map_list_of
            (     0, uint256("0xdbf8ee8b91b5f03d7786cb1d58f2588538b2d48d8c23a7913db5aac7bb58c481"))
			(	100, uint256("0x000cedc00442c5ecb96ec2f3d81e5513c59ec31f82cdfda95d939fab5f1a7696"))
			(	150, uint256("0xc977085510cb7256d7a7b96acfe851ee34f7dba91170b102ff80e0526ec2441a"))
			(	10000, uint256("0x621cb4ceab38c59da38cfe59c5e9547f0bbf324c374de8111fc6a15f31a39452"))
			(	50000, uint256("0xe8358688715339d51e0450bd1e9e3749bd940b31d4fc90b9eaf4530b2c8ffb9b"))
			(	100000, uint256("0xdaa983f98f6cf60f98dcd3151fe82b16f7825fecc657f0c29e13ac62d0351e81"))
			(	140000, uint256("0x8b525c5c5ac84021d5aae16b8d85a3977a91461c157733423de756fe32ce1637"))
			(	170000, uint256("0x8fd23e16bc80406154df4cf083ba35fe53d876a3ead261af86f8cfbaef344919"))
			(	219718, uint256("0x0e1dd6ee774d8f30594fa40ce550e4a938449726b1d326471d7ea47c73d6c4e0"))
			(	280000, uint256("0x68146cdfca86f2c644fbdcae80a24e4fe3c2adbe922730eb8a0cb0440c12bc86"))
			(	385291, uint256("0xfa5776daa57c46853089411e501bb455d893de2ea79dff1f96e85d1b0907a2dc"))
			;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }

        return NULL;
    }
}
<|endoftext|>


<commit_before>// OpenLieroX

// Input box
// Created 30/3/03
// Jason Boettcher

#include "defs.h"
#include "LieroX.h"
#include "Menu.h"

///////////////////
// Draw the frame into a buffer
void CFrame::PreDraw(void)
{
	// Create the buffer, if needed
	if (!bmpBuffer)  {
		SDL_PixelFormat *fmt = SDL_GetVideoSurface()->format;
		if (fmt)
			bmpBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,iWidth,iHeight,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask);
		else
			bmpBuffer = NULL;

		if (!bmpBuffer)
			return;
	}

	// Set the whole buffer transparent
	SDL_SetColorKey(bmpBuffer, SDL_SRCCOLORKEY, SDL_MapRGB(bmpBuffer->format,255,0,255));
	DrawRectFill(bmpBuffer,0,0,iWidth,iHeight,MakeColour(255,0,255));

	//
	// 1. Draw the lines
	//
	int line_left,line_right,line_top,line_bottom;

	line_left = iRound;
	line_right = iWidth - iRound;
	line_top = iRound;
	line_bottom = iHeight - iRound;

	Uint32 cur_col = iDarkColour;
	Uint8 dark_r,dark_g,dark_b;
	SDL_GetRGB(iDarkColour,bmpBuffer->format,&dark_r,&dark_g,&dark_b);
	Uint8 light_r,light_g,light_b;
	SDL_GetRGB(iLightColour,bmpBuffer->format,&light_r,&light_g,&light_b);
	int rstep,gstep,bstep;
	if (iBorder)  {
		rstep = (light_r-dark_r)/iBorder;
		gstep = (light_g-dark_g)/iBorder;
		bstep = (light_b-dark_b)/iBorder;
	}

	// Top line
	for (int j=0; j<iBorder; j++)  {
		DrawHLine(bmpBuffer,line_left,line_right,iY+j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Bottom line
	for (j=0; j<iBorder; j++)  {
		DrawHLine(bmpBuffer,line_left,line_right,iY+iHeight-j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Left line
	for (j=0; j<iBorder; j++)  {
		DrawVLine(bmpBuffer,line_top,line_bottom,iX+j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Right line
	for (j=0; j<iBorder; j++)  {
		DrawVLine(bmpBuffer,line_top,line_bottom,iX+iWidth-j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	//
	// 2. Draw the round borders
	//

	int x,y;

	float fStart = GetMilliSeconds();

	// Top left
	// (1,3/2*PI)
	float step = 1/(PI*iRound*(iBorder+0.0000001));
	for (float i=1.00;i<1.5;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (iRound-j)*sin(PI*i)-1;
			y = (iRound-j)*cos(PI*i)-1;
			PutPixel(bmpBuffer,x+iRound,y+iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Top right
	// (PI/2,PI)
	for (i=0.50;i<1;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (iRound-j)*sin(PI*i)+1;
			y = (iRound-j)*cos(PI*i)-1;
			PutPixel(bmpBuffer,x+iWidth-iRound,y+iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Bottom left
	// (3/2*PI,2PI)
	for (i=1.50;i<2;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (iRound-j)*sin(PI*i)-1;
			y = (iRound-j)*cos(PI*i)+1;
			PutPixel(bmpBuffer,x+iRound,y+iHeight-iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Bottom right
	// (0,PI)
	for (i=-0.01;i<0.5;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (iRound-j)*sin(PI*i)+1;
			y = (iRound-j)*cos(PI*i)+1;
			PutPixel(bmpBuffer,x+iWidth-iRound,y+iHeight-iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	float fLength = (GetMilliSeconds()-fStart)*1000;

}

/////////////////
// Draw the frame
void CFrame::Draw(SDL_Surface *bmpDest)
{
	if (bmpBuffer)
		DrawImage(bmpDest,bmpBuffer,iX,iY);
}

/////////////////
// Free the widget
void CFrame::Destroy(void)
{
	if(bmpBuffer) {
		SDL_FreeSurface(bmpBuffer);
		bmpBuffer = NULL;
	}
}<commit_msg>small fixes of non ANSI standard code<commit_after>// OpenLieroX

// Input box
// Created 30/3/03
// Jason Boettcher

#include "defs.h"
#include "LieroX.h"
#include "Menu.h"

///////////////////
// Draw the frame into a buffer
void CFrame::PreDraw(void)
{
	// Create the buffer, if needed
	if (!bmpBuffer)  {
		SDL_PixelFormat *fmt = SDL_GetVideoSurface()->format;
		if (fmt)
			bmpBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,iWidth,iHeight,fmt->BitsPerPixel,fmt->Rmask,fmt->Gmask,fmt->Bmask,fmt->Amask);
		else
			bmpBuffer = NULL;

		if (!bmpBuffer)
			return;
	}

	// Set the whole buffer transparent
	SDL_SetColorKey(bmpBuffer, SDL_SRCCOLORKEY, SDL_MapRGB(bmpBuffer->format,255,0,255));
	DrawRectFill(bmpBuffer,0,0,iWidth,iHeight,MakeColour(255,0,255));

	//
	// 1. Draw the lines
	//
	int line_left,line_right,line_top,line_bottom;

	line_left = iRound;
	line_right = iWidth - iRound;
	line_top = iRound;
	line_bottom = iHeight - iRound;

	Uint32 cur_col = iDarkColour;
	Uint8 dark_r,dark_g,dark_b;
	SDL_GetRGB(iDarkColour,bmpBuffer->format,&dark_r,&dark_g,&dark_b);
	Uint8 light_r,light_g,light_b;
	SDL_GetRGB(iLightColour,bmpBuffer->format,&light_r,&light_g,&light_b);
	int rstep,gstep,bstep;
	if (iBorder)  {
		rstep = (light_r-dark_r)/iBorder;
		gstep = (light_g-dark_g)/iBorder;
		bstep = (light_b-dark_b)/iBorder;
	}

	// Top line
	int j;
	for (j=0; j<iBorder; j++)  {
		DrawHLine(bmpBuffer,line_left,line_right,iY+j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Bottom line
	for (j=0; j<iBorder; j++)  {
		DrawHLine(bmpBuffer,line_left,line_right,iY+iHeight-j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Left line
	for (j=0; j<iBorder; j++)  {
		DrawVLine(bmpBuffer,line_top,line_bottom,iX+j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	cur_col = iDarkColour;

	// Right line
	for (j=0; j<iBorder; j++)  {
		DrawVLine(bmpBuffer,line_top,line_bottom,iX+iWidth-j,cur_col);
		cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
	}

	//
	// 2. Draw the round borders
	//

	int x,y;

	float fStart = GetMilliSeconds();

	// Top left
	// (1,3/2*PI)
	float step = 1/(PI*iRound*(iBorder+0.0000001));
	float i;
	for (i=1.00;i<1.5;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<(int)iBorder; j++)  {
			x = (int)((iRound-j)*sin(PI*i)-1);
			y = (int)((iRound-j)*cos(PI*i)-1);
			PutPixel(bmpBuffer,x+iRound,y+iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Top right
	// (PI/2,PI)
	for (i=0.50;i<1;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (int)((iRound-j)*sin(PI*i)+1);
			y = (int)((iRound-j)*cos(PI*i)-1);
			PutPixel(bmpBuffer,x+iWidth-iRound,y+iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Bottom left
	// (3/2*PI,2PI)
	for (i=1.50;i<2;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (int)((iRound-j)*sin(PI*i)-1);
			y = (int)((iRound-j)*cos(PI*i)+1);
			PutPixel(bmpBuffer,x+iRound,y+iHeight-iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	// Bottom right
	// (0,PI)
	for (i=-0.01;i<0.5;i+=step)  {
		cur_col = iDarkColour;
		for (j=0; j<iBorder; j++)  {
			x = (int)((iRound-j)*sin(PI*i)+1);
			y = (int)((iRound-j)*cos(PI*i)+1);
			PutPixel(bmpBuffer,x+iWidth-iRound,y+iHeight-iRound,cur_col);
			cur_col = MakeColour(dark_r+rstep*(j+1),dark_g+gstep*(j+1),dark_b+bstep*(j+1));
		}
	}

	float fLength = (GetMilliSeconds()-fStart)*1000;

}

/////////////////
// Draw the frame
void CFrame::Draw(SDL_Surface *bmpDest)
{
	if (bmpBuffer)
		DrawImage(bmpDest,bmpBuffer,iX,iY);
}

/////////////////
// Free the widget
void CFrame::Destroy(void)
{
	if(bmpBuffer) {
		SDL_FreeSurface(bmpBuffer);
		bmpBuffer = NULL;
	}
}
<|endoftext|>