• Forum has been upgraded, all links, images, etc are as they were. Please see Official Announcements for more information

How to receive InstantX transaction?

needbmw

New member
As far as I know -walletnotify option runs user script when the daemon sees new transaction with one confirmation.
What is right way to receive InstantX transactions?
 
As far as I know -walletnotify option runs user script when the daemon sees new transaction with one confirmation.
What is right way to receive InstantX transactions?

This is a great question, and I've been wondering the same thing myself. I know that it's not a simple process for an end-user. I think you would have to be a developer and access some lower-level features (recognizing MN tx locks?).

Would love to get some input from the core dev team on this, because this very thing will be huge for merchant adoption and enabling others to create merchant solutions.
 
I'll be open sourcing a python library I developed for the soda machine InstantX demo in Miami soon.

Today, it takes watching the p2p traffic and keeping track of the received messages.
There are plans to make this easier to use, but I'm hoping the library will act as a roadmap for developers and fill in the gap.

I'll post the technical details if anybody's interested, but the libraries readme will spell it out, once I've written it. ;)
 
I'll be open sourcing a python library I developed for the soda machine InstantX demo in Miami soon.

Today, it takes watching the p2p traffic and keeping track of the received messages.
There are plans to make this easier to use, but I'm hoping the library will act as a roadmap for developers and fill in the gap.

I'll post the technical details if anybody's interested, but the libraries readme will spell it out, once I've written it. ;)
Please do! Really looking forward to it.
 
I am working on a solution for this problem in Java, but will be modifying the SPV java base bitcoinj (currently called darkcoinj and is part of the Dash Wallet for Android) to include the necessary functions to detect and verify InstantX transactions.

This method requires translating from the Dash Core (C++) to bitcoinj (java) and comes with the limitations inherent to an SPV system (https://bitcoinj.github.io/#documentation).
 
So I'm looking through the dashvend code and trying to get my head wrapped around it. moocowmoo enlightned me on how nodes send inv (Inventory) messages to each other to communicate data, and some of those in Dash will be TX Lock message.

My question now is, is there a way to get these inv messages without reading them off the wire, like from the JSONRPC interface? It looks like dashvend uses JSONRPC — is that what's reading inv messages, or is it necessary to listen on the socket and read/parse the message as it comes across?
 
nmarley there are no rpc commands to interrogate all mempool message types, which is why I built dashvend as a pseudo-node instead of extending dashd. I wanted dashvend to work with a vanilla installation.

The jsonrpc interface is for sending refunds (and determining the refund address) using the local wallet.

Let me know if you have any other questions, I'm happy to help.
 
nmarley there are no rpc commands to interrogate all mempool message types, which is why I built dashvend as a pseudo-node instead of extending dashd. I wanted dashvend to work with a vanilla installation.

The jsonrpc interface is for sending refunds (and determining the refund address) using the local wallet.

Let me know if you have any other questions, I'm happy to help.
Awesome, thanks for all your help. It's been very useful in trying to understand how it all works together.

I'll probably print off the dashvend code and be looking over it the next few days to try and really grok it.
 
here's bit of code added to the processing overview, HTH.

During initialization, vend.py:
- configures dash_p2p.py to forward these message types (and 'tx's) to dash_ix.py
Code:
dashp2p.forward(vend.get_listeners())
get_listeners maps handlers for these message types:
     return ('tx', self.ix.recv_tx,
             'ix', self.ix.recv_ix,
             'txlvote', self.ix.recv_votes,
             'block', self.recv_block)
- configures dash_ix.py with the current payment address to monitor
Code:
self.ix.set_watch_address(self.current_address)

Messages forwarded to dash_ix.py:
- are checked against the current payment address
Code:
if self._find_payment(msg, txid, 'ix'):
- are stored in a temporary mempool
- are counted until a configurable threshold of locks is met
Code:
self._check_ix_threshold(txid)
(in two places: ix and lock handlers, they can come out of order)
 
Last edited by a moderator:
here's bit of code added to the processing overview, HTH.

During initialization, vend.py:
- configures dash_p2p.py to forward these message types (and 'tx's) to dash_ix.py
Code:
dashp2p.forward(vend.get_listeners())
get_listeners maps handlers for these message types:
     return ('tx', self.ix.recv_tx,
             'ix', self.ix.recv_ix,
             'txlvote', self.ix.recv_votes,
             'block', self.recv_block)
- configures dash_ix.py with the current payment address to monitor
Code:
self.ix.set_watch_address(self.current_address)

Messages forwarded to dash_ix.py:
- are checked against the current payment address
Code:
if self._find_payment(msg, txid, 'ix'):
- are stored in a temporary mempool
- are counted until a configurable threshold of locks is met
Code:
self._check_ix_threshold(txid)
(in two places: ix and lock handlers, they can come out of order)

Ok, so at a higher level, you're:

1. Somehow getting the INV messages for MSG_TXLOCK_VOTE (which I still don't know how you acquire the INV message), and
2. Aggregating the locks per transaction until you get a count which reaches an arbitrary threshold, which you've set to 7?

Is this an accurate assessment?
 
yes.

the DashP2P object in dashvend.py (defined in dashvend/dash_p2p.py)
Code:
dashp2p = DashP2P(mainnet=MAINNET)
connects to a local dashd instance on port 9999 and sends a version message to
say "hello I'm a dash node"
Code:
self.sock.connect((self.host, self.port))
self.sock.send(msg_version().to_bytes())
(msg_version comes from python-bitcoinlib)
Code:
from bitcoin.messages import msg_version, msg_getdata, msg_pong, MsgSerializable
which has had constants overridden (the monkeypatch, dashvend/dash.py) to work with dash
Code:
import dash

while connected it has to answer pings with pongs to stay connected
Code:
if msg.command == 'ping':
    pong = msg_pong(nonce=msg.nonce)
    self.sock.send(pong.to_bytes())

if the incoming messages are inventory messages, are one of 4 types (that dashvend cares about), and are in the 'routing' dict (self.route, set by vend.get_listeners()), they get processed by the function mapped to the types command name (msg.command which is one of 'ix','tx', 'txlvote', 'block').
Code:
        elif msg.command == 'inv':
            for i in msg.inv:
                # transaction/block/txlrequest/txlvote
                if i.type in (1, 2, 4, 5):
                    gd = msg_getdata()
                    gd.inv.append(i)
                    self.sock.send(gd.to_bytes())
        if msg.command in self.route:
            self.route[msg.command](msg)

note: the first time through 'msg.command' is 'inv'. The msg_getdata(), gd.inv.append, sock.send portion sends the /components/ of the inv message back in as messages with different 'msg.command' values ('ix','tx',etc.). That's how the routing handles the actual messages nested within in the original inv message bundle.

---

The threshold testing happens when either a lock or an ix is received because they can come out of order (locks before ix).

The lock threshold of 7 was chosen because sometimes over 3G cellular Internet not all 10 locks were received.
 
Last edited by a moderator:
Here's the soda machine demo code, should be a good roadmap for developers to follow.

https://github.com/moocowmoo/dashvend

Let me know if you have any questions!

Thanks for sharing! I'm having trouble understanding the reason for checking the mempool in the Python code. It is my understanding that dashd will do this for you, and the result will show up in the 'confirmations' area of the transaction details.
Code:
[
    {
        "account" : "",
        "address" : "y16F4wy4fL9psQdCVNSZScfRXFC8DCXG29",
        "category" : "receive",
        "amount" : 1.00000000,
        "vout" : 0,
        "confirmations" : 5,
        "bcconfirmations" : 0,
        "txid" : "7557c69ccd21ba3e3d441efebe8e80e720658ccf936dd2b091157d2626327405",
        "walletconflicts" : [
        ],
        "time" : 1460143493,
        "timereceived" : 1460143493
    }
]

"confirmations: 5" means that it has 5 instantx confirmations
"bcconfirmations: 0" means it has 0 blockchain confirmations
 
Thanks for sharing! I'm having trouble understanding the reason for checking the mempool in the Python code. It is my understanding that dashd will do this for you, and the result will show up in the 'confirmations' area of the transaction details.

You're welcome!

The answer is non-wallet transaction support.
As of v12.0, gettransaction only works for addresses that the wallet has the private key for.

It was more difficult to write, but my design goal was to keep all private keys off the vending machine.
By analyzing wire-traffic, dashvend can detect InstantX without requiring the address' private key.
 
Back
Top