aboutsummaryrefslogblamecommitdiff
path: root/include/hotstuff/util.h
blob: 930bc89f10a7f0febc49c2417d4b0b94731cd30b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16















                                                                           


                        
                            






                                         



                                      
                                                                                    

                   



                     



                                 
                         

                                 
                                 

      
                          





















                                                                    





                                                                   

                                                                   
                           









































































                                                                                  
/**
 * Copyright 2018 VMware
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _HOTSTUFF_UTIL_H
#define _HOTSTUFF_UTIL_H

#include "hotstuff/config.h"
#include "salticidae/util.h"

namespace hotstuff {

class Logger: public salticidae::Logger {
    public:
    using salticidae::Logger::Logger;

    void proto(const char *fmt, ...) {
        va_list ap;
        va_start(ap, fmt);
        write("proto", is_tty() ? salticidae::TTY_COLOR_MAGENTA : nullptr, fmt, ap);
        va_end(ap);
    }
};

extern Logger logger;

#ifdef HOTSTUFF_PROTO_LOG
#define HOTSTUFF_ENABLE_LOG_PROTO
#endif

#ifdef HOTSTUFF_DEBUG_LOG
#define HOTSTUFF_NORMAL_LOG
#define HOTSTUFF_ENABLE_LOG_DEBUG
#define HOTSTUFF_ENABLE_LOG_PROTO
#endif

#ifdef HOTSTUFF_NORMAL_LOG
#define HOTSTUFF_ENABLE_LOG_INFO
#define HOTSTUFF_ENABLE_LOG_WARN
#endif

#ifdef HOTSTUFF_ENABLE_LOG_INFO
#define HOTSTUFF_LOG_INFO(...) hotstuff::logger.info(__VA_ARGS__)
#else
#define HOTSTUFF_LOG_INFO(...) ((void)0)
#endif

#ifdef HOTSTUFF_ENABLE_LOG_DEBUG
#define HOTSTUFF_LOG_DEBUG(...) hotstuff::logger.debug(__VA_ARGS__)
#else
#define HOTSTUFF_LOG_DEBUG(...) ((void)0)
#endif

#ifdef HOTSTUFF_ENABLE_LOG_WARN
#define HOTSTUFF_LOG_WARN(...) hotstuff::logger.warning(__VA_ARGS__)
#else
#define HOTSTUFF_LOG_WARN(...) ((void)0)
#endif

#ifdef HOTSTUFF_ENABLE_LOG_PROTO
#define HOTSTUFF_LOG_PROTO(...) hotstuff::logger.proto(__VA_ARGS__)
#else
#define HOTSTUFF_LOG_PROTO(...) ((void)0)
#endif

#define HOTSTUFF_LOG_ERROR(...) hotstuff::logger.error(__VA_ARGS__)

#ifdef HOTSTUFF_BLK_PROFILE
class BlockProfiler {
    enum BlockState {
        BLK_SEEN,
        BLK_FETCH,
        BLK_CC
    };

    struct BlockProfile {
        bool is_local;          /* is the block proposed by the replica itself? */
        BlockState state;
        double hash_seen_time;  /* the first time to see block hash */
        double full_fetch_time; /* the first time to get full block content */
        double cc_time;         /* the time when it receives cc */
        double commit_time;     /* the time when it commits */
    };

    std::unordered_map<const uint256, BlockProfile> blocks;
    ElapsedTime timer;

    public:
    BlockProfiler() { timer.start(); }

    auto rec_blk(const uint256 &blk_hash, bool is_local) {
        auto it = blocks.find(blk_hash);
        assert(it == blocks.end());
        timer.stop(false);
        return blocks.insert(std::make_pair(blk_hash,
            BlockProfile{is_local, BLK_SEEN, timer.elapsed_sec, 0, 0, 0})).first;
    }

    void get_blk(const uint256 &blk_hash) {
        auto it = blocks.find(blk_hash);
        if (it == blocks.end())
            it = rec_blk(blk_hash, false);
        BlockProfile &blkp = it->second;
        assert(blkp.state == BLK_SEEN);
        timer.stop(false);
        blkp.full_fetch_time = timer.elapsed_sec;
        blkp.state = BLK_FETCH;
    }

    void have_cc(const uint256 &blk_hash) {
        auto it = blocks.find(blk_hash);
        assert(it != blocks.end());
        BlockProfile &blkp = it->second;
        assert(blkp.state == BLK_FETCH);
        timer.stop(false);
        blkp.polling_start_time = timer.elapsed_sec;
        blkp.state = BLK_CC;
    }

    const char *decide_blk(const uint256 &blk_hash) {
        static char buff[1024];
        auto it = blocks.find(blk_hash);
        assert(it != blocks.end());
        BlockProfile &blkp = it->second;
        assert(blkp.state == BLK_CC);
        timer.stop(false);
        blkp.commit_time = timer.elapsed_sec;
        snprintf(buff, sizeof buff, "(%d,%.4f,%.4f,%.4f,%.4f,%.4f)",
                blkp.is_local,
                blkp.hash_seen_time, blkp.full_fetch_time,
                blkp.polling_start_time, blkp.polling_end_time,
                blkp.commit_time);
        blocks.erase(it);
        return buff;
    }
};

#endif

}

#endif