Exemplo n.º 1
0
def on_receive(receiver, type, msg_hash, N):
    if type == 'block':
        res = accept_block(receiver, msg_hash, N)
    else:
        res = accept_vote(receiver, msg_hash)
        return
    if res:
        is_in_attack_chain = get_block_field(msg_hash, 'is_in_attack_chain')
        dep = get_field(receiver, is_in_attack_chain, 'dependencies')
        if int(msg_hash) in dep.keys():
            dep = get_field(receiver, is_in_attack_chain, 'dependencies')
            for child_hash in dep[int(msg_hash)][0]:
                on_receive(receiver, 'block', child_hash, N)
            for child_hash in dep[int(msg_hash)][1]:
                on_receive(receiver, 'vote', child_hash, N)
            # print("miner " + str(receiver) + " deletes " + \
            # 	str(str(hash) +":" + str(dep[int(hash)])) + "from its dependencies")
            del dep[int(msg_hash)]
            #print("删除依赖")
            update_field(receiver, is_in_attack_chain, 'dependencies', dep)
Exemplo n.º 2
0
def maybe_vote_last_checkpoint(miner, hash, is_in_attack_chain, N):
    target_block = hash  #参数是str类型的
    source_block = get_field(miner, is_in_attack_chain,
                             'highest_justified_checkpoint')

    #target_block_epoch是int型的数据,而vote表中target_epoch也是int型
    target_block_epoch = get_block_field(target_block, 'epoch')
    miner_current_epoch = get_field(miner, is_in_attack_chain, 'current_epoch')

    if target_block_epoch > miner_current_epoch:
        miner_current_epoch = target_block_epoch
        #pdb.set_trace()
        update_field(miner, is_in_attack_chain, 'current_epoch',
                     miner_current_epoch)

        if is_ancestor(miner, source_block, target_block, is_in_attack_chain):
            hash = random.randint(1, 10**30)
            sender = miner
            source_block_epoch = get_block_field(source_block, 'epoch')
            sql_vote = "insert into vote values("\
             + "'" + str(hash) + "',"\
             + str(sender) + ","\
             + "'" + str(source_block) + "',"\
             + "'" + str(target_block) + "',"\
             + str(source_block_epoch) + ","\
             + str(target_block_epoch) + ","\
             + str(is_in_attack_chain) + ");"
            chain = 'attack' if is_in_attack_chain else 'honest'
            sql_broadcast = broadcast(chain, hash,
                                      (N + 1) * Block_Proposal_Time, miner,
                                      'vote')
            db = pymysql.connect("localhost", "root", "root", "attack_casper")
            cur = db.cursor()
            cur.execute(sql_vote)
            cur.execute(sql_broadcast)
            db.commit()
            cur.close()
            db.close()
Exemplo n.º 3
0
def miner_view(miner_id):
    blocks = []
    if miner_id in miners['attacker']:
        processed = get_field(miner_id, 0, 'processed')
        for block_hash in processed:
            blocks.append(str(block_hash))
        processed = get_field(miner_id, 1, 'processed')
        for block_hash in processed:
            blocks.append(str(block_hash))
    else:
        processed = get_field(miner_id, 0, 'processed')
        for block_hash in processed:
            blocks.append(str(block_hash))
    blocks = str(blocks)
    blocks = blocks.replace("[", "(")
    blocks = blocks.replace("]", ")")
    sql_get_block_info = "select hash, pre_hash, is_in_attack_chain, type, height"\
     " from block where hash in " + blocks + " ;"
    db = pymysql.connect("localhost", "root", "root", "attack_casper")
    cur = db.cursor()
    cur.execute(sql_get_block_info)
    result = cur.fetchall()
    db.commit()
    cur.close()
    db.close()

    G = nx.DiGraph()
    for item in result:
        hash = item[0]
        pre_hash = item[1]
        height = item[4]
        G.add_node(hash, object=[item[3], height])  #item[3]是字符串类型,type
        if hash != pre_hash:
            G.add_edge(hash, pre_hash,
                       object=item[2])  #item[2]是int型,is_in_attack_chain
    return G
Exemplo n.º 4
0
def check_head(receiver, hash, is_in_attack_chain):
    highest_justified_checkpoint_hash = get_field(
        receiver, is_in_attack_chain, 'highest_justified_checkpoint')
    tail_membership = get_field(receiver, is_in_attack_chain,
                                'tail_membership')

    #print("观察is_ancestor函数")
    if is_ancestor(receiver, highest_justified_checkpoint_hash, \
     tail_membership[int(hash)], is_in_attack_chain):
        update_field(receiver, is_in_attack_chain, 'head', hash)
    else:
        print('Wrong chain, reset the chain to be a descendant of the '
              'highest justified checkpoint.')
        max_height = get_block_field(highest_justified_checkpoint_hash,
                                     'height')
        max_descendant = highest_justified_checkpoint_hash
        tails = get_field(receiver, is_in_attack_chain, 'tails')
        for _hash in tails:
            if is_ancestor(receiver, highest_justified_checkpoint_hash, _hash,
                           is_in_attack_chain):
                new_height = get_block_field(tails[_hash], 'height')
                if new_height > max_height:
                    max_descendant = tails[_hash]
        update_field(receiver, is_in_attack_chain, 'head', max_descendant)
Exemplo n.º 5
0
def get_checkpoint_parent(receiver, is_in_attack_chain, hash):
    sql_block_info = "select height, pre_hash from block where hash = '" + str(
        hash) + "';"
    db = pymysql.connect("localhost", "root", "root", "attack_casper")
    cur = db.cursor()
    cur.execute(sql_block_info)
    res = cur.fetchall()
    db.commit()
    cur.close()
    db.close()

    height = res[0][0]
    pre_hash = res[0][1]

    tail_membership = get_field(receiver, is_in_attack_chain,
                                'tail_membership')

    #print("观察height 和 tail_membership[pre_hash]的值为多少")
    if height == 0:
        return None
    return tail_membership[int(pre_hash)]
Exemplo n.º 6
0
def accept_vote(receiver, hash):
    source_hash = int(get_vote_field(hash, 'source_hash'))  #是str转int
    target_hash = int(get_vote_field(hash, 'target_hash'))
    is_in_attack_chain = get_block_field(target_hash, 'is_in_attack_chain')
    processed = get_field(receiver, is_in_attack_chain, 'processed')
    #pdb.set_trace()
    if source_hash not in processed:
        dep = get_field(receiver, is_in_attack_chain, 'dependencies')
        if source_hash not in dep.keys():
            dep[source_hash] = [[], []]  #依赖分为两种,一种是区块,一种是vote,第一个list记录
        dep[source_hash][1].append(int(hash))
        update_field(receiver, is_in_attack_chain, 'dependencies', dep)
        return False

    justified = get_field(receiver, is_in_attack_chain, 'justified')
    if source_hash not in justified:
        return False

    if target_hash not in processed:
        dep = get_field(receiver, is_in_attack_chain, 'dependencies')
        if target_hash not in dep.keys():
            dep[target_hash] = [[], []]  #依赖分为两种,一种是区块,一种是vote,第一个list记录
        dep[target_hash][1].append(int(hash))
        update_field(receiver, is_in_attack_chain, 'dependencies', dep)
        return False

    if not is_ancestor(receiver, source_hash, target_hash, is_in_attack_chain):
        return False

    #TODO:增加一个vote的sender是否属于volidator验证集合的判断,毫无必要

    sender = get_vote_field(hash, 'sender')
    votes = get_field(receiver, is_in_attack_chain, 'votes')
    if sender not in votes:
        votes[sender] = []
    target_epoch = get_vote_field(hash, 'target_epoch')
    source_epoch = get_vote_field(hash, 'source_epoch')
    for past_vote_hash in votes[sender]:
        past_target_epoch = get_vote_field(past_vote_hash, 'target_epoch')
        if past_target_epoch == target_epoch:
            print("miner %d got slashed! " % sender)
            deposit = get_field(receiver, is_in_attack_chain, 'deposit')
            deposit[sender] = 0
            update_field(receiver, is_in_attack_chain, 'deposit', deposit)
            #stake = get_field(receiver, is_in_attack_chain, 'stake')
            #需要更新deposit和stake
            return False

        past_source_epoch = get_vote_field(past_vote_hash, 'source_epoch')
        if (past_source_epoch < source_epoch and past_target_epoch > target_epoch)\
         or (past_source_epoch > source_epoch and past_target_epoch < target_epoch):
            print("miner %d got slashed! " % sender)
            deposit = get_field(receiver, is_in_attack_chain, 'deposit')
            deposit[sender] = 0
            update_field(receiver, is_in_attack_chain, 'deposit', deposit)
            return False
    votes[sender].append(int(hash))
    update_field(receiver, is_in_attack_chain, 'votes', votes)

    print(f"miner %d accept the vote of hash {hash}" % receiver)
    deposit = get_field(receiver, is_in_attack_chain, 'deposit')
    vote_count = get_field(receiver, is_in_attack_chain, 'vote_count')
    if source_hash not in vote_count:
        vote_count[source_hash] = {}
    vote_count[source_hash][target_hash] = \
     vote_count[source_hash].get(target_hash, 0) + deposit[sender]
    update_field(receiver, is_in_attack_chain, 'vote_count', vote_count)
    total = 0
    for key in deposit.keys():
        total += deposit[key]
    if vote_count[source_hash][target_hash] >= (total * 2) / 3:
        justified = get_field(receiver, is_in_attack_chain, 'justified')
        justified.append(target_hash)
        update_field(receiver, is_in_attack_chain, 'justified', justified)
        highest_justified_checkpoint = get_field(
            receiver, is_in_attack_chain, 'highest_justified_checkpoint')
        highest_justified_epoch = get_block_field(highest_justified_checkpoint,
                                                  'epoch')
        if target_epoch > highest_justified_epoch:
            highest_justified_checkpoint = target_hash
            update_field(receiver, is_in_attack_chain,
                         'highest_justified_checkpoint', target_hash)
        if target_epoch - source_epoch == 1:
            finalized = get_field(receiver, is_in_attack_chain, 'finalized')
            finalized.append(source_hash)
            update_field(receiver, is_in_attack_chain, 'finalized', finalized)
    return True
Exemplo n.º 7
0
def accept_block(receiver, hash, N):
    sql_get_block_info = "select pre_hash, is_in_attack_chain, height from "\
      + "block where hash = '" + str(hash) +"';"
    db = pymysql.connect("localhost", "root", "root", "attack_casper")
    cursor = db.cursor()

    cursor.execute(sql_get_block_info)
    res_info = cursor.fetchall()
    db.commit()
    cursor.close()
    db.close()

    pre_hash = int(res_info[0][0])
    is_in_attack_chain = res_info[0][1]
    height = res_info[0][2]

    processed = get_field(receiver, is_in_attack_chain, 'processed')
    dep = get_field(receiver, is_in_attack_chain, 'dependencies')

    if pre_hash not in processed:
        if pre_hash not in dep.keys():
            dep[pre_hash] = [[], []]  #依赖分为两种,一种是区块,一种是vote,第一个list记录
        dep[pre_hash][0].append(int(hash))
        update_field(receiver, is_in_attack_chain, 'dependencies', dep)
        return

    print(f"miner %d accept the block of hash {hash}" % receiver)

    processed = processed + (int(hash), )
    #pdb.set_trace()
    update_field(receiver, is_in_attack_chain, 'processed', processed)

    tail_membership = get_field(receiver, is_in_attack_chain,
                                'tail_membership')
    tails = get_field(receiver, is_in_attack_chain, 'tails')
    if height % EPOCH_SIZE == 0:
        tail_membership[int(hash)] = int(hash)
        tails[int(hash)] = int(hash)
        update_field(receiver, is_in_attack_chain, 'tail_membership',
                     tail_membership)
        update_field(receiver, is_in_attack_chain, 'tails', tails)
        if receiver in validator:
            maybe_vote_last_checkpoint(receiver, hash, is_in_attack_chain, N)
    else:

        tail_membership[int(hash)] = tail_membership[pre_hash]
        update_field(receiver, is_in_attack_chain, 'tail_membership',
                     tail_membership)
        sql_get_height = "select height from block where hash = '"\
         + str(tails[tail_membership[int(hash)]]) + "';"

        db = pymysql.connect("localhost", "root", "root", "attack_casper")
        cur = db.cursor()
        cur.execute(sql_get_height)
        tail_height = cur.fetchall()[0][0]
        db.commit()
        cur.close()
        db.close()
        if height > tail_height:
            tails[tail_membership[int(hash)]] = int(hash)

            update_field(receiver, is_in_attack_chain, 'tails', tails)

    check_head(receiver, hash, is_in_attack_chain)
    return True