Ejemplo n.º 1
0
def PING(self, source, msg):
    #logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    #nodeState[self][MEMB_MSGS_RECEIVED] += 1

    addEntryDB(self, source)

    sim.send(PONG, source, self, PONG_MSG)
Ejemplo n.º 2
0
def BLOCK(self, source, msg, block):
    logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    nodeState[self][DISS_MSGS_RECEIVED] += 1

    if block.getHash() not in REPEATED_BLOCK_COUNT[self]:
        REPEATED_BLOCK_COUNT[self].update({block.getHash(): 1})
    else:
        REPEATED_BLOCK_COUNT[self][block.getHash()] += 1

    if block.getHash() not in nodeState[self][KNOWN_BLOCKS]:
        # Remove from missing/asked
        a = (ANN_BLOCK, block.getHash())
        if a in nodeState[self][MISSING_ANN]:
            del nodeState[self][MISSING_ANN][a]
            if a in nodeState[self][ASKED_ANN]:
                del nodeState[self][ASKED_ANN][a]

        nodeState[self][KNOWN_BLOCKS][block.getHash()] = block
        nodeState[self][QUEUED_BLOCKS].append(block)

        eagerList = nodeState[self][BTREE][EAGER].copy()
        if source in eagerList:
            eagerList.remove(source)
        else:
            graftBTree(self, source)
        for n in eagerList:
            sim.send(BLOCK, n, self, BLOCK_MSG, block)
            nodeState[self][DISS_MSGS_SENT] += 1
        nodeState[self][QUEUED_ANN].append((ANN_BLOCK, block.getHash()))
    else:
        pruneBTree(self, source)
        sim.send(PRUNE, source, self, PRUNE_MSG)
        nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 3
0
def TXS(self, source, msg, tx):
    #logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    nodeState[self][DISS_MSGS_RECEIVED] += 1

    if tx.getHash() not in nodeState[self][KNOWN_TXS]:
        # Remove from missing/asked
        a = (ANN_TX, tx.getHash())
        if a in nodeState[self][MISSING_ANN]:
            del nodeState[self][MISSING_ANN][a]
            if a in nodeState[self][ASKED_ANN]:
                del nodeState[self][ASKED_ANN][a]

        nodeState[self][KNOWN_TXS][tx.getHash()] = tx
        nodeState[self][QUEUED_TXS].append(tx)

        eagerList = nodeState[self][BTREE][EAGER].copy()
        if source in eagerList:
            eagerList.remove(source)
        else:
            graftBTree(self, source)
        for n in eagerList:
            sim.send(TXS, n, self, TXS_MSG, tx)
            nodeState[self][DISS_MSGS_SENT] += 1
        nodeState[self][QUEUED_ANN].append((ANN_TX, tx.getHash()))
    elif tx.getNumber() % 100 == 0:
        pruneBTree(self, source)
        sim.send(PRUNE, source, self, PRUNE_MSG)
        nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 4
0
def PING(self, source, msg):
	#logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	#nodeState[self][MEMB_MSGS_RECEIVED] += 1
	addEntryDb(self, source)
	updateEntryPingDb(self, source, nodeState[self][CURRENT_TIME])

	sim.send(PONG, source, self, PONG_MSG)
Ejemplo n.º 5
0
def NEWBLOCK(self, source, msg, block):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	if block.getHash() not in REPEATED_BLOCK_COUNT[self]:
		REPEATED_BLOCK_COUNT[self].update({block.getHash():1})
	else:
		REPEATED_BLOCK_COUNT[self][block.getHash()] += 1

	if block.getHash() in nodeState[self][KNOWN_BLOCKS]:
		propagate = False
	else:
		propagate = True
		nodeState[self][QUEUED_BLOCKS].append(block)
		nodeState[self][KNOWN_BLOCKS][block.getHash()] = block

	#propagation
	if propagate:
		neighbors = getNeighbors(self)
		if source in neighbors:
			neighbors.remove(source)
		rootSample = random.sample(neighbors, int(math.sqrt(len(neighbors))))
		for n in neighbors:
			if n in rootSample:
				sim.send(NEWBLOCK, n, self, NEWBLOCK_MSG, block)
			else:
				sim.send(NEWBLOCKHASHES, n, self, NEWBLOCKHASHES_MSG, [block.getHash()])
			nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 6
0
def TRANSACTIONS(self, source, msg, txs):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	if verifyTxs(self, txs):
		for t in txs:
			nodeState[self][KNOWN_TXS][t.getHash()] = t
			if t not in nodeState[self][QUEUED_TXS]:
				nodeState[self][QUEUED_TXS].append(t)
			if not nodeState[self][ANN_TXS].get(t.getHash()):
				nodeState[self][ANN_TXS][t.getHash()] = []
			if source not in nodeState[self][ANN_TXS][t.getHash()]:
				nodeState[self][ANN_TXS][t.getHash()].append(source)

		# Propagation
		for n in getNeighbors(self):
			tmp = []
			for t in txs:
				if n not in nodeState[self][ANN_TXS][t.getHash()]:
					nodeState[self][ANN_TXS][t.getHash()].append(n)
					tmp.append(t)
	
			if tmp:
				sim.send(TRANSACTIONS, n, self, TRANSACTIONS_MSG, tmp)
				nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 7
0
def GETDATA(self, source, msg, type, hashes, sync=False):
    logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    nodeState[self][DISS_MSGS_RECEIVED] += 1

    if type == ANN_BLOCK:
        if sync:
            retrieve = []
            b_index = nodeState[self][BLOCKCHAIN].index(
                nodeState[self][BLOCKCHAIN_HASHES].get(hashes[0]))
            for i in range(0, b_index):
                retrieve.append(nodeState[self][BLOCKCHAIN][b_index -
                                                            i].getHeader())
        else:
            retrieve = list(hashes)
        for h in retrieve:
            if h in nodeState[self][KNOWN_BLOCKS]:
                sim.send(BLOCK, source, self, BLOCK_MSG,
                         nodeState[self][KNOWN_BLOCKS][h])
                nodeState[self][DISS_MSGS_SENT] += 1
    elif type == ANN_TX:
        for h in hashes:
            if h in nodeState[self][KNOWN_TXS]:
                sim.send(TXS, source, self, TXS_MSG,
                         nodeState[self][KNOWN_TXS][h])
                nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 8
0
def GETADDR(self, source, msg):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][MEMB_MSGS_RECEIVED] += 1
	if source not in nodeState[self][DB]:
		nodeState[self][DB].append(source)

	sim.send(ADDR, source, self, ADDR_MSG, createSample(self))
	nodeState[self][MEMB_MSGS_SENT] += 1
Ejemplo n.º 9
0
def lookup(self, target):
	queries = 0
	for n in lookupNeighbors(self, target):
		if queries >= alpha:
			break
		sim.send(FINDNODE, n, self, FINDNODE_MSG, target)
		nodeState[self][MEMB_MSGS_SENT] += 1
		queries += 1
Ejemplo n.º 10
0
def PING(myself, source, nonce):
    global nodeState

    check_if_connected(myself, source)

    if should_log(myself):
        nodeState[myself][MSGS][PING_MSG] += 1

    sim.send(PONG, source, myself, nonce)
Ejemplo n.º 11
0
def HEADERS(self, source, msg, headers):
	# The headers message sends block headers to a node which previously requested certain headers with a getheaders message.
	# A headers message can be empty.
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	if verifyHeaders(self, headers):
		sim.send(GETBLOCKS, source, self, GETBLOCKS_MSG, headers)
		nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 12
0
def FINDNODE(self, source, msg):
    logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    nodeState[self][MEMB_MSGS_RECEIVED] += 1

    addEntryDB(self, source)
    addEntryNeighbs(self, source)

    sim.send(NEIGHBORS, source, self, NEIGHBORS_MSG, lookupNeighbors(self))
    nodeState[self][MEMB_MSGS_SENT] += 1
Ejemplo n.º 13
0
def NEWBLOCKHASHES(self, source, msg, hashes):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	tmp = []
	for h in hashes:
		if h not in nodeState[self][KNOWN_BLOCKS].keys():
			tmp.append(h)
	if tmp:
		sim.send(GETBLOCKBODIES, source, self, GETBLOCKBODIES_MSG, tmp)
		nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 14
0
def VERSION(self, source, msg):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][MEMB_MSGS_RECEIVED] += 1

	if self == source:
		return

	if source not in nodeState[self][DB]:
		nodeState[self][DB].append(source)

	sim.send(VERACK, source, self, VERACK_MSG)
	nodeState[self][MEMB_MSGS_SENT] += 1
Ejemplo n.º 15
0
def send_ping(myself, target, pto):
    global ping_nonce

    ping_send = False
    if pto[PING_STRC][PING_NONCE_SENT] == 0 and pto[PING_STRC][
            PING_TIME_START] + PING_INTERVAL < nodeState[myself][CURRENT_TIME]:
        ping_send = True
    if ping_send:
        pto[PING_STRC][PING_TIME_START] = nodeState[myself][CURRENT_TIME]
        pto[PING_STRC][PING_NONCE_SENT] = ping_nonce
        ping_nonce += 1
        sim.send(PING, target, myself, pto[PING_STRC][PING_NONCE_SENT])
Ejemplo n.º 16
0
def BLOCKHEADERS(self, source, msg, headers):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	hashes = []
	if verifyHeaders(self, headers):
		for b in nodeState[self][BLOCKCHAIN]:
			if b.getHeader() in headers:
				hashes.append(b.getHash())   

	if hashes:
		sim.send(GETBLOCKBODIES, source, self, GETBLOCKBODIES_MSG, hashes)
		nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 17
0
def send_addr(myself, target, pto):
    if pto[ADDR_STRC][NEXT_ADDR_SEND] < nodeState[myself][CURRENT_TIME]:
        pto[ADDR_STRC][NEXT_ADDR_SEND] = poisson_next_send(
            nodeState[myself][CURRENT_TIME], AVG_ADDRESS_BROADCAST_INTERVAL)
        addr_to_send = []
        for addr in pto[ADDR_STRC][ADDR_TO_SEND]:
            if not has_addr(pto, addr):
                add_addr(pto, addr)
                addr_to_send.append(addr)
                if len(addr_to_send) >= MAX_ADDR_MSG_SIZE:
                    sim.send(ADDR, target, myself, addr_to_send)
        pto[ADDR_STRC][ADDR_TO_SEND] = []
        if addr_to_send:
            sim.send(ADDR, target, myself, addr_to_send)
Ejemplo n.º 18
0
def lookupBack(self, target, stopMatch):
	# recursive lookup
	# TODO move out of threads
	global neighborsQueue
	global nodeState

	asked = {}
	seen = []
	result = []
	pendingQueries = 0

	result = lookupNeighbors(self, target)
	while True:
		for n in result:
			if pendingQueries >= alpha:
				break
			if n not in asked.keys():
				asked[n] = time.time()
				pendingQueries += 1
				addEntryDb(self, n)
				addEntryBucket(self, n)
				sim.send(FINDNODE, n, self, FINDNODE_MSG, target)
				nodeState[self][MEMB_MSGS_SENT] += 1

		if pendingQueries == 0:
			break

		for queried in asked.keys():
			if asked[queried] == 0 or queried not in neighborsQueue:
				continue

			response = neighborsQueue[queried]
			for n in response:
				if n not in seen:
					seen.append(n)
					result.append(n)
					if stopMatch and n == target:
						return result
			asked[queried] = 0
			pendingQueries -= 1

		for n in asked.keys():
			if asked[n] == 0:
				continue

			t = (time.time() - asked[n]) * 1000
			if t > lookupTimeout:
				pendingQueries = 0

	return result
Ejemplo n.º 19
0
def GETBLOCKS(self, source, msg, headers):
	# The getblocks message requests an inv message that provides block header hashes starting from a particular point in the block chain.
	# It allows a peer which has been disconnected or started for the first time to get the data it needs to request the blocks it hasn’t seen.
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	tmp = []
	for b in nodeState[self][BLOCKCHAIN]:
		if b.getHeader() in headers:
			tmp.append([MSG_BLOCK, b.getHash()])
	
	if len(tmp) > 0:
		sim.send(INV, source, self, INV_MSG, tmp)
		nodeState[self][DISS_MSGS_SENT] += 1
	del tmp
Ejemplo n.º 20
0
def ADDR(self, source, msg, addrs):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][MEMB_MSGS_RECEIVED] += 1

	temp = []
	for n in addrs:
		if n != self and n not in nodeState[self][CONNS]:
			temp.append(n)
			nodeState[self][RELAY_NODES].append(n)

	for n in temp:
		addConn(self, n)
		sim.send(VERSION, n, self, VERSION_MSG)
		nodeState[self][MEMB_MSGS_SENT] += 1
	del temp
Ejemplo n.º 21
0
def GETBLOCKBODIES(self, source, msg, hashes):
	# Send full block
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	blocks = []
	for h in hashes:
		if h in nodeState[self][KNOWN_BLOCKS].keys():
			blocks.append(nodeState[self][KNOWN_BLOCKS].get(h))
		elif h in nodeState[self][BLOCKCHAIN_HASHES].keys():
			blocks.append(nodeState[self][BLOCKCHAIN_HASHES].get(h))

	if blocks:
		sim.send(BLOCKBODIES, source, self, BLOCKBODIES_MSG, blocks)
		nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 22
0
def join(self):
	if self not in NETWORK_NODES:
		NETWORK_NODES.append(self)

	if len(NETWORK_NODES) < 2:
		return

	destNodes = random.choices(NETWORK_NODES, k=min(len(NETWORK_NODES)-1, 5))
	while self in destNodes:
		destNodes = random.choices(NETWORK_NODES, k=min(len(NETWORK_NODES)-1, 5))
	
	for destNode in destNodes:
		addConn(self, destNode)
		sim.send(VERSION, destNode, self, VERSION_MSG)
		sim.send(GETADDR, destNode, self, GETADDR_MSG)
		nodeState[self][MEMB_MSGS_SENT] += 2
Ejemplo n.º 23
0
def STATUS(self, source, msg, bestHash, blockNum):
    logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
    nodeState[self][DISS_MSGS_RECEIVED] += 1

    if source not in nodeState[self][SENT_STATUS]:
        sim.send(STATUS, source, self, STATUS_MSG,
                 nodeState[self][BLOCKCHAIN][-1].getHash(),
                 nodeState[self][BLOCKCHAIN][-1].getNumber())
        nodeState[self][DISS_MSGS_SENT] += 1
    else:
        nodeState[self][SENT_STATUS].remove(source)

    # Request Headers
    if nodeState[self][BLOCKCHAIN][-1].getNumber() < blockNum:
        sim.send(GETDATA, source, self, ANN_BLOCK, GETDATA_MSG, [bestHash],
                 True)
        nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 24
0
def join(self):
	if self not in NETWORK_NODES:
		NETWORK_NODES.append(self)
	if len(NETWORK_NODES) < 2:
		return

	destNodes = random.choices(NETWORK_NODES, k=min(len(NETWORK_NODES)-1, 5))
	while self in destNodes:
		destNodes = random.choices(NETWORK_NODES, k=min(len(NETWORK_NODES)-1, 5))

	for destNode in destNodes:
		addEntryDb(self, destNode)
		addEntryBucket(self, destNode)
		sim.send(FINDNODE, destNode, self, FINDNODE_MSG, destNode)
		nodeState[self][SENT_STATUS].append(destNode)
		sim.send(STATUS, destNode, self, STATUS_MSG, nodeState[self][BLOCKCHAIN][-1].getHash(), nodeState[self][BLOCKCHAIN][-1].getNumber())
		nodeState[self][DISS_MSGS_SENT] += 1
		nodeState[self][MEMB_MSGS_SENT] += 1
Ejemplo n.º 25
0
def GETDATA(self, source, msg, inv):
	# The getdata message requests one or more data objects from another node.
	# The objects are requested by an inventory, which the requesting node typically received previously by way of an inv message.
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	for i in inv:
		if i[0] == MSG_TX:
			t = nodeState[self][KNOWN_TXS].get(i[1])
			rmInvConn(self, source, MSG_TX, t.getHash())
			sim.send(TX, source, self, TX_MSG, t)
			del t
			nodeState[self][DISS_MSGS_SENT] += 1
		elif i[0] == MSG_BLOCK:
			b = nodeState[self][KNOWN_BLOCKS].get(i[1])
			if b is None:
				continue
			rmInvConn(self, source, MSG_BLOCK, b.getHash())
			sim.send(BLOCK, source, self, BLOCK_MSG, b)
			del b
			nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 26
0
def INV(self, source, msg, inv):
	# The inv message (inventory message) transmits one or more inventories of objects known to the transmitting peer.
	# It can be sent unsolicited to announce new transactions or blocks, or it can be sent in reply to a getblocks message or mempool message.
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1
	if source not in nodeState[self][DB]:
		nodeState[self][DB].append(source)

	tmp = []
	for i in inv:
		if i[0] == MSG_TX:
			if i[1] not in nodeState[self][KNOWN_TXS]:
				tmp.append(i)
		elif i[0] == MSG_BLOCK:
			if i[1] not in nodeState[self][KNOWN_BLOCKS]:
				tmp.append(i)
	if len(tmp) == 0:
		return
	sim.send(GETDATA, source, self, GETDATA_MSG, tmp)
	del tmp
	nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 27
0
def VERSION(myself, source):
    global nodeState

    if should_log(myself):
        nodeState[myself][MSGS][VERSION_MSG] += 1

    # Node connects to itself case, there's a condition in the Bitcoin code for this
    if myself == source:
        return

    if source not in nodeState[myself][NODE_NEIGHBOURHOOD]:
        add_new_addr(myself, source, source, 0)
        open_network_connection(myself, source, False)

    pto = nodeState[myself][NODE_NEIGHBOURHOOD][source]

    if pto[F_INBOUND]:
        sim.send(VERSION, source, myself)

    sim.send(VERACK, source, myself)

    if not pto[F_INBOUND]:
        addr = get_addr(myself)
        push_address(pto, addr)

        if len(nodeState[myself][RANDOM]) < 1000:
            sim.send(GETADDR, source, myself)
            pto[ADDR_STRC][F_GET_ADDR] = True

        mark_address_as_good(myself, source, True,
                             nodeState[myself][CURRENT_TIME])

    # TODO implement feeler

    return True
Ejemplo n.º 28
0
def GETBLOCKHEADERS(self, source, msg, hash, reverse):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	headers = []
	b_index = nodeState[self][BLOCKCHAIN].index(nodeState[self][BLOCKCHAIN_HASHES].get(hash))
	min_range = 0

	if reverse == 0:
		min_range = len(nodeState[self][BLOCKCHAIN]) - b_index
	elif reverse == 1:
		min_range = b_index

	for i in range(0, min(maxBlockHeaders, min_range)):
		if reverse == 0:
			headers.append(nodeState[self][BLOCKCHAIN][b_index + i].getHeader())
		elif reverse == 1:
			headers.append(nodeState[self][BLOCKCHAIN][b_index - i].getHeader())

	if headers:
		sim.send(BLOCKHEADERS, source, self, BLOCKHEADERS_MSG, headers)
		nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 29
0
def GETHEADERS(self, source, msg, start, end):
	# The getheaders message requests a headers message that provides block headers starting from a particular point in the block chain.
	# It allows a peer which has been disconnected or started for the first time to get the headers it hasn’t seen yet.
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	tmp = []
	started = False
	for b in nodeState[self][BLOCKCHAIN]:
		if b.getHash() == end:
			tmp.append(b.getHeader())
			break
		if started:
			tmp.append(b.getHeader())
		elif not started and b.getHash() == start:
			started = True
		else:
			continue

	sim.send(HEADERS, source, self, HEADERS_MSG, tmp)
	del tmp
	nodeState[self][DISS_MSGS_SENT] += 1
Ejemplo n.º 30
0
def STATUS(self, source, msg, bestHash, blockNumber):
	logger.info("Node: {} Received: {} From: {}".format(self, msg, source))
	nodeState[self][DISS_MSGS_RECEIVED] += 1

	addEntryDb(self, source)

	if source not in nodeState[self][SENT_STATUS]:
		sim.send(STATUS, source, self, STATUS_MSG, nodeState[self][BLOCKCHAIN][-1].getHash(), nodeState[self][BLOCKCHAIN][-1].getNumber())
		nodeState[self][DISS_MSGS_SENT] += 1
	else:
		nodeState[self][SENT_STATUS].remove(source)

	# Send Transactions
	sim.send(TRANSACTIONS, source, self, TRANSACTIONS_MSG, nodeState[self][QUEUED_TXS])
	nodeState[self][DISS_MSGS_SENT] += 1

	# Request Headers
	if nodeState[self][BLOCKCHAIN][-1].getNumber() < blockNumber:
		sim.send(GETBLOCKHEADERS, source, self, GETBLOCKHEADERS_MSG, bestHash, 1)
		nodeState[self][DISS_MSGS_SENT] += 1