text:
//  boost/chrono/process_times.hpp  -----------------------------------------------------------//

//  Copyright Beman Dawes 1994, 2007, 2008
//  Copyright Vicente J Botet Escriba 2009-2010

//  Distributed under the Boost Software License, Version 1.0.
//  See http://www.boost.org/LICENSE_1_0.txt

//  See http://www.boost.org/libs/system for documentation.

#ifndef BOOST_PROCESS_TIMES_HPP
#define BOOST_PROCESS_TIMES_HPP

#include <boost/chrono/duration.hpp>
#include <boost/chrono/time_point.hpp>
#include <boost/system/error_code.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include <ostream>
#include <boost/chrono/detail/system.hpp>

#ifndef BOOST_CHRONO_HEADER_ONLY
#include <boost/config/abi_prefix.hpp> // must be the last #include
#endif

namespace boost
{
namespace chrono
{
//--------------------------------------------------------------------------------------//
//                                  process_clock                                       //
//--------------------------------------------------------------------------------------//

    class BOOST_CHRONO_DECL process_clock
    {
    public:
        typedef nanoseconds                          duration;
        typedef duration::rep                        rep;
        typedef duration::period                     period;
        typedef chrono::time_point<process_clock>    time_point;
        BOOST_CHRONO_STATIC_CONSTEXPR bool is_steady =             true;

        struct durations
        {
          process_clock::duration                       real;    // real (i.e wall clock) time
          process_clock::duration                       user;    // user cpu time
          process_clock::duration                       system;  // system cpu time
        };
        struct time_points
        {
          process_clock::time_point                       real;    // real (i.e wall clock) time
          process_clock::time_point                       user;    // user cpu time
          process_clock::time_point                       system;  // system cpu time
        };

        static BOOST_CHRONO_INLINE void now( durations & times,
                         system::error_code & ec = BOOST_CHRONO_THROWS );
        static BOOST_CHRONO_INLINE void now( time_points & times,
                         system::error_code & ec = BOOST_CHRONO_THROWS );
    };

//--------------------------------------------------------------------------------------//
//                                  process_times                                       //
//--------------------------------------------------------------------------------------//

    typedef process_clock::durations process_times;

//--------------------------------------------------------------------------------------//
//                                  process_timer                                       //
//--------------------------------------------------------------------------------------//

    class BOOST_CHRONO_DECL process_timer
    // BOOST_CHRONO_DECL is required to quiet compiler warnings even though
    // process_timer has no dynamically linked members, because process_timer is
    // used as a base class for run_timer, which does have dynamically linked members.
    {
    public:

      typedef process_clock                          clock;
      typedef process_clock::duration                duration;
      typedef process_clock::time_point              time_point;

      explicit process_timer( system::error_code & ec = BOOST_CHRONO_THROWS )
      {
        start(ec);
      }

     ~process_timer() {}  // never throws()

      void  start( system::error_code & ec = BOOST_CHRONO_THROWS )
      {
        process_clock::now( m_start, ec );
      }

      void  elapsed( process_times & times, system::error_code & ec = BOOST_CHRONO_THROWS )
      {
        process_times end;
        process_clock::now( end, ec );
        times.real  = end.real - m_start.real;
        times.user       = end.user - m_start.user;
        times.system     = end.system - m_start.system;
      }

    protected:
      process_times   m_start;
    private:
      process_timer(const process_timer&); // = delete;
      process_timer& operator=(const process_timer&); // = delete;
    };

//--------------------------------------------------------------------------------------//
//                                    run_timer                                         //
//--------------------------------------------------------------------------------------//

    class BOOST_CHRONO_DECL run_timer : public process_timer
    {
      // every function making use of inlined functions of class string are not inlined to avoid DLL issues
    public:

      // each constructor form has two overloads to avoid a visible default to
      // std::cout, which in turn would require including <iostream>, with its
      // high associated cost, even when the standard streams are not used.

      BOOST_CHRONO_INLINE
      explicit run_timer( system::error_code & ec = BOOST_CHRONO_THROWS );
      BOOST_CHRONO_INLINE
      explicit run_timer( std::ostream & os,
        system::error_code & ec = BOOST_CHRONO_THROWS );

      BOOST_CHRONO_INLINE
      explicit run_timer( const std::string & format,
        system::error_code & ec = BOOST_CHRONO_THROWS );
      BOOST_CHRONO_INLINE
      run_timer( std::ostream & os, const std::string & format,
        system::error_code & ec = BOOST_CHRONO_THROWS );

      BOOST_CHRONO_INLINE
      run_timer( const std::string & format, int places,
        system::error_code & ec = BOOST_CHRONO_THROWS );
      BOOST_CHRONO_INLINE
      run_timer( std::ostream & os, const std::string & format,
        int places, system::error_code & ec = BOOST_CHRONO_THROWS );

      BOOST_CHRONO_INLINE
      explicit run_timer( int places,
        system::error_code & ec = BOOST_CHRONO_THROWS );
      BOOST_CHRONO_INLINE
      run_timer( std::ostream & os, int places,
        system::error_code & ec = BOOST_CHRONO_THROWS );

      BOOST_CHRONO_INLINE
      run_timer( int places, const std::string & format,
        system::error_code & ec = BOOST_CHRONO_THROWS );
      BOOST_CHRONO_INLINE
      run_timer( std::ostream & os, int places, const std::string & format,
        system::error_code & ec = BOOST_CHRONO_THROWS );

      ~run_timer()  // never throws
      {
        system::error_code ec;
        if ( !reported() ) report( ec );
      }

      BOOST_CHRONO_INLINE void  start( system::error_code & ec = BOOST_CHRONO_THROWS )
      {
        m_reported = false;
        process_timer::start( ec );
      }

      BOOST_CHRONO_INLINE void  report( system::error_code & ec = BOOST_CHRONO_THROWS );

      BOOST_CHRONO_INLINE void  test_report( duration real_, duration user_, duration system_ );

      BOOST_CHRONO_INLINE bool  reported() const { return m_reported; }

      BOOST_CHRONO_INLINE static int default_places() { return m_default_places; }

    private:
      int             m_places;
      std::ostream &  m_os;

#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable:4251)
#endif
      std::string     m_format;
#if defined _MSC_VER
#pragma warning(pop)
#endif
      bool            m_reported;

      BOOST_CHRONO_INLINE static std::ostream &  m_cout();
      //{return std::cout;}
      static const int m_default_places = 3;
      run_timer(const run_timer&); // = delete;
      run_timer& operator=(const run_timer&); // = delete;
    };

  } // namespace chrono
} // namespace boost

#ifndef BOOST_CHRONO_HEADER_ONLY
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#else
#include <boost/chrono/detail/inlined/process_clock.hpp>
#include <boost/chrono/detail/inlined/run_timer.hpp>
#include <boost/chrono/detail/inlined/run_timer_static.hpp>
#endif

#endif  // BOOST_PROCESS_TIMES_HPP

max_stars_repo_name: zigaosolin/Raytracer

max_issues_repo_name: zigaosolin/Raytracer

max_forks_repo_name: zigaosolin/Raytracer


text:
/* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <array>
#include <vector>
#include <utility>
#include <iostream>
#include <cstdint>
#include <map>
#include <random>
#include <boost/multiprecision/cpp_int.hpp>

using namespace boost::multiprecision;

//------------------------------------
//              Factors
//------------------------------------

typedef std::pair<unsigned long, int> Factor;

class Factors
{
 private:
  unsigned long n_;
  std::vector<unsigned long> all_factors_;
  std::vector<std::vector<unsigned long>> cofactors_;

  unsigned long ISqrt_(unsigned long x);

  void CalculateAllFactors_();

  // Return a vector of all order-way cofactor sets of n.
  std::vector<std::vector<unsigned long>> MultiplicativeSplitRecursive_(unsigned long n, int order);

 public:
  Factors();
  Factors(const unsigned long n, const int order);
  Factors(const unsigned long n, const int order, std::map<unsigned, unsigned long> given);

  void PruneMax(std::map<unsigned, unsigned long>& max);

  std::vector<unsigned long>& operator[](int index);

  std::size_t size();

  void Print();
  void PrintAllFactors();
  void PrintCoFactors();

  friend std::ostream& operator<<(std::ostream& out, const Factors& f);
};

//------------------------------------
//        Cartesian Counter
//------------------------------------

template <int order>
class CartesianCounter
{
 private:
  // Note: base is variable for each position!
  std::array<uint128_t, order> base_;
  std::array<uint128_t, order> value_;
  checked_uint128_t integer_;
  checked_uint128_t endint_;

  bool IncrementRecursive_(int position)
  {
    if (value_[position] < base_[position] - 1)
    {
      value_[position]++;
      return true;
    }
    else if (position < order - 1)
    {
      value_[position] = 0;
      return IncrementRecursive_(position + 1);
    }
    else
    {
      // Overflow! We could do one of 3 things:
      // (a) Throw an exception.
      // (b) Wrap-around to 0.
      // (c) Saturate and return a code.
      // We choose (c) for this implementation.
      return false;
    }
  }

  void UpdateIntegerFromValue()
  {
    integer_ = 0;
    checked_uint128_t base = 1;
    for (int i = 0; i < order; i++)
    {
      integer_ += (checked_uint128_t(value_[i]) * base);
      base *= base_[i];
    }
  }

  void UpdateValueFromInteger()
  {
    uint128_t n = integer_;
    for (int i = 0; i < order; i++)
    {
      value_[i] = n % base_[i];
      n = n / base_[i];
    }
  }

 public:
  CartesianCounter(std::array<uint128_t, order> base = {})
  {
    Init(base);
  }

  template<typename T>
  void Init(T base)
  {
    value_ = {};
    integer_ = 0;
    endint_ = 1;
    for (int i = 0; i < order; i++)
    {
      base_[i] = base[i];
      endint_ *= checked_uint128_t(base_[i]);
    }
  }

  bool Increment()
  {
    integer_++;
    return IncrementRecursive_(0);
  }

  std::array<uint128_t, order> Read() const
  {
    return value_;
  }

  std::array<uint128_t, order> Base() const
  {
    return base_;
  }

  uint128_t operator[] (int dim)
  {
    return value_[dim];
  }

  void Set(uint128_t n)
  {
    assert(checked_uint128_t(n) < endint_);
    integer_ = n;
    UpdateValueFromInteger();
  }

  void Set(int dim, uint128_t v)
  {
    value_[dim] = v;
    UpdateIntegerFromValue();
    assert(integer_ < endint_);
  }

  void Set(std::array<uint128_t, order> v)
  {
    value_ = v;
    UpdateIntegerFromValue();
    assert(integer_ < endint_);
  }

  uint128_t EndInteger() const
  {
    return endint_;
  }

  uint128_t Integer() const
  {
    return integer_;
  }
};

//------------------------------------
//    Cartesian Counter (dynamic)
//------------------------------------

class CartesianCounterDynamic
{
 private:
  // Note: base is variable for each position!
  int order_;
  std::vector<uint128_t> base_;
  std::vector<uint128_t> value_;
  checked_uint128_t integer_;
  checked_uint128_t endint_;

  bool IncrementRecursive_(int position)
  {
    if (value_[position] < base_[position] - 1)
    {
      value_[position]++;
      return true;
    }
    else if (position < order_ - 1)
    {
      value_[position] = 0;
      return IncrementRecursive_(position + 1);
    }
    else
    {
      // Overflow! We could do one of 3 things:
      // (a) Throw an exception.
      // (b) Wrap-around to 0.
      // (c) Saturate and return a code.
      // We choose (c) for this implementation.
      return false;
    }
  }

  void UpdateIntegerFromValue()
  {
    integer_ = 0;
    checked_uint128_t base = 1;
    for (int i = 0; i < order_; i++)
    {
      integer_ += (checked_uint128_t(value_[i]) * base);
      base *= base_[i];
    }
  }

  void UpdateValueFromInteger()
  {
    uint128_t n = integer_;
    for (int i = 0; i < order_; i++)
    {
      value_[i] = n % base_[i];
      n = n / base_[i];
    }
  }

 public:
  CartesianCounterDynamic() = delete;

  CartesianCounterDynamic(unsigned order) :
      order_(order)
  {
    base_.resize(order_);
    value_.resize(order_);
  }

  CartesianCounterDynamic(std::vector<uint128_t> base) :
      CartesianCounterDynamic(base.size())
  {
    Init(base);
  }

  template<typename T>
  void Init(T base)
  {
    integer_ = 0;
    endint_ = 1;
    for (int i = 0; i < order_; i++)
    {
      base_[i] = base[i];
      endint_ *= checked_uint128_t(base_[i]);
      value_[i] = 0;
    }
  }

  bool Increment()
  {
    integer_++;
    return IncrementRecursive_(0);
  }

  std::vector<uint128_t> Read() const
  {
    return value_;
  }

  std::vector<uint128_t> Base() const
  {
    return base_;
  }

  uint128_t operator[] (int dim)
  {
    return value_[dim];
  }

  void Set(uint128_t n)
  {
    assert(order_ != 0);
    assert(checked_uint128_t(n) < endint_);
    integer_ = n;
    UpdateValueFromInteger();
  }

  void Set(int dim, uint128_t v)
  {
    assert(dim < order_);
    value_[dim] = v;
    UpdateIntegerFromValue();
    assert(integer_ < endint_);
  }

  void Set(std::vector<uint128_t> v)
  {
    order_ = v.size();
    value_ = v;
    UpdateIntegerFromValue();
    assert(integer_ < endint_);
  }

  uint128_t EndInteger() const
  {
    return endint_;
  }

  uint128_t Integer() const
  {
    return integer_;
  }
};

//------------------------------------
//             Factoradic
//------------------------------------

template <class T>
class Factoradic
{
 private:
  const static std::size_t MaxLength = 20;  // 21! > 2^64.
  std::uint64_t factorial_table_[MaxLength + 1];

 public:
  Factoradic()
  {
    factorial_table_[0] = 1;
    std::uint64_t fact = 1;
    for (std::uint64_t i = 1; i <= MaxLength; i++)
    {
      fact = fact * i;
      factorial_table_[i] = fact;
    }
  }

  std::uint64_t Factorial(std::uint64_t n)
  {
    assert(n <= MaxLength);
    return factorial_table_[n];
  }

  void Permute(T* buffer, std::size_t length, std::uint64_t index)
  {
    std::uint64_t scale = factorial_table_[length];
    assert(index < scale);

    for (std::size_t i = 0; i < length - 1; i++)
    {
      scale /= (std::uint64_t)(length - i);
      std::size_t d = index / scale;
      index %= scale;
      if (d > 0)
      {
        const T c = buffer[i + d];
        memmove(buffer + i + 1, buffer + i, d * sizeof(T));
        buffer[i] = c;
      }
    }
  }
};

//------------------------------------
//        PatternGenerator128
//------------------------------------

class PatternGenerator128
{
 protected:
  const std::uint64_t uint64_max_ = std::numeric_limits<std::uint64_t>::max();
  uint128_t bound_;

 public:
  PatternGenerator128(uint128_t bound);

  virtual uint128_t Next() = 0;
};

class SequenceGenerator128 final : public PatternGenerator128
{
 private:
  bool autoloop_;
  uint128_t cur_;

 public:
  SequenceGenerator128(uint128_t bound, bool autoloop = true);

  uint128_t Next();
};

class RandomGenerator128 final : public PatternGenerator128
{
 private:
  bool use_two_generators_;

  std::default_random_engine engine_;
  std::uniform_int_distribution<std::uint64_t> low_gen_;
  std::uniform_int_distribution<std::uint64_t> high_gen_;

 public:
  RandomGenerator128(uint128_t bound);

  uint128_t Next();
};

//------------------------------------
//           Miscellaneous
//------------------------------------

// Returns the smallest factor of an integer and the quotient after
// division with the smallest factor.
void SmallestFactor(uint64_t n, uint64_t& factor, uint64_t& residue);

// Helper function to get close-to-square layouts of arrays
// containing a given number of nodes.
void GetTiling(uint64_t num_elems, uint64_t& height, uint64_t& width);

double LinearInterpolate(double x,
                         double x0, double x1,
                         double q0, double q1);

double BilinearInterpolate(double x, double y,
                           double x0, double x1,
                           double y0, double y1,
                           double q00, double q01, double q10, double q11);

//---------------------------------------------
// STL Utility Functions: move to another file
//---------------------------------------------

template<typename K>
struct TaggedBound
{
  bool valid;
  K bound;
};

template<typename K, typename V>
std::tuple<TaggedBound<K>, TaggedBound<K>>
FindBounds(std::map<K, V> map, K key)
{
  TaggedBound<K> lower = { false, K() };
  TaggedBound<K> upper = { false, K() };

  if (!map.empty())
  {
    // Find consecutive entries in the map that bound the width parameter.
    typename std::map<K, V>::iterator it;
    for (it = map.begin(); it != map.end() && key > it->first; it++);

    if (it != map.end())
    {
      upper.valid = true;
      upper.bound = it->first;
    }

    if (it != map.begin())
    {
      it--;
      lower.valid = true;
      lower.bound = it->first;
    }
    else if (key == it->first)
    {
      lower.valid = true;
      lower.bound = it->first;
    }
  }

  return std::make_tuple(lower, upper);
}

ext: hpp

max_stars_repo_name: nelliewu-nv/timeloop

max_issues_repo_name: nelliewu-nv/timeloop

max_forks_repo_name: nelliewu-nv/timeloop


text:
#include "stun/stochastic_tunneling.h"
#include "stub/random_utils.h"
#include "stub/temperature.h"
#include "stub/utils.h"
#include "stun/schedule_params.h"
#include <boost/ut.hpp>
#include <trompeloeil.hpp>

using namespace boost::ut;

namespace {
using namespace angonoka::stun;

struct RandomUtilsMock final : RandomUtils {
    MAKE_MOCK0(uniform_01, float(), noexcept override);
    MAKE_MOCK1(
        uniform_int,
        int16(std::int16_t max),
        noexcept override);
};

struct MakespanMock final : Makespan {
    float operator()(Schedule schedule) noexcept override
    {
        return call(schedule);
    }
    MAKE_MOCK1(call, float(Schedule schedule), noexcept);
};

struct MutatorMock final : Mutator {
    void operator()(MutSchedule schedule) const noexcept override
    {
        return call(schedule);
    }
    MAKE_MOCK1(call, void(MutSchedule schedule), const noexcept);
};

struct TemperatureMock final : Temperature {
    operator float() noexcept override { return to_float(); }
    MAKE_MOCK0(to_float, float(), noexcept);
    MAKE_MOCK1(update, void(float stun), noexcept override);
    MAKE_MOCK0(average_stun, float(), const noexcept override);
};
} // namespace

suite stochastic_tunneling = [] {
    "StochasticTunneling type traits"_test = [] {
        using angonoka::stun::StochasticTunneling;
        expect(std::is_nothrow_destructible_v<StochasticTunneling>);
        expect(!std::is_default_constructible_v<StochasticTunneling>);
        expect(std::is_copy_constructible_v<StochasticTunneling>);
        expect(std::is_copy_assignable_v<StochasticTunneling>);
        expect(std::is_nothrow_move_constructible_v<
               StochasticTunneling>);
        expect(
            std::is_nothrow_move_assignable_v<StochasticTunneling>);
    };

    constexpr auto run_mock = [](auto test_fn) {
        using namespace angonoka::stun;
        using trompeloeil::_;

        RandomUtilsMock random_utils;
        MakespanMock makespan;
        TemperatureMock temperature;
        MutatorMock mutator;
        std::vector<ScheduleItem> schedule(3);

        trompeloeil::sequence seq;

        REQUIRE_CALL(makespan, call(schedule))
            .RETURN(1.F)
            .IN_SEQUENCE(seq);
        REQUIRE_CALL(mutator, call(_)).IN_SEQUENCE(seq);
        REQUIRE_CALL(makespan, call(_)).RETURN(1.F).IN_SEQUENCE(seq);
        REQUIRE_CALL(temperature, to_float())
            .RETURN(.5F)
            .IN_SEQUENCE(seq);
        REQUIRE_CALL(random_utils, uniform_01())
            .RETURN(.1F)
            .IN_SEQUENCE(seq);
        REQUIRE_CALL(temperature, update(_)).IN_SEQUENCE(seq);

        REQUIRE_CALL(mutator, call(_)).IN_SEQUENCE(seq);
        REQUIRE_CALL(makespan, call(_)).RETURN(.1F).IN_SEQUENCE(seq);

        test_fn(
            mutator,
            random_utils,
            makespan,
            temperature,
            schedule);
    };

    "stochastic tunneling"_test = [&] {
        using namespace angonoka::stun;
        "simple"_test = [&] {
            run_mock([](auto& mutator,
                        auto& random_utils,
                        auto& makespan,
                        auto& temperature,
                        auto& schedule) {
                StochasticTunneling stun{
                    {.mutator{&mutator},
                     .random{&random_utils},
                     .makespan{&makespan},
                     .temp{&temperature},
                     .gamma{.5F}},
                    schedule};
                for (int i{0}; i < 2; ++i) stun.update();

                expect(stun.normalized_makespan() == .1_d);
                expect(stun.schedule().size() == 3);
            });
        };

        "two phase construction"_test = [&] {
            run_mock([](auto& mutator,
                        auto& random_utils,
                        auto& makespan,
                        auto& temperature,
                        auto& schedule) {
                StochasticTunneling stun{
                    {.mutator{&mutator},
                     .random{&random_utils},
                     .makespan{&makespan},
                     .temp{&temperature},
                     .gamma{.5F}}};
                stun.reset(schedule);
                for (int i{0}; i < 2; ++i) stun.update();

                expect(stun.normalized_makespan() == .1_d);
                expect(stun.schedule().size() == 3);
            });
        };
    };

    "StochasticTunneling options"_test = [] {
        using namespace angonoka::stun;
        using trompeloeil::_;

        RandomUtilsMock random_utils;
        MakespanMock makespan;
        TemperatureMock temperature;
        MutatorMock mutator;
        std::vector<ScheduleItem> schedule{{0, 0}, {1, 1}, {2, 2}};

        ALLOW_CALL(makespan, call(_)).RETURN(1.F);

        StochasticTunneling::Options options{
            .mutator{&mutator},
            .random{&random_utils},
            .makespan{&makespan},
            .temp{&temperature},
            .gamma{.5F}};

        StochasticTunneling stun{options, schedule};

        expect(stun.options().makespan == &makespan);

        MakespanMock makespan2;

        options.makespan = &makespan2;
        stun.options(options);

        expect(stun.options().makespan == &makespan2);
    };

    "StochasticTunneling special member functions"_test = [] {
        using namespace angonoka::stun;
        using trompeloeil::_;

        RandomUtilsMock random_utils;
        MakespanMock makespan;
        TemperatureMock temperature;
        MutatorMock mutator;
        std::vector<ScheduleItem> schedule{{0, 0}, {1, 1}, {2, 2}};
        std::vector<ScheduleItem> schedule2{{3, 3}, {4, 4}, {5, 5}};

        ALLOW_CALL(makespan, call(_)).RETURN(1.F);

        StochasticTunneling::Options options{
            .mutator{&mutator},
            .random{&random_utils},
            .makespan{&makespan},
            .temp{&temperature},
            .gamma{.5F}};

        "copy assignment"_test = [&] {
            StochasticTunneling stun{options, schedule};
            StochasticTunneling stun2{options, schedule2};
            stun = stun2;

            expect(stun.schedule()[0].agent_id == 3);
        };

        "move assignment"_test = [&] {
            StochasticTunneling stun{options, schedule};
            StochasticTunneling stun2{options, schedule2};
            stun = std::move(stun2);

            expect(stun.schedule()[0].agent_id == 3);
        };

        "copy ctor"_test = [&] {
            StochasticTunneling stun{options, schedule};
            StochasticTunneling stun2{stun};

            expect(stun2.schedule()[1].agent_id == 1);
        };

        "move ctor"_test = [&] {
            StochasticTunneling stun{options, schedule};
            StochasticTunneling stun2{std::move(stun)};

            expect(stun2.schedule()[1].agent_id == 1);
        };

        "self copy"_test = [&] {
            StochasticTunneling stun{options, schedule};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-assign-overloaded"
            stun = stun;
#pragma clang diagnostic pop
            expect(stun.schedule()[1].agent_id == 1);
        };

        "self move"_test = [&] {
            StochasticTunneling stun{options, schedule};
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wself-move"
            stun = std::move(stun);
#pragma clang diagnostic pop
            expect(stun.schedule()[1].agent_id == 1);
        };
    };
};

ext: cpp

max_stars_repo_name: coffee-lord/angonoka

max_issues_repo_name: coffee-lord/angonoka

max_forks_repo_name: coffee-lord/angonoka


text:
//
// cookie.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2013 Jack (jack dot wgm at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// path LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef AVHTTP_COOKIE_HPP
#define AVHTTP_COOKIE_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <stdlib.h>     // for atol.
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/algorithm/cxx11/copy_if.hpp>
#include <boost/date_time.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>

#include "avhttp/detail/escape_string.hpp"
#include "avhttp/detail/parsers.hpp"
#include "avhttp/file.hpp"

namespace avhttp {

class cookies;
inline cookies operator+(const cookies& lhs, const cookies& rhs);

// 用于管理cookie的实现.
// 请求前设置cookie, 示例如下:.
// @begin example
//  http_stream h(io);
//  ...
// 	cookies cookie;
// 	cookie("cookie_name1", "hohoo");
// 	cookie("cookie_name1", "hahaha");
//  设置到http_stream.
// 	h.http_cookies(cookie);
// @end example
// 需要访问http服务器返回的cookie, 示例如下:
// @begin example
//  http_stream h(io);
//  ...
//  cookies cookie = h.http_cookies();
//  cookies::iterator i = cookie.begin();
//  for (; i != cookie.end(); i++)
//  {
//    std::cout <<　i->name << ":" << i->value << std::endl;
//  }
// @end example
class cookies
{
public:
	// cookie结构定义.
	typedef struct cookie_t
	{
		cookie_t()
			: httponly(false)
			, secure(false)
		{}

		// name和value, name必须不为空串.
		std::string name;
		std::string value;

		// 如果为空串, 即匹配任何域名.
		std::string domain;

		// 如果为空串, 即匹配任何路径.
		std::string path;

		// 如果为无效时间, 表示为不过期.
		boost::posix_time::ptime expires;

		// httponly在这里没有意义, secure只有为https时, 才带上此cookie.
		bool httponly;
		bool secure;

		// 用于 std::sort 算法的比较函数对象.
		// 基于 过期时间进行排序.
		template<typename Compare>
		struct compare_by_expires_t
			: std::binary_function<cookie_t, cookie_t, bool>
		{
			compare_by_expires_t(const Compare& comp)
			  : m_comp(comp)
			{
			}

			bool operator()(const cookie_t& lhs, const cookie_t& rhs)
			{
				return m_comp(lhs.expires, rhs.expires);
			}

        private:
			Compare m_comp;
		};

		template<typename Compare>
		static compare_by_expires_t<Compare>
		compare_by_expires(const Compare & comp)
		{
			return compare_by_expires_t<Compare>(comp);
		}

	} http_cookie;

public:

	/// Constructor.
	explicit cookies()
	{}

	/// Destructor.
	~cookies()
	{}

	typedef std::vector<http_cookie>::iterator iterator;
	typedef std::vector<http_cookie>::const_iterator const_iterator;
	typedef std::vector<http_cookie>::reference reference;
	typedef std::vector<http_cookie>::const_reference const_reference;
	typedef std::vector<http_cookie>::value_type value_type;

	iterator begin() { return m_cookies.begin(); }
	iterator end() { return m_cookies.end(); }

	const_iterator begin() const { return m_cookies.begin(); }
	const_iterator end() const { return m_cookies.end(); }

	void push_back(const value_type& val) { m_cookies.push_back(val); }

	// 保存cookies到指定的文件, 以Netscape HTTP Cookie File格式保存, 兼容curl.
	// @param filename指定保存的文件名.
	// @param default_domain默认的domain, 如果http服务器没有返回domain, 保存时
	//   将以default_domain作为domain来处理, default_domain一般可以指定为所访问
	//   的http服务器domain.
	// 备注: 失败将抛出一个boost::system::system_error异常.
	void save_to_file(const std::string& filename, const std::string& default_domain = "") const
	{
		std::fstream f;
		f.open(filename.c_str(), std::ios::out);
		if (!f.is_open())
		{
			f.open(filename.c_str(), std::ios::out|std::ios::trunc);
			if (!f.is_open())
			{
				boost::system::error_code ec =
					make_error_code(boost::system::errc::no_such_file_or_directory);
				boost::throw_exception(boost::system::system_error(ec));
			}
		}

		// 写入memo信息.
		if (fs::file_size(filename) == 0)
		{
			std::string memo =
				"# Netscape HTTP Cookie File\n"
				"# http://curl.haxx.se/docs/http-cookies.html\n"
				"# This file was generated by libcurl! Edit at your own risk.\n\n";
			f.write(memo.c_str(), memo.size());
		}

		std::vector<http_cookie>::const_iterator i = m_cookies.begin();
		for (; i != m_cookies.end(); i++)
		{
			const http_cookie& cookie = *i;
			std::string tmp;

			// domain.
			if (cookie.domain.empty())
			{
				tmp = default_domain;
			}
			else
			{
				tmp = cookie.domain;
			}
			f.write(tmp.c_str(), tmp.size());
			f.write("\t", 1);

			// flag.
			cookie.domain.empty() ? tmp = "FALSE" : tmp = "TRUE";
			f.write(tmp.c_str(), tmp.size());
			f.write("\t", 1);

			// path.
			f.write(cookie.path.c_str(), cookie.path.size());
			f.write("\t", 1);

			// secure.
			cookie.secure ? tmp = "TRUE" : tmp = "FALSE";
			f.write(tmp.c_str(), tmp.size());
			f.write("\t", 1);

			// expires.
			time_t t = 0;
			if (cookie.expires != boost::posix_time::not_a_date_time)
			{
				t = detail::ptime_to_time_t(cookie.expires);
			}
			std::ostringstream oss;
			oss.imbue(std::locale("C"));
			oss << t;
			tmp = oss.str();
			f.write(tmp.c_str(), tmp.size());
			f.write("\t", 1);

			// name.
			f.write(cookie.name.c_str(), cookie.name.size());
			f.write("\t", 1);

			// value.
			f.write(cookie.value.c_str(), cookie.value.size());
			f.write("\t\n", 1);
		}
	}

	// 从文件加载cookie.
	// @param filename指定的文件名, 该文件必须是Netscape HTTP Cookie File格式保存.
	// 备注: 失败将抛出一个boost::system::system_error异常.
	void load_from_file(const std::string& filename)
	{
		std::fstream f;
		f.open(filename.c_str(), std::ios::in|std::ios::out);
		if (!f.is_open())
		{
			boost::system::error_code ec =
				make_error_code(boost::system::errc::no_such_file_or_directory);
			boost::throw_exception(boost::system::system_error(ec));
		}

		std::string line;
		while (!f.eof())
		{
			std::getline(f, line);
			// 过滤掉空行和注释行.
			boost::trim(line);
			if (line.empty() || line.at(0) == '#')
			{
				continue;
			}

			// 开始解析.
			std::vector<std::string> split_vec;
			boost::split(split_vec, line, boost::is_any_of("\t"), boost::token_compress_on);
			time_t time;
			time = atol(split_vec[4].c_str());
			http_cookie cookie;
			cookie.domain = split_vec[0];
			cookie.path = split_vec[2];
			cookie.secure = split_vec[3] == "TRUE" ? true : false;
			cookie.expires = boost::posix_time::from_time_t(time);
			std::string s = boost::posix_time::to_simple_string(cookie.expires);
			cookie.name = split_vec[5];
			cookie.value = split_vec[6];

			// 更新或插入cookie.
			m_cookies.push_back(cookie);
		}
	}

	// 更新一个cookie.
	// @name 指定cookie的名称.
	// @value cookie的值.
	cookies& operator()(const std::string& name, const std::string& value)
	{
		http_cookie tmp;
		tmp.name = name;
		tmp.value = value;
		m_cookies.push_back(tmp);
		return *this;
	}

	// 更新一个cookie.
	// @cookie 指定cookie
	cookies& operator()(const http_cookie & cookie)
	{
		m_cookies.push_back(cookie);
		return *this;
	}

	// 更新cookie, 接受一个http服务器返回的Set-Cookie格式字符串的cookie.
	cookies& operator()(const std::string& str)
	{
		std::vector<http_cookie> cookie;
		if (parse_cookie_string(str, cookie))
		{
			for (std::vector<http_cookie>::iterator i = cookie.begin();
				i != cookie.end(); i++)
			{
				m_cookies.push_back(*i);
			}
		}

		return *this;
	}

	// 获取HTTP请求头需要的 cookie 行
	// @https 是否为 https 连接.
	// @domain 指定的domain, 如果为空串, 则默认添加所有domain的cookie.
	// @path 指定的path, 如果为空串, 则添加所有path的cookie.
	// 返回http 请求header中可用的cookie格式字符串.
	std::string get_cookie_line(bool https = false,
		std::string domain = "", std::string path = "") const
	{
		std::string cookie;
		if (m_cookies.size() != 0)
		{
			cookies tmp;

			// 通过+运算自动去掉重复的cookie项.
			tmp = tmp + *this;

			// 构造字符串.
			cookies::const_iterator i = tmp.begin();
			for (; i != tmp.end(); i++)
			{
				// 判断是否为空.
				if (i->value.empty())
					continue;
				// 判断secure.
				if (i->secure && !https)
					continue;
				// 路径非空, 判断路径是否匹配.
				boost::trim(path);
				if (!path.empty())
				{
					std::string cookie_path = i->path;
					boost::trim(cookie_path);
					boost::filesystem::path p1(path);
					boost::filesystem::path p2(cookie_path);
					if (p1 != p2)
						continue;
				}
				// domain非空, 判断domain是否匹配.
				boost::trim(domain);
				if (!domain.empty())
				{
					std::string cookie_domain = i->domain;
					boost::trim(cookie_domain);
					if (!cookie_domain.empty())
					{
						// 第一个字符为'.', 表示匹配所有以cookie_domain结尾的domain.
						if (cookie_domain.at(0) == '.')
						{
							// 去掉'.'.
							boost::trim_left_if(cookie_domain, boost::is_any_of("."));
							// 然后再判断是否是domain的结 尾, 如果是
							// 则表示ok, 否则匹配不通过.
							if (!boost::iends_with(domain, cookie_domain))
							{
								continue;
							}
						}
						else if (cookie_domain != domain) // 必须全部匹配.
						{
							continue;
						}
					}
				}
				// 判断是否过期, 小于当前时间表示过期, 不添加到cookie.
				if ( !i->expires.is_not_a_date_time()
					&& i->expires < boost::posix_time::second_clock::local_time())
				{
					continue;
				}

				if (!cookie.empty())
				{
					cookie += "; ";
				}

				cookie += (i->name + "=" + i->value);
			}
		}
		return cookie;
	}

	// 获取指定的 cookie
	std::string operator[](const std::string& key) const
	{
		const_iterator i = m_cookies.begin();

		for (; i != m_cookies.end(); ++i)
		{
			if (i->name == key && !i->value.empty())
				return i->value;
		}

		return "";
	}

	// 查找基于 名字.
	iterator find(const std::string& key)
	{
		iterator i = m_cookies.begin();

		for (; i != m_cookies.end(); ++i)
		{
			if (i->name == key)
				return i;
		}

		return end();
	}

	// 查找基于 名字.
	const_iterator find(const std::string& key) const
	{
		const_iterator i = m_cookies.begin();

		for (; i != m_cookies.end(); ++i)
		{
			if (i->name == key)
				return i;
		}

		return end();
	}

	// 查找基于 域/路径/名字.
	iterator find(const http_cookie& key)
	{
		iterator i = m_cookies.begin();

		for (; i != m_cookies.end(); ++i)
		{
			if (i->name == key.name && i->domain == key.domain && i->path == key.path)
				return i;
		}

		return end();
	}

	// 查找基于 域/路径/名字.
	const_iterator find(const http_cookie& key) const
	{
		const_iterator i = m_cookies.begin();

		for (; i != m_cookies.end(); ++i)
		{
			if (i->name == key.name && i->domain == key.domain && i->path == key.path)
				return i;
		}

		return end();
	}

private:
	struct http_cookie_is_same_name
	{
		http_cookie_is_same_name(const std::string & name)
		  : m_name(name)
		{}

		bool operator()( const http_cookie & cookie)
		{
			return cookie.name == m_name ;
		}

		std::string m_name;
	};

public:
	// 删除指定名称的cookie.
	void remove_cookie(const std::string& name)
	{
		std::remove_if(m_cookies.begin(), m_cookies.end(),
			http_cookie_is_same_name(name) );
	}

	// 清除所有cookie.
	void clear()
	{
		m_cookies.clear();
	}

	// 返回cookie数.
	int size() const
	{
		return m_cookies.size();
	}

	// 保留n个cookie空间.
	void reserve(std::size_t n)
	{
		m_cookies.reserve(n);
	}

	// 设置默认domain.
	void default_domain(const std::string& domain)
	{
		m_default_domain = domain;
	}

	// 返回当前默认domain.
	std::string default_domain() const
	{
		return m_default_domain;
	}

private:

	// 解析cookie字符.
	// 示例字符串:
	// gsid=none; expires=Sun, 22-Sep-2013 14:27:43 GMT; path=/; domain=.fidelity.cn; httponly
	// gsid=none; gsid2=none; expires=Sun, 22-Sep-2013 14:27:43 GMT; path=/; domain=.fidelity.cn
	inline bool parse_cookie_string(const std::string& str, std::vector<http_cookie>& cookie)
	{
		// 解析状态.
		enum
		{
			cookie_name_start,
			cookie_name,
			cookie_value_start,
			cookie_value,
			cookie_bad
		} state = cookie_name_start;

		std::string::const_iterator iter = str.begin();
		std::string name;
		std::string value;
		std::map<std::string, std::string> tmp;
		http_cookie cookie_tmp;

		// 开始解析http-cookie字符串.
		while (iter != str.end() && state != cookie_bad)
		{
			const char c = *iter++;
			switch (state)
			{
			case cookie_name_start:
				if (c == ' ')
					continue;
				if (detail::is_char(c))
				{
					name.push_back(c);
					state = cookie_name;
				}
				else
					state = cookie_bad;
				break;
			case cookie_name:
				if (c == ';')
				{
					state = cookie_name_start;
					if (boost::to_lower_copy(name) == "secure")
						cookie_tmp.secure = true;
					else if (boost::to_lower_copy(name) == "httponly")
						cookie_tmp.httponly = true;
					else
						state = cookie_bad;
					name = "";
				}
				else if (c == '=')
				{
					value = "";
					state = cookie_value_start;
				}
				else if (detail::is_tspecial(c) || c == ':')
				{
					name = "";
					state = cookie_name_start;
				}
				else if (detail::is_char(c) || c == '_')
					name.push_back(c);
				break;
			case cookie_value_start:
				if (c == ';')
				{
					tmp[name] = value; // 添加或更新.
					name = "";
					value = "";
					state = cookie_name_start;
					continue;
				}

				if (c == '\"' || c == '\'')
					continue;

				if (detail::is_char(c))
				{
					value.push_back(c);
					state = cookie_value;
				}
				else
					state = cookie_bad;
				break;
			case cookie_value:
				if (c == ';' || c == '\"' || c == '\'')
				{
					tmp[name] = value;	// 添加或更新.
					name = "";
					value = "";
					state = cookie_name_start;
				}
				else if (detail::is_char(c))
					value.push_back(c);
				else
					state = cookie_bad;
				break;
			case cookie_bad:
				break;
			}
		}
		if (state == cookie_name && !name.empty())
		{
			if (boost::to_lower_copy(name) == "secure")
				cookie_tmp.secure = true;
			else if (boost::to_lower_copy(name) == "httponly")
				cookie_tmp.httponly = true;
		}
		else if (state == cookie_value && !value.empty())
		{
			tmp[name] = value;	// 添加或更新.
		}
		else if (state == cookie_bad)
		{
			return false;
		}

		for (std::map<std::string, std::string>::iterator i = tmp.begin();
			i != tmp.end(); )
		{
			if (boost::to_lower_copy(i->first) == "expires")
			{
				if (!detail::parse_http_date(i->second, cookie_tmp.expires))
					BOOST_ASSERT(0);	// for debug.
				tmp.erase(i++);
			}
			else if (boost::to_lower_copy(i->first) == "domain")
			{
				cookie_tmp.domain = i->second;
				if (i->second.empty() && !m_default_domain.empty())
				{
					cookie_tmp.domain = m_default_domain;
				}
				tmp.erase(i++);
			}
			else if (boost::to_lower_copy(i->first) == "path")
			{
				cookie_tmp.path = i->second;
				tmp.erase(i++);
			}
			else
			{
				i++;
			}
		}

		// 添加到容器返回.
		for (std::map<std::string, std::string>::iterator i = tmp.begin();
			i != tmp.end(); i++)
		{
			cookie_tmp.name = i->first;
			cookie_tmp.value = i->second;
			cookie.push_back(cookie_tmp);
		}

		return true;
	}

private:
	// 保存所有cookie.
	std::vector<http_cookie> m_cookies;

	// 设置默认域.
	std::string m_default_domain;
};

namespace detail {

inline bool cookie_megerable(const cookies::http_cookie& element, const cookies& container)
{
	// 查看是否 element 符合拷贝进 container 的资格.
	// 第一，他应该不是空的.
	cookies::const_iterator it = container.find(element.name);

	// 首先，它不存在, 那就直接更新.
	if (container.find(element) == container.end())
	{
		return true;
	}

	// 既然存在了，那就得比较比较.

	// 要拷贝进去的自己都是空的，有什么资格要拷贝进去!
	if (element.value.empty())
		return false;

	// 不过如果原来的是空的，那就可以拷贝进去.
	if (it->value.empty())
		return true;

	// 要是原来的时间要比你新，那还是不能拷贝.
	if (element.expires <= it->expires)
		return false;

	// 好了，基本上不能拷贝的都判定好了，接下来就是能拷贝的了.
	return true;
}

} // namespace detail

// 将两个 cookies 容器合并.
inline cookies operator+(const cookies& lhs, const cookies& rhs)
{
	cookies tmp, ret;

	// 首先一股脑的拷贝进去.
	std::copy(lhs.begin(), lhs.end(), std::back_inserter(tmp));
	std::copy(rhs.begin(), rhs.end(), std::back_inserter(tmp));

	// 排序！ 我是多么希望能使用 c++11 的 lambda 表达式来简化这里的代码!
	std::sort(tmp.begin(), tmp.end(),
		cookies::http_cookie::compare_by_expires(std::greater<boost::posix_time::ptime>()));

	// std::copy_if 的 boost 版本，能在 c++98 下用了，good
	boost::algorithm::copy_if(tmp.begin(), tmp.end(), std::back_inserter(ret),
		boost::bind(detail::cookie_megerable, _1, boost::ref(ret)));
	// 返回完成结果.
	return ret;
}

} // namespace avhttp

#endif // AVHTTP_COOKIE_HPP


text:
/// \file endpoint.hpp
/// \brief Defines endpoint conversion functions.
#ifndef DRIVER_TCPIP___ENDPOINT_H
#define DRIVER_TCPIP___ENDPOINT_H

#include <driver_tcpip_msgs/endpoint.h>

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp>

namespace driver_tcpip {
namespace endpoint {

// TCP
/// \brief Converts a ROS endpoint to an ASIO TCP endpoint.
/// \param endpoint_ros The ROS endpoint to convert.
/// \returns The converted ASIO TCP endpoint.
boost::asio::ip::tcp::endpoint to_asio_tcp(const driver_tcpip_msgs::endpoint& endpoint_ros);
/// \brief Converts an ASIO TCP endpoint to a ROS endpoint.
/// \param endpoint_asio The ASIO TCP endpoint to convert.
/// \returns The converted ROS endpoint.
driver_tcpip_msgs::endpoint to_ros(const boost::asio::ip::tcp::endpoint& endpoint_asio);

// UDP
/// \brief Converts a ROS endpoint to an ASIO UDP endpoint.
/// \param endpoint_ros The ROS endpoint to convert.
/// \returns The converted ASIO UDP endpoint.
boost::asio::ip::udp::endpoint to_asio_udp(const driver_tcpip_msgs::endpoint& endpoint_ros);
/// \brief Converts an ASIO UDP endpoint to a ROS endpoint.
/// \param endpoint_asio The ASIO UDP endpoint to convert.
/// \returns The converted ROS endpoint.
driver_tcpip_msgs::endpoint to_ros(const boost::asio::ip::udp::endpoint& endpoint_asio);

}}

#endif


text:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2014-2016 The FFF Core developers
// Original code was distributed under the MIT software license.
// Copyright (c) 2014-2019 Coin Sciences Ltd
// FFF_Core code distributed under the GPLv3 license, see COPYING file.

#include "structs/base58.h"
#include "version/clientversion.h"
#include "core/init.h"
#include "core/main.h"
#include "net/net.h"
#include "net/netbase.h"
#include "rpc/rpcserver.h"
#include "utils/timedata.h"
#include "utils/util.h"
#ifdef ENABLE_WALLET
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
#include "community/community.h"

#include <stdint.h>

/* MCHN START */
#include "FFF_Core/FFF_Core.h"
#include "wallet/wallettxs.h"
std::string BurnAddress(const std::vector<unsigned char>& vchVersion);
std::string SetBannedTxs(std::string txlist);
std::string SetLockedBlock(std::string hash);
int mc_StoreSetRuntimeParam(std::string param_name);
double mc_GetChainRewards(int chain_height,int64_t *raw_value);

/* MCHN END */

#include <boost/assign/list_of.hpp>
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"

using namespace boost;
using namespace boost::assign;
using namespace json_spirit;
using namespace std;

bool CFFFAddressFromTxEntity(CFFFAddress &address,mc_TxEntity *lpEntity);
Object AddressEntry(CFFFAddress& address,uint32_t verbose);
int paramtoint(Value param,bool check_for_min,int min_value,string error_message);

/**
 * @note Do not add or change anything in the information returned by this
 * method. `getinfo` exists for backwards-compatibility only. It combines
 * information from wildly different sources in the program, which is a mess,
 * and is thus planned to be deprecated eventually.
 *
 * Based on the source of the information, new information should be added to:
 * - `getblockchaininfo`,
 * - `getnetworkinfo` or
 * - `getwalletinfo`
 *
 * Or alternatively, create a specific query method for the information.
 **/
Value getinfo(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error("Help message not found\n");

    proxyType proxy;
    GetProxy(NET_IPV4, proxy);

    Object obj;
/* MCHN START */
//    obj.push_back(Pair("version", CLIENT_VERSION));
//    obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));

    obj.push_back(Pair("version", mc_BuildDescription(mc_gState->GetNumericVersion())));
    obj.push_back(Pair("nodeversion", mc_gState->GetNumericVersion()));
    obj.push_back(Pair("edition", pEF->ENT_Edition()));
    obj.push_back(Pair("protocolversion", mc_gState->m_NetworkParams->ProtocolVersion()));
    obj.push_back(Pair("chainname", string(mc_gState->m_NetworkParams->Name())));
    obj.push_back(Pair("description", string((char*)mc_gState->m_NetworkParams->GetParam("chaindescription",NULL))));
    obj.push_back(Pair("protocol", string((char*)mc_gState->m_NetworkParams->GetParam("chainprotocol",NULL))));
    obj.push_back(Pair("port", GetListenPort()));
    obj.push_back(Pair("setupblocks", mc_gState->m_NetworkParams->GetInt64Param("setupfirstblocks")));

    obj.push_back(Pair("nodeaddress", FFF_CoreServerAddress(true) + strprintf(":%d",GetListenPort())));

    obj.push_back(Pair("burnaddress", BurnAddress(Params().Base58Prefix(CChainParams::PUBKEY_ADDRESS))));
    obj.push_back(Pair("incomingpaused", (mc_gState->m_NodePausedState & MC_NPS_INCOMING) ? true : false));
    obj.push_back(Pair("miningpaused", (mc_gState->m_NodePausedState & MC_NPS_MINING) ? true : false));
    obj.push_back(Pair("offchainpaused", (mc_gState->m_NodePausedState & MC_NPS_OFFCHAIN) ? true : false));

/* MCHN END */
#ifdef ENABLE_WALLET
    if (pwalletMain) {
        obj.push_back(Pair("walletversion", pwalletMain->GetVersion()));
        obj.push_back(Pair("balance",       ValueFromAmount(pwalletMain->GetBalance())));
        obj.push_back(Pair("walletdbversion", mc_gState->GetWalletDBVersion()));
    }
#endif
/* MCHN START */
    obj.push_back(Pair("reindex",       fReindex));
/* MCHN END */
    obj.push_back(Pair("blocks",        (int)chainActive.Height()));

    double chain_balance=0.;
    int64_t total_value=0;
    chain_balance=mc_GetChainRewards((int)chainActive.Height(),&total_value);
    obj.push_back(Pair("chainrewards",        chain_balance));

    mc_EntityDetails entitylist_entity;
    int32_t entity_count;
    if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_ASSET))
    {
        mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        obj.push_back(Pair("assets",        (int)entity_count));
    }
    if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_STREAM))
    {
        mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        obj.push_back(Pair("streams",       (int)entity_count));
    }

    if(mc_gState->m_WalletMode & MC_WMD_EXPLORER)
    {
        mc_TxEntity entity;

        entity.Zero();
        entity.m_EntityType=MC_TET_EXP_TX_PUBLISHER;
        entity.m_EntityType |= MC_TET_CHAINPOS;
        entity_count=pwalletTxsMain->GetListSize(&entity,NULL);

        obj.push_back(Pair("addresses",       (int)entity_count));

        entity.Zero();
        entity.m_EntityType=MC_TET_EXP_TX;
        entity.m_EntityType |= MC_TET_CHAINPOS;
        entity_count=pwalletTxsMain->GetListSize(&entity,NULL);

        obj.push_back(Pair("transactions",       (int)entity_count));

        {
            LOCK(cs_vNodes);
            obj.push_back(Pair("peers",       (int)vNodes.size()));
        }
    }

    obj.push_back(Pair("timeoffset",    GetTimeOffset()));
    obj.push_back(Pair("connections",   (int)vNodes.size()));
    obj.push_back(Pair("proxy",         (proxy.IsValid() ? proxy.ToStringIPPort() : string())));
    obj.push_back(Pair("difficulty",    (double)GetDifficulty()));
    obj.push_back(Pair("testnet",       Params().TestnetToBeDeprecatedFieldRPC()));
#ifdef ENABLE_WALLET
    if (pwalletMain) {
        obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime()));
        obj.push_back(Pair("keypoolsize",   (int)pwalletMain->GetKeyPoolSize()));
    }
    if (pwalletMain && pwalletMain->IsCrypted())
        obj.push_back(Pair("unlocked_until", nWalletUnlockTime));
    obj.push_back(Pair("paytxfee",      ValueFromAmount(payTxFee.GetFeePerK())));
#endif

/* MCHN START */
    ::minRelayTxFee = CFeeRate(MIN_RELAY_TX_FEE);
/* MCHN END */

    obj.push_back(Pair("relayfee",      ValueFromAmount(::minRelayTxFee.GetFeePerK())));
    obj.push_back(Pair("errors",        GetWarnings("statusbar")));
    return obj;
}

Value getchaintotals(const json_spirit::Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error("Help message not found\n");

    Object obj;
    mc_TxEntityStat entStat;
    int32_t entity_count;

    int rpc_slot=GetRPCSlot();

    pwalletTxsMain->WRPReadLock();

    obj.push_back(Pair("blocks",       (int)chainActive.Height()));

    double chain_balance=0.;
    int64_t total_value=0;
    chain_balance=mc_GetChainRewards((int)chainActive.Height(),&total_value);
    obj.push_back(Pair("rewards",        chain_balance));

    if(mc_gState->m_WalletMode & MC_WMD_EXPLORER)
    {
        mc_TxEntity entity;

        entity.Zero();
        entity.m_EntityType=MC_TET_EXP_TX_PUBLISHER;
        entity.m_EntityType |= MC_TET_CHAINPOS;
        entity_count=pwalletTxsMain->WRPGetListSize(&entity,NULL);

        obj.push_back(Pair("addresses",       (int)entity_count));

        entity.Zero();
        entity.m_EntityType=MC_TET_EXP_TX;
        entity.m_EntityType |= MC_TET_CHAINPOS;
        entity_count=pwalletTxsMain->WRPGetListSize(&entity,NULL);

        obj.push_back(Pair("transactions",       (int)entity_count));
    }
    else
    {
        obj.push_back(Pair("addresses",       Value::null));
        obj.push_back(Pair("transactions",       Value::null));
    }

    entStat.Zero();
    entStat.m_Entity.m_EntityType=MC_TET_ENTITY_KEY | MC_TET_CHAINPOS;

    if(!pwalletTxsMain->WRPFindEntity(&entStat))
    {
        pwalletTxsMain->WRPReadUnLock();

        mc_EntityDetails entitylist_entity;
        LOCK(cs_main);
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_ASSET))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("assets",        (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_STREAM))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("streams",       (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_FILTER))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("filters",       (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_VARIABLE))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("variables",       (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_LIBRARY))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("libraries",       (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_UPGRADE))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("upgrades",       (int)entity_count));
        entity_count=0;
        if(mc_gState->m_Assets->FindEntityList(&entitylist_entity,MC_ENT_TYPE_LICENSE_TOKEN))
        {
            mc_gState->m_Assets->GetTotalQuantity(&entitylist_entity,&entity_count);
        }
        obj.push_back(Pair("licenses",       (int)entity_count));
    }
    else
    {
        mc_TxEntity entity;

        uint32_t entity_key;

        entity.Zero();
        entity.m_EntityType=entStat.m_Entity.m_EntityType | MC_TET_SUBKEY;

        entity_key=MC_ENT_TYPE_ASSET;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("assets",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_STREAM;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("streams",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_FILTER;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("filters",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_VARIABLE;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("variables",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_LIBRARY;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("libraries",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_UPGRADE;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("upgrades",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        entity_key=MC_ENT_TYPE_LICENSE_TOKEN;
        memcpy(entity.m_EntityID,&entity_key,sizeof(uint32_t));
        obj.push_back(Pair("licenses",(int)pwalletTxsMain->WRPGetListSize(&entity,entStat.m_Generation,NULL)));

        pwalletTxsMain->WRPReadUnLock();
    }

    return obj;
}

Value getinitstatus(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error("Help message not found\n");

    Object obj;

    obj.push_back(Pair("version", mc_BuildDescription(mc_gState->GetNumericVersion())));
    obj.push_back(Pair("nodeversion", mc_gState->GetNumericVersion()));

    LOCK(cs_NodeStatus);

    if(pNodeStatus)
    {
        obj.push_back(Pair("initialized", false));
        obj.push_back(Pair("connecttime", (int64_t)(mc_TimeNowAsUInt()-pNodeStatus->tStartConnectTime)));
        obj.push_back(Pair("connectaddress", pNodeStatus->sSeedIP));
        obj.push_back(Pair("connectport", pNodeStatus->nSeedPort));
        obj.push_back(Pair("handshakelocal", pNodeStatus->sAddress));
        obj.push_back(Pair("lasterror", pNodeStatus->sLastError));
    }
    else
    {
        obj.push_back(Pair("initialized", (mc_gState->m_NetworkParams->m_Status == MC_PRM_STATUS_VALID) ));
    }

    return obj;

}

Value gethealthcheck(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 0)
        throw runtime_error("Help message not found\n");

    pEF->ENT_RPCVerifyEdition("gethealthcheck API");

    return pEF->HCH_RPCHealthCheck(params);
}

#ifdef ENABLE_WALLET
class DescribeAddressVisitor : public boost::static_visitor<Object>
{
private:
    isminetype mine;

public:
    DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}

    Object operator()(const CNoDestination &dest) const { return Object(); }

    Object operator()(const CKeyID &keyID) const {
        Object obj;
        CPubKey vchPubKey;
        obj.push_back(Pair("isscript", false));
        if (mine == ISMINE_SPENDABLE) {
            pwalletMain->GetPubKey(keyID, vchPubKey);
            obj.push_back(Pair("pubkey", HexStr(vchPubKey)));
            obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
        }
        return obj;
    }

    Object operator()(const CScriptID &scriptID) const {
        Object obj;
        obj.push_back(Pair("isscript", true));
        if (mine != ISMINE_NO) {
            CScript subscript;
            pwalletMain->GetCScript(scriptID, subscript);
            std::vector<CTxDestination> addresses;
            txnouttype whichType;
            int nRequired;
            ExtractDestinations(subscript, whichType, addresses, nRequired);
            obj.push_back(Pair("script", GetTxnOutputType(whichType)));
            obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
            Array a;
            BOOST_FOREACH(const CTxDestination& addr, addresses)
                a.push_back(CFFFAddress(addr).ToString());
            obj.push_back(Pair("addresses", a));
            if (whichType == TX_MULTISIG)
                obj.push_back(Pair("sigsrequired", nRequired));
        }
        return obj;
    }
};
#endif

/* MCHN START */

string getparamstring(string param)
{
    string str;
    str="";
    if(mapMultiArgs.count(param))
    {
        for(int i=0;i<(int)mapMultiArgs[param].size();i++)
        {
            if(str.size())
            {
                str += ",";
            }
            str += mapMultiArgs[param][i];
        }
    }
    return str;
}

Value getruntimeparams(const json_spirit::Array& params, bool fHelp)
{
    if (fHelp || params.size() > 1)
        throw runtime_error("Help message not found\n");

    Object obj;
/*
    obj.push_back(Pair("daemon",GetBoolArg("-daemon",false)));
    obj.push_back(Pair("datadir",mc_gState->m_Params->DataDir(0,0)));
    obj.push_back(Pair("debug",getparamstring("-debug")));
 */
    obj.push_back(Pair("port",GetListenPort()));
    obj.push_back(Pair("reindex",GetBoolArg("-reindex",false)));
    obj.push_back(Pair("rescan",GetBoolArg("-rescan",false)));
/*
    obj.push_back(Pair("rpcallowip",getparamstring("-rpcallowip")));
    obj.push_back(Pair("rpcport",GetArg("-rpcport", BaseParams().RPCPort())));
 */
    obj.push_back(Pair("txindex",GetBoolArg("-txindex",true)));
    obj.push_back(Pair("autocombineminconf",GetArg("-autocombineminconf", 1)));
    obj.push_back(Pair("autocombinemininputs",GetArg("-autocombinemininputs", 50)));
    obj.push_back(Pair("autocombinemaxinputs",GetArg("-autocombinemaxinputs", 100)));
    obj.push_back(Pair("autocombinedelay",GetArg("-autocombinedelay", 1)));
    obj.push_back(Pair("autocombinesuspend",GetArg("-autocombinesuspend", 15)));
    obj.push_back(Pair("autosubscribe",GetArg("-autosubscribe","")));
    CKeyID keyID;
    CPubKey pkey;
    if(!pwalletMain->GetKeyFromAddressBook(pkey,MC_PTP_CONNECT))
    {
        LogPrintf("mchn: Cannot find address having connect permission, trying default key\n");
        pkey=pwalletMain->vchDefaultKey;
    }
    keyID=pkey.GetID();
    obj.push_back(Pair("handshakelocal",GetArg("-handshakelocal",CFFFAddress(keyID).ToString())));
    obj.push_back(Pair("bantx",GetArg("-bantx","")));
    obj.push_back(Pair("lockblock",GetArg("-lockblock","")));
    obj.push_back(Pair("hideknownopdrops",GetBoolArg("-hideknownopdrops",false)));
    obj.push_back(Pair("maxshowndata",GetArg("-maxshowndata",MAX_OP_RETURN_SHOWN)));
    obj.push_back(Pair("maxqueryscanitems",GetArg("-maxqueryscanitems",MAX_STREAM_QUERY_ITEMS)));
    obj.push_back(Pair("v1apicompatible",GetBoolArg("-v1apicompatible",false)));
    obj.push_back(Pair("miningrequirespeers",Params().MiningRequiresPeers()));
    obj.push_back(Pair("mineemptyrounds",Params().MineEmptyRounds()));
    obj.push_back(Pair("miningturnover",Params().MiningTurnover()));
    obj.push_back(Pair("lockadminminerounds",Params().LockAdminMineRounds()));
    obj.push_back(Pair("gen",GetBoolArg("-gen", true)));
    obj.push_back(Pair("genproclimit",GetArg("-genproclimit", 1)));
    obj.push_back(Pair("lockinlinemetadata",GetBoolArg("-lockinlinemetadata", true)));
    obj.push_back(Pair("acceptfiltertimeout",GetArg("-acceptfiltertimeout", DEFAULT_ACCEPT_FILTER_TIMEOUT)));
    obj.push_back(Pair("sendfiltertimeout",GetArg("-sendfiltertimeout", DEFAULT_SEND_FILTER_TIMEOUT)));
/*
    obj.push_back(Pair("shortoutput",GetBoolArg("-shortoutput",false)));
    obj.push_back(Pair("walletdbversion", mc_gState->GetWalletDBVersion()));
*/
    return obj;
}

bool paramtobool(Value param,bool strict)
{
    if(!strict)
    {
        if(param.type() == str_type)
        {
            if(param.get_str() == "true")
            {
                return true;
            }
            return atoi(param.get_str().c_str()) != 0;
        }
        if(param.type() == int_type)
        {
            if(param.get_int())
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    if(param.type() != bool_type)
    {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type, should be boolean");
    }

    return param.get_bool();
}

bool paramtobool(Value param)
{
    return paramtobool(param,true);
}

Value setruntimeparam(const json_spirit::Array& params, bool fHelp)
{
    if (fHelp || params.size() != 2)
        throw runtime_error("Help message not found\n");

    if(mc_gState->m_NetworkParams->IsProtocolFFF_Core() == 0)
    {
        throw JSONRPCError(RPC_NOT_SUPPORTED, "This API is supported only if protocol=FFF_Core");
    }

    string param_name=params[0].get_str();
    string old_value="";
    bool old_value_found=false;
    if (mapArgs.count("-" + param_name))
    {
        old_value_found=true;
        old_value=mapArgs["-" + param_name];
    }

    bool fFound=false;
    if(param_name == "miningrequirespeers")
    {
        mapArgs ["-" + param_name]=paramtobool(params[1],false) ? "1" : "0";
        fFound=true;
    }
    if(param_name == "mineemptyblocks")
    {
        mapArgs ["-" + param_name]=paramtobool(params[1],false) ? "1" : "0";
        fFound=true;
    }
    if(param_name == "mineblocksondemand")
    {
        mapArgs ["-" + param_name]=paramtobool(params[1],false) ? "1" : "0";
        fFound=true;
    }
    if(param_name == "hideknownopdrops")
    {
        mapArgs ["-" + param_name]=paramtobool(params[1],false) ? "1" : "0";
        fFound=true;
    }
    if(param_name == "lockinlinemetadata")
    {
        mapArgs ["-" + param_name]=paramtobool(params[1],false) ? "1" : "0";
        fFound=true;
    }
    if(param_name == "mineemptyrounds")
    {
        if( (params[1].type() == real_type) || (params[1].type() == str_type) )
        {
            double dValue;
            if(params[1].type() == real_type)
            {
                dValue=params[1].get_real();
            }
            else
            {
                dValue=atof(params[1].get_str().c_str());
            }
            mapArgs ["-" + param_name]= strprintf("%f", dValue);
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if(param_name == "miningturnover")
    {
        if( (params[1].type() == real_type) || (params[1].type() == str_type) )
        {
            double dValue;
            if(params[1].type() == real_type)
            {
                dValue=params[1].get_real();
            }
            else
            {
                dValue=atof(params[1].get_str().c_str());
            }
            if( (dValue >= 0.) && (dValue <= 1.) )
            {
                mapArgs ["-" + param_name]= strprintf("%f", dValue);
            }
            else
            {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Should be in range (0,1)");
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if( (param_name == "lockadminminerounds") ||
        (param_name == "maxshowndata") ||
        (param_name == "maxqueryscanitems") ||
        (param_name == "acceptfiltertimeout") ||
        (param_name == "sendfiltertimeout") ||
        (param_name == "dropmessagestest") )
    {
        if( (params[1].type() == int_type) || (params[1].type() == str_type) )
        {
            int nValue;
            if(params[1].type() == int_type)
            {
                nValue=params[1].get_int();
            }
            else
            {
                nValue=atoi(params[1].get_str().c_str());
            }
            if( nValue >= 0 )
            {
                mapArgs ["-" + param_name]=strprintf("%d", nValue);
                if(param_name == "acceptfiltertimeout")
                {
                    if(pFFF_CoreFilterEngine)
                    {
                        pFFF_CoreFilterEngine->SetTimeout(pFFF_CoreFilterEngine->GetAcceptTimeout());
                    }
                }
            }
            else
            {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Should be non-negative");
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if( (param_name == "compatibility") )
    {
        if( (params[1].type() == int_type) || (params[1].type() == str_type) )
        {
            int nValue;
            if(params[1].type() == int_type)
            {
                nValue=params[1].get_int();
            }
            else
            {
                nValue=atoi(params[1].get_str().c_str());
            }
            mc_gState->m_Compatibility=(uint32_t)nValue;
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if(param_name == "bantx")
    {
        if(params[1].type() == str_type)
        {
            string error=SetBannedTxs(params[1].get_str());
            if(error.size())
            {
                throw JSONRPCError(RPC_INVALID_PARAMETER, error);
            }
            else
            {
                mapArgs ["-" + param_name]=params[1].get_str();
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if(param_name == "lockblock")
    {
        if(params[1].type() == str_type)
        {
            string error=SetLockedBlock(params[1].get_str());
            if(error.size())
            {
                throw JSONRPCError(RPC_INVALID_PARAMETER, error);
            }
            else
            {
                mapArgs ["-" + param_name]=params[1].get_str();
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if(param_name == "handshakelocal")
    {
        if(params[1].type() == str_type)
        {
            CFFFAddress address(params[1].get_str());
            if (!address.IsValid())
            {
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
            }
            else
            {
                mapArgs ["-" + param_name]=params[1].get_str();
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }
    if(param_name == "autosubscribe")
    {
        if(params[1].type() == str_type)
        {
            string autosubscribe=params[1].get_str();
            uint32_t mode=MC_WMD_NONE;

            mode |= mc_AutosubscribeWalletMode(params[1].get_str(),false);

/*
            bool found=false;
            if(autosubscribe=="streams")
            {
                mode |= MC_WMD_AUTOSUBSCRIBE_STREAMS;
                found=true;
            }
            if(autosubscribe=="assets")
            {
                mode |= MC_WMD_AUTOSUBSCRIBE_ASSETS;
                found=true;
            }
            if( (autosubscribe=="assets,streams") || (autosubscribe=="streams,assets"))
            {
                mode |= MC_WMD_AUTOSUBSCRIBE_STREAMS;
                mode |= MC_WMD_AUTOSUBSCRIBE_ASSETS;
                found=true;
            }
            if( autosubscribe=="" )
            {
                found=true;
            }
            if(!found)
            {
                throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value");
            }
*/
            if(mode == MC_WMD_NONE)
            {
                if(params[1].get_str().size() != 0)
                {
                    throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value");
                }
            }

            if(pwalletTxsMain)
            {
                pwalletTxsMain->SetMode(mode,MC_WMD_AUTOSUBSCRIBE_STREAMS | MC_WMD_AUTOSUBSCRIBE_ASSETS);
            }
            mapArgs ["-" + param_name]=params[1].get_str();
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter value type");
        }
        fFound=true;
    }

    if(!fFound)
    {
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Unsupported runtime parameter: " + param_name);
    }

    if(mc_StoreSetRuntimeParam(param_name))
    {
        if(old_value_found)
        {
            mapArgs["-" + param_name]=old_value;
        }
        else
        {
            mapArgs.erase("-" + param_name);
        }
        throw JSONRPCError(RPC_GENERAL_FILE_ERROR, "Cannot store new parameter value permanently");
    }

    SetFFF_CoreRuntimeParams();

    return Value::null;
}

Value getblockchainparams(const json_spirit::Array& params, bool fHelp)
{
    if (fHelp || params.size() > 2)                                            // MCHN
        throw runtime_error("Help message not found\n");

    bool fDisplay = true;
    if (params.size() > 0)
        fDisplay = params[0].get_bool();

    int nHeight=chainActive.Height();
    if (params.size() > 1)
    {
        if(params[1].type() == bool_type)
        {
            if(!params[1].get_bool())
            {
                nHeight=0;
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "with-upgrades should be boolean");
/*
            if(params[1].type() == int_type)
            {
                nHeight=params[1].get_int();
            }
 */
        }
    }

    if (nHeight < 0 || nHeight > chainActive.Height())
    {
        nHeight+=chainActive.Height();
        if (nHeight <= 0 || nHeight > chainActive.Height())
        {
            throw JSONRPCError(RPC_BLOCK_NOT_FOUND, "Block height out of range");
        }
    }

    Object obj;
    int protocol_version=(int)mc_gState->m_NetworkParams->GetInt64Param("protocolversion");

    if(nHeight)
    {
        protocol_version=mc_gState->m_NetworkParams->ProtocolVersion();
    }

    for(int i=0;i<mc_gState->m_NetworkParams->m_Count;i++)
    {
        if((mc_gState->m_NetworkParams->m_lpParams+i)->IsRelevant(protocol_version))
        {

            string param_name;
            Value param_value;
            unsigned char* ptr;
            int size;
            bool hidden=false;
            string param_string="";;

            ptr=(unsigned char*)mc_gState->m_NetworkParams->GetParam((mc_gState->m_NetworkParams->m_lpParams+i)->m_Name,&size);
            if(size == 0)
            {
                ptr=NULL;
            }
/*
            else
            {
                if(((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_DATA_TYPE_MASK) == MC_PRM_STRING)
                {
                    if(size == 1)
                    {
                        ptr=NULL;
                    }
                }
            }
*/
            if(fDisplay)
            {
                param_name=(mc_gState->m_NetworkParams->m_lpParams+i)->m_DisplayName;
            }
            else
            {
                param_name=(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name;
            }

            if(ptr)
            {
                switch((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_DATA_TYPE_MASK)
                {
                    case MC_PRM_BINARY:
                        for(int c=0;c<size;c++)
                        {
                            param_string += strprintf("%02x",*((unsigned char*)ptr+c));
                        }
                        param_value=param_string;
                        break;
                    case MC_PRM_STRING:
                        param_value = string((char*)ptr);
                        break;
                    case MC_PRM_BOOLEAN:
                        if(*(char*)ptr)
                        {
                            param_value=true;
                        }
                        else
                        {
                            param_value=false;
                        }
                        break;
                    case MC_PRM_INT32:
                        if((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_DECIMAL)
                        {
//                            param_value=((double)(int)mc_GetLE(ptr,4))/MC_PRM_DECIMAL_GRANULARITY;
                            int n=(int)mc_GetLE(ptr,4);
                            if(n >= 0)
                            {
//                                param_value=((double)n+mc_gState->m_NetworkParams->ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY;
                                param_value=((double)n)/MC_PRM_DECIMAL_GRANULARITY;
                            }
                            else
                            {
//                                param_value=-((double)(-n)+mc_gState->m_NetworkParams->ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY;
                                param_value=-((double)(-n))/MC_PRM_DECIMAL_GRANULARITY;
                            }
                        }
                        else
                        {
                            param_value=(int)mc_GetLE(ptr,4);
                        }
                        break;
                    case MC_PRM_UINT32:
                        if((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_DECIMAL)
                        {
//                            param_value=((double)mc_GetLE(ptr,4)+mc_gState->m_NetworkParams->ParamAccuracy())/MC_PRM_DECIMAL_GRANULARITY;
                            param_value=((double)mc_GetLE(ptr,4))/MC_PRM_DECIMAL_GRANULARITY;
                        }
                        else
                        {
                            param_value=mc_GetLE(ptr,4);
                            if((mc_gState->m_NetworkParams->m_lpParams+i)->m_Type & MC_PRM_HIDDEN)
                            {
                                if(mc_GetLE(ptr,4) == (mc_gState->m_NetworkParams->m_lpParams+i)->m_DefaultIntegerValue)
                                {
                                    hidden=true;
                                }
                            }
                        }
                        break;
                    case MC_PRM_INT64:
                        param_value=mc_GetLE(ptr,8);
                        break;
                    case MC_PRM_DOUBLE:
                        param_value=*(double*)ptr;
                        break;
                }
            }
            else
            {
                param_value=Value::null;
            }
            if(nHeight)
            {
                if(strcmp("protocolversion",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=mc_gState->m_NetworkParams->m_ProtocolVersion;
                }
                if(strcmp("maximumblocksize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_BLOCK_SIZE;
                }
                if(strcmp("targetblocktime",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MCP_TARGET_BLOCK_TIME;
                }
                if(strcmp("maxstdtxsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_STANDARD_TX_SIZE;
                }
                if(strcmp("maxstdopreturnscount",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MCP_MAX_STD_OP_RETURN_COUNT;
                }
                if(strcmp("maxstdopreturnsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_OP_RETURN_RELAY;
                }
                if(strcmp("maxstdopdropscount",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MCP_STD_OP_DROP_COUNT;
                }
                if(strcmp("maxstdelementsize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_SCRIPT_ELEMENT_SIZE;
                }
                if(strcmp("maximumchunksize",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_CHUNK_SIZE;
                }
                if(strcmp("maximumchunkcount",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(int)MAX_CHUNK_COUNT;
                }
                if(strcmp("anyonecanconnect",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_CONNECT != 0);
                }
                if(strcmp("anyonecansend",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_SEND != 0);
                }
                if(strcmp("anyonecanreceive",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_RECEIVE != 0);
                }
                if(strcmp("anyonecanreceiveempty",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_RECEIVE_EMPTY != 0);
                }
                if(strcmp("anyonecancreate",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_CREATE != 0);
                }
                if(strcmp("anyonecanissue",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_ISSUE != 0);
                }
                if(strcmp("anyonecanactivate",(mc_gState->m_NetworkParams->m_lpParams+i)->m_Name) == 0)
                {
                    param_value=(MCP_ANYONE_CAN_ACTIVATE != 0);
                }
            }

            if(!hidden)
            {
                obj.push_back(Pair(param_name,param_value));
            }
        }
    }

    return obj;
}

void SetSynchronizedFlag(CTxDestination &dest,Object &ret)
{
    if(mc_gState->m_WalletMode & MC_WMD_ADDRESS_TXS)
    {
        mc_TxEntityStat entStat;
        CKeyID *lpKeyID=boost::get<CKeyID> (&dest);
        CScriptID *lpScriptID=boost::get<CScriptID> (&dest);
        entStat.Zero();
        if(lpKeyID)
        {
            memcpy(&entStat,lpKeyID,MC_TDB_ENTITY_ID_SIZE);
            entStat.m_Entity.m_EntityType=MC_TET_PUBKEY_ADDRESS | MC_TET_CHAINPOS;
        }
        if(lpScriptID)
        {
            memcpy(&entStat,lpScriptID,MC_TDB_ENTITY_ID_SIZE);
            entStat.m_Entity.m_EntityType=MC_TET_SCRIPT_ADDRESS | MC_TET_CHAINPOS;
        }
        if(pwalletTxsMain->FindEntity(&entStat))
        {
            if(entStat.m_Flags & MC_EFL_NOT_IN_SYNC)
            {
                ret.push_back(Pair("synchronized",false));
                ret.push_back(Pair("startblock",entStat.m_LastImportedBlock+1));
            }
            else
            {
                ret.push_back(Pair("synchronized",true));
            }
        }
    }
}

Object AddressEntry(CFFFAddress& address,uint32_t verbose)
{
// 0x01 add isvalid=true
// 0x02 verbose

    Object ret;
    if(verbose & 0x01)
    {
        ret.push_back(Pair("isvalid", true));
    }
    CTxDestination dest = address.Get();
    string currentAddress = address.ToString();
    ret.push_back(Pair("address", currentAddress));
#ifdef ENABLE_WALLET
    isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
    ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
    if(verbose & 0x02)
    {
        if (mine != ISMINE_NO) {
            ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
            Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
            ret.insert(ret.end(), detail.begin(), detail.end());
        }
        if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
            ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
    #endif
        SetSynchronizedFlag(dest,ret);
    }

    return ret;
}

/* MCHN END */

Value validateaddress(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)                                            // MCHN
        throw runtime_error("Help message not found\n");

    string str=params[0].get_str();
    CFFFAddress address(str);
    bool isValid = address.IsValid();

    Object ret;
/* MCHN START */
    if(!isValid)
    {
        CFFFSecret vchSecret;
        CPubKey pubkey;
        isValid = vchSecret.SetString(str);

        if (isValid)
        {
            CKey key;
            key = vchSecret.GetKey();
            isValid=key.IsValid();
            if (isValid)
            {
                pubkey = key.GetPubKey();
                isValid=key.VerifyPubKey(pubkey);
            }
        }
        else
        {
            if (IsHex(str))
            {
                pubkey=CPubKey(ParseHex(str));
                isValid=pubkey.IsFullyValid();
            }
        }
        if(isValid)
        {
            address=CFFFAddress(pubkey.GetID());
        }
    }

    if(!isValid)
    {
        ret.push_back(Pair("isvalid", false));
        return ret;
    }

    return AddressEntry(address,0x03);
/*
    ret.push_back(Pair("isvalid", isValid));
    if (isValid)
    {
        CTxDestination dest = address.Get();
        string currentAddress = address.ToString();
        ret.push_back(Pair("address", currentAddress));
#ifdef ENABLE_WALLET
        isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
        ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
        if (mine != ISMINE_NO) {
            ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
            Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
            ret.insert(ret.end(), detail.begin(), detail.end());
        }
        if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
            ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
#endif
        SetSynchronizedFlag(dest,ret);

    }
*/
//    return ret;
/* MCHN END */
}

/* MCHN START */

Value createkeypairs(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 1)                                            // MCHN
        throw runtime_error("Help message not found\n");

    int count=1;
    if (params.size() > 0)
    {
        count=paramtoint(params[0],true,0,"Invalid count");
    }

    Array retArray;
    bool fCompressed = true;

    for(int i=0;i<count;i++)
    {
        CKey secret;
        secret.MakeNewKey(fCompressed);

        CPubKey pubkey = secret.GetPubKey();

        Object entry;
        entry.push_back(Pair("address", CFFFAddress(pubkey.GetID()).ToString()));
        entry.push_back(Pair("pubkey", HexStr(pubkey)));
        entry.push_back(Pair("privkey", CFFFSecret(secret).ToString()));

        retArray.push_back(entry);
    }

    return retArray;
}

Value getaddresses(const Array& params, bool fHelp)
{
    if (fHelp || params.size() > 1)                                            // MCHN
        throw runtime_error("Help message not found\n");

    int verbose=0x00;

    if (params.size() > 0)
    {
        if(params[0].type() == bool_type)
        {
            if(params[0].get_bool())
            {
                verbose=0x02;
            }
        }
        else
        {
            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid value for 'verbose' parameter, should be boolean");
        }
    }

    Array ret;

    if((mc_gState->m_WalletMode & MC_WMD_TXS))
    {
        int entity_count;
        mc_TxEntityStat *lpEntity;

        entity_count=pwalletTxsMain->GetEntityListCount();
        for(int i=0;i<entity_count;i++)
        {
            lpEntity=pwalletTxsMain->GetEntity(i);
            CFFFAddress address;
            if( ((lpEntity->m_Entity.m_EntityType & MC_TET_ORDERMASK) == MC_TET_CHAINPOS) &&
                ((lpEntity->m_Flags & MC_EFL_NOT_IN_LISTS) == 0 ) )
            {
                if(CFFFAddressFromTxEntity(address,&(lpEntity->m_Entity)))
                {
                    if(verbose)
                    {
                        ret.push_back(AddressEntry(address,verbose));
                    }
                    else
                    {
                        ret.push_back(address.ToString());
                    }
                }
            }
        }
    }
    else
    {
        // Find all addresses that have the given account
        BOOST_FOREACH(const PAIRTYPE(CFFFAddress, CAddressBookData)& item, pwalletMain->mapAddressBook)
        {
            const CFFFAddress& address = item.first;

            if(verbose)
            {
                Object addr;
                CTxDestination dest = address.Get();
                string currentAddress = address.ToString();
                addr.push_back(Pair("address", currentAddress));
                isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO;
                addr.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
                if (mine != ISMINE_NO) {
                    addr.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
                    Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
                    addr.insert(addr.end(), detail.begin(), detail.end());
                }
                if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
                    addr.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));

                SetSynchronizedFlag(dest,addr);

                ret.push_back(addr);
            }
            else
            {
                ret.push_back(address.ToString());
            }

        }
    }
    return ret;
}

/* MCHN END */
/**
 * Used by addmultisigaddress / createmultisig:
 */
CScript _createmultisig_redeemScript(const Array& params)
{
    int nRequired = params[0].get_int();
    const Array& keys = params[1].get_array();

    // Gather public keys
    if (nRequired < 1)
        throw runtime_error("a multisignature address must require at least one key to redeem");
    if ((int)keys.size() < nRequired)
        throw runtime_error(
            strprintf("not enough keys supplied "
                      "(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
    if (keys.size() > 16)
        throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
    std::vector<CPubKey> pubkeys;
    pubkeys.resize(keys.size());
    for (unsigned int i = 0; i < keys.size(); i++)
    {
        const std::string& ks = keys[i].get_str();
#ifdef ENABLE_WALLET
        // Case 1: FFF address and we have full public key:
        CFFFAddress address(ks);
        if (pwalletMain && address.IsValid())
        {
            CKeyID keyID;
            if (!address.GetKeyID(keyID))
                throw runtime_error(
                    strprintf("%s does not refer to a key",ks));
            CPubKey vchPubKey;
            if (!pwalletMain->GetPubKey(keyID, vchPubKey))
                throw runtime_error(
                    strprintf("no full public key for address %s",ks));
            if (!vchPubKey.IsFullyValid())
                throw runtime_error(" Invalid public key: "+ks);
            pubkeys[i] = vchPubKey;
        }

        // Case 2: hex public key
        else
#endif
        if (IsHex(ks))
        {
            CPubKey vchPubKey(ParseHex(ks));
            if (!vchPubKey.IsFullyValid())
                throw runtime_error(" Invalid public key: "+ks);
            pubkeys[i] = vchPubKey;
        }
        else
        {
            throw runtime_error(" Invalid public key: "+ks);
        }
    }
    CScript result = GetScriptForMultisig(nRequired, pubkeys);

    if(Params().RequireStandard())
    {
        if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
            throw runtime_error(
                    strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
    }

    return result;
}

Value createmultisig(const Array& params, bool fHelp)
{
    if (fHelp || params.size() < 2 || params.size() > 2)                        // MCHN
    {
        throw runtime_error("Help message not found\n");
    }

/* MCHN START */
    if(mc_gState->m_NetworkParams->IsProtocolFFF_Core())
    {
        if((MCP_ALLOW_ARBITRARY_OUTPUTS == 0) || (mc_gState->m_Features->FixedDestinationExtraction() == 0) )
        {
            if(MCP_ALLOW_P2SH_OUTPUTS == 0)
            {
                throw JSONRPCError(RPC_NOT_ALLOWED, "P2SH outputs are not allowed for this blockchain");
            }
        }
    }
/* MCHN END */

    // Construct using pay-to-script-hash:
    CScript inner = _createmultisig_redeemScript(params);
    CScriptID innerID(inner);
    CFFFAddress address(innerID);

    Object result;
    result.push_back(Pair("address", address.ToString()));
    result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));

    return result;
}

Value verifymessage(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 3)                                            // MCHN
        mc_ThrowHelpMessage("verifymessage");

    string strAddress  = params[0].get_str();
    string strSign     = params[1].get_str();
    string strMessage  = params[2].get_str();

    CFFFAddress addr(strAddress);
    if (!addr.IsValid())
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");

    CKeyID keyID;
    if (!addr.GetKeyID(keyID))
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Address does not refer to key");

    bool fInvalid = false;
    vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);

    if (fInvalid)
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Malformed base64 encoding");

    CHashWriter ss(SER_GETHASH, 0);
    ss << strMessageMagic;
    ss << strMessage;

    CPubKey pubkey;
    if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
        return false;

    return (pubkey.GetID() == keyID);
}

Value setmocktime(const Array& params, bool fHelp)
{
    if (fHelp || params.size() != 1)
        throw runtime_error("Help message not found\n");

    if (!Params().MineBlocksOnDemand())
        throw runtime_error("setmocktime for regression testing (-regtest mode) only");

    RPCTypeCheck(params, boost::assign::list_of(int_type));
    SetMockTime(params[0].get_int64());

    return Value::null;
}