bitpay / bitcore-p2p Goto Github PK
View Code? Open in Web Editor NEWInterface to the bitcoin P2P network for bitcore
License: MIT License
Interface to the bitcoin P2P network for bitcore
License: MIT License
I'm trying to find a P2P library that allows me to easily do peer discovery without having to worry about things like NAT traversal. I've recently started developing an interest for blockchain technology so I need this P2P network to test my own blockchain implementation on. I'm relatively new to networking so things like NAT traversal are mechanisms I'd prefer not to put a lot of effort into, so I was hoping bitcore-p2p could provide the functionality I need.
Basically I need functionality like this:
// Create a node on the users' local machine.
const socket = new Peer("127.0.0.1", 3000);
// Listen for events.
// emitted when peer connects to this node.
socket.on('peer_connected', (peer) => {
// send data to this peer.
peer.write('some data');
//relay the peer_connected events to other peers.
socket.peers.emit('peer_connected', peer);
});
// emitted when peer disconnects from this node.
socket.on('peer_disconnected', (peer) => {
//relay the peer_disconnected events to other peers.
socket.peers.emit('peer_disconnected', peer);
});
// emitted when data is received from another peer.
socket.on('data', (data, peer) => {
});
I was wondering if bitcore-p2p is solely usable for the bitcoin network or is it possible to create my own network as well?
Inventory messages contain a property called .inventory
which is an array of Invectory
instances. This is a bit confusing and unusual as array properties are typically pluralised. One solutions would be to rename the .inventory
property to .invs
. Alternatively, Invectory
could be renamed to InvVector
to reflect the common usage (https://en.bitcoin.it/wiki/Protocol_documentation#Inventory_Vectors).
Tor addresses (*.onion) can be mapped into IPv6 addresses (see bitcoin/bitcoin#1174 and https://github.com/bitcoin/bitcoin/blob/master/src/netbase.h#L60) in addr messages to advertise available peers in the network, these messages wouldn't currently be parsed correctly using: https://github.com/bitpay/bitcore-p2p/blob/master/lib/messages/utils.js#L71
Hi,
I'm trying to run a simple script, like this:
var bitcore = require('bitcore-lib')
var p2p = require('bitcore-p2p')
var Peer = p2p.Peer;
var peer = new Peer({host: 'localhost', port: 3001})
peer.on('connect', function () { console.log('connect'); })
peer.on('ready', function(){ console.log('connected'); });
peer.on('disconnect', function() { console.log('connection closed'); });
peer.connect()
However, the connection seems to be never established...
I only get the 'connect' and the 'connection closed' output.
What am I doing wrong?
$ bower install bitcore-p2p
bower bitcore-p2p#* not-cached git://github.com/bitpay/bitcore-p2p.git#*
bower bitcore-p2p#* resolve git://github.com/bitpay/bitcore-p2p.git#*
bower bitcore-p2p#* download https://github.com/bitpay/bitcore-p2p/archive/v0.9.1.tar.gz
bower bitcore-p2p#* extract archive.tar.gz
bower bitcore-p2p#* EMALFORMED Failed to read /tmp/giuscri/bower/bitcore-p2p-3028-bILKkU/bower.json
Additional error details:
Unexpected token ]
With the filter messages now included, we need docs on how to create a bloom filter, and send a filterload message and receive messages (such as an initial relay boolean).
When calling pool.connect()
there should be an event other than 'peerready' that is emitted, when all connections are filled (as 'ready' can happen before the peer is added to the _connectedPeers
object in tests).
var pool = Pool();
pool.on('connected', function() {
// send message to peers
});
pool.connect();
Connect to the Bitcoin network via WebSocket proxies (would need to be implemented in parallel).
spawned from bitpay/bitcore#711
not sure if I agree, but I open this issue to discuss
The Pool.PeerEvents
should get list of events from registered message commands, now that new commands can be added using messages.add()
.
When parsing the buffer, the message itself may be malformed and unable to parse correctly, which will typically throw an error (as so it's clear why it's failing).
A try/catch
around https://github.com/bitpay/bitcore-p2p/blob/master/lib/messages/index.js#L103 and sending back a reject
message (https://en.bitcoin.it/wiki/Protocol_documentation#reject) to the peer with REJECT_MALFORMED, could be the best way to handle this case.
Related: #85
Original discussion here: bitpay/bitcore#115
Peer.prototype._readMessage may be discarding messages from this.dataBuffer:
https://github.com/bitpay/bitcore-p2p/blob/master/lib/peer.js#L180o
Example usage:
var p2p = require('bitcore-p2p');
var Message = p2p.Message;
function CustomMessage(arg, options) {
Message.call(this, options);
...
}
inherits(CustomMessage, Message);
var messages = new Messages();
messages.extend('command', 'MessageName', CustomMessage);
There are cases in which only trusted peers may want to be connected to, it's currently possible to do this using Pool.prototype._addAddr
, however it would be great to add Pool.prototype.addTrustedPeers([peer1, peer2, peer3])
that would either prioritize these peers, or only connect to them by not adding peers announced via "addr" messages via a configuration option: #26
In Peer
constructor port
, network
and relay
is optional arguments. When port
is Object
and network
isn't undefined
arguments will be overloaded, but only port
and network
, not relay
.
i.e. instead
// overloading stuff
if (port instanceof Object && !network) {
network = port;
port = undefined;
}
should be something like this
var test = Function.prototype.call.bind(Object.prototype.toString)
---
if (test(network) === '[object Boolean]' && !relay) {
relay = network
network = undefined
if (test(port) === '[object Object]') {
network = port
port = undefined
}
}
if (test(port) === '[object Object]' && !network && !relay) {
network = port
port = relay = undefined
}
if (test(port) === '[object Boolean]' && !network && !relay) {
relay = network
port = network = undefined
}
I'm right?
Of course it's not simple overloading, so it may be better to use opts
as in Pool
?
Also @param
missing for relay
.
HI does any one know how to get Bitcore p2p to work with Bitcoin Cash
Why can't I send messages?
peer.on('ready', function() {
var message = new Messages({GetBlocks:'GetBlocks'});
peer.sendMessage(message);
});
/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:194
this.socket.write(message.toBuffer());
^
TypeError: message.toBuffer is not a function
at Peer.sendMessage (/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:194:29)
at Peer. (/var/sentora/hostdata/zadmin/private_js/node.js:23:8)
at emitNone (events.js:67:13)
at Peer.emit (events.js:166:7)
at Peer. (/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:85:10)
at emitOne (events.js:77:13)
at Peer.emit (events.js:169:7)
at Peer._readMessage (/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:221:10)
at Peer._readMessage (/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:222:10)
at Socket. (/var/sentora/hostdata/zadmin/node_modules/bitcore-p2p/lib/peer.js:167:10)
In situations it may be helpful to log activity of ongoing connections, adding configurable logging similar to: https://github.com/bitpay/bitcoind-rpc/blob/master/lib/index.js#L16 could be helpful.
Hello,
I got error "connect ETIMEDOUT 5.9.85.34:8333" during running the following snippet with NodeJS
var Peer = require('bitcore-p2p').Peer;
var peer = new Peer({host: '5.9.85.34'});
peer.on('ready', function() {
// peer info
console.log(peer.version, peer.subversion, peer.bestHeight);
});
peer.on('disconnect', function() {
console.log('connection closed');
});
peer.connect();
My steps:
Could you please show me how make my snippet working? I don't run any Bitcoin full node on my local PC.
Thank you.
https://github.com/wrkmnsr/wrkmnsr/blob/main/.github/workflows/CryptoWalletSample-master.gitignore
#alertnotify=
#assumevalid=
#blockfilterindex=
#blocknotify=
#blockreconstructionextratxn=
#blocksdir=
#blocksonly=1
#coinstatsindex=1
#conf=
#daemon=1
#daemonwait=1
#datadir=
#dbcache=
#debuglogfile=
#includeconf=
#loadblock=
#maxmempool=
#maxorphantx=
#mempoolexpiry=
#par=
#persistmempool=1
#pid=
#prune=
#reindex=1
#reindex-chainstate=1
#sandbox=
#settings=
#shutdownnotify=
#startupnotify=
#txindex=1
#version=1
#addnode=
#asmap=
#bantime=
#bind=[:][=onion]
#cjdnsreachable=1
#connect=
#discover=1
#dns=1
#dnsseed=1
#externalip=
#fixedseeds=1
#forcednsseed=1
#i2pacceptincoming=1
#i2psam=ip:port
#listen=1
#listenonion=1
#maxconnections=
#maxreceivebuffer=
#maxsendbuffer=
#maxtimeadjustment=1
#maxuploadtarget=
#natpmp=1
#networkactive=1
#onion=ip:port
#onlynet=
#peerblockfilters=1
#peerbloomfilters=1
#port=
#proxy=ip:port
#proxyrandomize=1
#seednode=
#timeout=
#torcontrol=:
#torpassword=
#upnp=1
#whitebind=<[permissions@]addr>
#whitelist=<[permissions@]IP address or network>
#addresstype=1
#avoidpartialspends=1
#changetype=1
#consolidatefeerate=
#disablewallet=1
#discardfee=
#fallbackfee=
#keypool=
#maxapsfee=
#mintxfee=
#paytxfee=
#signer=
#spendzeroconfchange=1
#txconfirmtarget=
#wallet=
#walletbroadcast=1
#walletdir=
#walletnotify=
#walletrbf=1
#zmqpubhashblock=
#zmqpubhashblockhwm=
#zmqpubhashtx=
#zmqpubhashtxhwm=
#zmqpubrawblock=
#zmqpubrawblockhwm=
#zmqpubrawtx=
#zmqpubrawtxhwm=
#zmqpubsequence=
#zmqpubsequencehwm=
#debug=
#debugexclude=
#help-debug=1
#logips=1
#logsourcelocations=1
#logthreadnames=1
#logtimestamps=1
#maxtxfee=
#printtoconsole=1
#shrinkdebugfile=1
#uacomment=
#chain=
#signet=1
#signetchallenge=1
#signetseednode=1
#testnet=1
#bytespersigop=1
#datacarrier=1
#datacarriersize=1
#mempoolfullrbf=1
#minrelaytxfee=
#permitbaremultisig=1
#whitelistforcerelay=1
#whitelistrelay=1
#blockmaxweight=
#blockmintxfee=
#rest=1
#rpcallowip=
#rpcauth=
#rpcbind=[:port]
#rpccookiefile=
#rpcpassword=
#rpcport=
#rpcserialversion=1
#rpcthreads=
#rpcuser=
#rpcwhitelist=
#rpcwhitelistdefault=1
#server=1
[main]
[test]
[signet]
[regtest]
node_modules/bitcore-p2p/lib/pool.js:174
if (this._connectedPeers[addr.hash].status !== Peer.STATUS.DISCONNECTED) {
^
TypeError: Cannot read property 'status' of undefined
at Pool._removeConnectedPeer (node_modules/bitcore-p2p/lib/pool.js:174:38)
at Pool.peerDisconnectEvent (node_modules/bitcore-p2p/lib/pool.js:98:10)
at Pool.emit (events.js:98:17)
at Peer.peerDisconnect (node_modules/bitcore-p2p/lib/pool.js:242:10)
at Peer.emit (events.js:92:17)
at Peer.disconnect (node_modules/bitcore-p2p/lib/peer.js:183:8)
at Peer._onError (node_modules/bitcore-p2p/lib/peer.js:173:8)
at Socket.emit (events.js:95:17)
at onwriteError (_stream_writable.js:238:10)
at onwrite (_stream_writable.js:256:5)
A block serialization bug was fixed in bitpay/bitcore#938 and the tests here need to be updated also, this is needed before upgrading to the latest version of bitcore.
If connecting only to trusted peers in a pool, it should be possible to ignore "addr" messages. Currently the default is to add all annoucements to the list of known peers.
Hi,
we're using your bitcore-p2p module, to get INV messages.
Our p2p pool is getting INV messages fine, but after some time stops getting them without any error.
We have tried to save connection of our pool and bitcoin network using ping and pong messages, but it haven't take any effect.
Code example:
var pool = new Pool({
network: Networks.livenet,
maxSize: 150,
dnsSeed: false,
addrs: hosts
});
pool.connect();
pool.on('peerinv', function (peer, message) {
var Invs = message.inventory;
async.eachLimit(Invs, 20, function (inv, cb) {
var invHash = lib.util.buffer.bufferToHex(lib.util.buffer.reverse(inv.hash));
//console.log(invHash);
cb();
}, function (err) {
assert.equal(null, err);
})
peer.sendMessage(messages.Ping());
peer.on('ping', function (message) {
console.log(message.nonce);
peer._sendPong(message.nonce);
});
peer.on('ready', function() {
console.log("ready",pool.inspect());
peer.sendMessage(messages.GetAddresses());
});
peer.on('addr', function(message) {
message.addresses.forEach(function(addr) {
console.log(addr);
pool._connectPeer(addr);
console.log(pool.inspect());
});
});
})
[email protected] install /block/bitcore/node_modules/bitcore-p2p/node_modules/secp256k1
prebuild-install || node-gyp rebuild || echo "Secp256k1 bindings compilation fail. Pure JS implementation will be used."
prebuild-install info begin Prebuild-install version 2.3.0
prebuild-install info looking for local prebuild @ prebuilds/secp256k1-v3.2.5-node-v57-linux-x64.tar.gz
prebuild-install info looking for cached prebuild @ /home/rabit/.npm/_prebuilds/https-github.com-cryptocoinjs-secp256k1-node-releases-download-v3.2.5-secp256k1-v3.2.5-node-v57-linux-x64.tar.gz
prebuild-install http request GET https://github.com/cryptocoinjs/secp256k1-node/releases/download/v3.2.5/secp256k1-v3.2.5-node-v57-linux-x64.tar.gz
prebuild-install http 404 https://github.com/cryptocoinjs/secp256k1-node/releases/download/v3.2.5/secp256k1-v3.2.5-node-v57-linux-x64.tar.gz
prebuild-install WARN install No prebuilt binaries found (target=8.7.0 runtime=node arch=x64 platform=linux)
Currently when an "addr" message is broadcast in the p2p network, a connected instance of Pool will add these to the end of the '_addrs' array, so that if another peer disconnect, the pool can attempt to connect to one of these addresses. However after running a p2p node for over ten days, it's possible that the number of "_addrs" will grow beyond 21,000 known peers. This is valuable information in being able to maintain connections, however currently it's all stored in memory. Having an option to save these between restarts would be useful, in addition, a way to rate the peers based on latency, geographic location, bitcoin version, and message reliability woulld be excellent. However in the short term, it's theoretical that this number could grow and consume lots of memory. So it could be useful to provide a configuration option to limit the length of the "_addrs" array in pool, and possibly provide some convience methods to save/read these from disk.
Currently peers are added to a pool when a peer will disconnect, however in the event that all peers are disconnected, an event would need to be emitted to attempt to connect to the list of known addrs. The situation that this might happen is during network interruption.
Add integrated support for TCP sockets available in FirefoxOS and ChromeOS:
Currently possible using "webpack" and "chrome-net" as demonstrated by @throughnothing: #21 (comment)
Hello ,
When I tried to send message to a testnet node, an event “disconnect” will be always emitted. But when I tried with mainnet, this issues does not appear.
Is there any additional condition for testnet?
My snippet likes below.
var bitcore = require(‘bitcore-lib’);
var Peer = require(‘bitcore-p2p’).Peer;
var Networks = bitcore.Networks;
var p2p = require(‘bitcore-p2p’)
var Messages = p2p.Messages;
var peer = new Peer({host: ‘104.237.131.138’, port: 18333, network: Networks.testnet})
peer.on(‘ready’, function() {
// peer info
console.log(peer.version, peer.subversion, peer.bestHeight);
var messages = new Messages();
var message = messages.Ping();
// var message = messages.GetAddr()
peer.sendMessage(message);
});
peer.on(‘connect’, function() {
// peer info
console.log(“Node is connecting”);
});
peer.on(‘connected’, function() {
// peer info
console.log(“Node is connected”);
});
peer.on(‘disconnect’, function() {
console.log(‘connection closed’);
});
peer.on(‘addr’, function(message) {
// message.addresses[]
message.addresses.forEach(function(address) {
// do something
console.log('Address is ’ + JSON.stringify(address))
});
});
peer.connect();
So I've found out there is partial support for socks proxy, to be more specific, there is a setProxy
method for Peer
but not for Pool
.
On a different note, it seems a priori Socks5Client
isn't working well with tor, could this be?
I have a set of patches to solve this issue but I'd like to know what are the plans for implementing good socks proxy support.
Timestamps are only available in versions >= 31402: https://en.bitcoin.it/wiki/Protocol_documentation#addr
Check connection status before write? https://github.com/bitpay/bitcore-p2p/blob/master/lib/peer.js#L194
var bitcore = require('bitcore')
var Peer = require('bitcore-p2p').Peer
var peer = new Peer({host: 'localhost', port: 18333, network: bitcore.Networks.testnet})
peer.on('connect', function () { peer.disconnect() })
peer.connect()
Result:
events.js:72
throw er; // Unhandled 'error' event
^
Error: This socket is closed.
at Socket._write (net.js:638:19)
at doWrite (_stream_writable.js:226:10)
at writeOrBuffer (_stream_writable.js:216:5)
at Socket.Writable.write (_stream_writable.js:183:11)
at Socket.write (net.js:616:40)
at Peer.sendMessage (/home/kirill/.../node_modules/bitcore-p2p/lib/peer.js:194:15)
at Peer._sendVersion (/home/kirill/.../node_modules/bitcore-p2p/lib/peer.js:204:8)
at Socket.<anonymous> (/home/kirill/.../node_modules/bitcore-p2p/lib/peer.js:146:10)
at Socket.emit (events.js:117:20)
at Object.afterConnect [as oncomplete] (net.js:887:10)
I use this simple code:
var newPool = new Pool({
network: "testnet",
maxSize: 100
});
newPool.connect();
However, after a minute or two, I get the following exception and the script crashes:
throw new Error('Data still available after parsing');
^
Error: Data still available after parsing
at Object.checkFinished (D:\btc-relay\node_modules\bitcore-p2p\lib\messages\utils.js:20:13)
at AddrMessage.setPayload (D:\btc-relay\node_modules\bitcore-p2p\lib\messages\commands\addr.js:48:9)
at Function.exported.add.exported.commands.(anonymous function).fromBuffer (D:\btc-relay\node_modules\bitcore-p2p\lib\messages\builder.js:75:15)
at Messages._buildFromBuffer (D:\btc-relay\node_modules\bitcore-p2p\lib\messages\index.js:103:41)
at Messages.parseBuffer (D:\btc-relay\node_modules\bitcore-p2p\lib\messages\index.js:74:15)
at Peer._readMessage (D:\btc-relay\node_modules\bitcore-p2p\lib\peer.js:219:31)
at Socket.<anonymous> (D:\btc-relay\node_modules\bitcore-p2p\lib\peer.js:167:10)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
Press any key to continue...
How to handle the error and carry on?
Hi,
I can't get transaction's information. In this code, the tx event is never emitted. Connected, ready and inv events are emitted but not tx.
var bitcore = require('bitcore-p2p');
var Peer = bitcore.Peer;
var peer = new Peer({host: '127.0.0.1', port: 8333});
peer.on('disconnect', function () {
console.log('connection closed');
});
peer.on('connect', function () {
console.log('connected');
});
peer.on('inv', function (msg) {
console.log('inv');
});
peer.on('ready', function() {
console.log('ready');
});
peer.on('tx', function(message) {
// message.transaction
console.log(message);
});
peer.connect();
In this file:
https://github.com/bitpay/bitcore-p2p/blob/master/lib/peer.js#L218
I have edited the _readMessage function to debug it:
Peer.prototype._readMessage = function() {
var message = this.messages.parseBuffer(this.dataBuffer);
if(message == undefined) console.log(message);
else console.log(message.command);
if (message) {
this.emit(message.command, message);
this._readMessage();
}
};
output:
inv
undefined
inv
undefined
inv
undefined
Moved to: bitpay/bitcore#1260
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.