slickage / baron Goto Github PK
View Code? Open in Web Editor NEWBaron is a Bitcoin payment processor that anyone can deploy
Baron is a Bitcoin payment processor that anyone can deploy
Warren had an issue when the balance_due did not match up with the line items, so the balance_due for the invoice should be calculated based off the line items within baron.
(Low priority)
req.headers['referer'] contains the referring URL that displays the QR image. If the hostname portion matches req.port then render the QR code, otherwise reject with a 400-level error.
We thought stopWatchingPayment() may be redundant given checkPaymentExpiration()
function checkPaymentExpiration(payment) {
var curTime = new Date().getTime();
var expirationTime = Number(payment.created) + config.spotRateValidForMinutes * 60 * 1000;
if(payment.status === 'unpaid' && expirationTime < curTime) {
payment.watched = false;
db.insert(payment);
}
}
checkPaymentExpiration() does almost the same thing except time granularity is limited to the updateWatchListInterval.
However removing stopWatchingPayment() breaks something, suggesting USD handling is broken in the case of restarting Baron. Need to investigate.
invoice.metadata
that can contain any data. Whatever is put there during invoice creation is passed back in the callback. This aids in baron integration with apps who do not wish to track payments in their own database.invoice.metadata.id
and unpaid subsequent invoice creation with the same ID returns the previously created invoice instead of creating a new invoice.https://github.com/slickage/baron/blob/master/jobs/lastblockjob.js#L36
function processBlockHash(blockHashObj) {
var blockHash = blockHashObj.hash;
api.getBlock(blockHash, function(err, block) {
if (err || !block) {
// TODO: If there's an error, lastblock in db is probably corrupt.
// Should we update the latest block?
console.log('Error: Last block may have been corrupted. Bitcoind may be out of sync with network.');
return console.log(err);
}
Currently baron fails if the previously stored best blockhash is not known to the data source. This can be valid in very rare instances where you were on a fork that subsequently lost and baron switches to a different data source that is entirely unaware of the fork. Should this happen it should log the fact that the previous block hash is unknown and recover on the best block hash from the data source.
I recommend handling this along with #27 because it can be handled in the cleanest fashoin by walking backwards in the internal block database until it finds a block that is valid in the external data source.
bitcoin/bitcoin#3656
C++ implementation
See adness site.js for an example.
18:43:38 web.1 | started with pid 7894
18:43:39 web.1 | connect: multipart: use parser (multiparty, busboy, formidable) directly
18:43:39 web.1 | connect: limit: Restrict request size at location of read
18:43:39 web.1 | Baron listening at http://0.0.0.0:8080
18:43:39 web.1 | exited with code 1
Should print an error informing the admin what to do.
Here is what is planned for the webhooks.
sha256 hashing will be entirely removed. It was a bad idea. My fault. It adds complexity without any additional security.
The "paid" webhook will work in a similar manner as the current webhook (sans sha256). Baron will remove the webhook from the retry queue if it receives a 200 response upon post.
The application can then optionally verify details about the payment by reading a status route on baron. The status route has multiple purposes.
Outgoing link to external explorer leaks the payment ID's in cleartext to the Internet as the referrer. A safe redirect link is needed.
23:57:02 web.1 | ===========================
23:57:02 web.1 | Processing Last Block: 0000000073ec735fc882d79b1020fe8ea788a20be29edb8de156513ae1bb0d61
23:57:02 web.1 | ===========================
23:57:02 web.1 | [SyntaxError: Unexpected token S]
23:57:02 web.1 | Error: Last block may have been corrupted. Bitcoind may be out of sync with network.
23:57:02 web.1 | [SyntaxError: Unexpected token S]
23:57:02 web.1 | Error parsing transaction from body: Safe mode: Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. [Host: 127.0.0.1:18332 User:QmHJG1jkmSnhYME Using password:yes]. Code:-2
In this rare event Baron needs to know to stop asking for payments until things return to normal. Baron should refuse to show new payment addresses and instead print an error something like, "Temporary Downtime. Bitcoin is currently in safe mode. Please contact the system administrator."
In some limited cases during Baron startup only, use of transaction.blocktime for the payment time may be closer to accurate than transaction.time.
This requires a bit more thought of exactly when.
The current API routes are a bit messy and likely to change along with future improvements. It would be very messy if 3rd party software becomes reliant on the current API elements.
How should we deal with this?
These types of transactions are possible but extremely rare because the standard client does not create them. These are of minor importance. Perhaps fix this later, and add to a list of automated tests.
gettransaction
and listsinceblock
already hides this detail from you. Just keep this in mind for a later implementation if you end up processing all outputs individually within Baron.The standard client does do the following type of payment, and it is only somewhat rare.
Our lack of unique user sessions makes us vulnerable to transparent HTTP caching which would cause weird errors for Baron users.
Currently baron stores the last known blockhash in couchdb. It uses this blockhash on startup with listSinceBlock in order to process incoming payments that may have happened during downtime.
The way we are currently doing this non-ideal because it bloats couchdb with all the deletion and addition of a frequently changing record. Upon every new block it deletes the previous blockhash and adds the new record.
It turns out we do not need to store the last known block hash if we can obtain it from a different part of the database. For example, the most recent transaction blockhash fine to query with listSinceBlock.
If you have quantity 1, perhaps it would be cleaner if the invoice hid the 1x and price per unit for that line item?
If you are using a non-local instance of couchdb or localhost is secured with a password then Baron's configuration requires an optional password field?
(Low priority)
We can remove the required random UUID CouchDB config requirement if we generate our own random _id's.
http://blog.tompawlak.org/how-to-generate-random-values-nodejs-javascript
3. Generate random values using Node.js crypto module
appears to be an easy-to-use built-in nodejs approach. It appears we cannot rely on crypto.randomBytes
because it can fail if entropy is drained.
senchalabs/connect#932 (comment)
crypto.pseudoRandomBytes
appears entirely adequate if this is true, that it relies on openssl which itself is seeded from /dev/urandom. This should be good enough for the privacy required of invoiceId's.
Policy (rules) and Terms & Conditions should be on the vendor's website somewhere, not within the code of the generic auction system.
Currently it grabs the nearest timestamp before.
We're ignoring sent payments now.
Proposed Details
type: block
contains at least...
gettransaction
, the # of confirmations can be calculated from latest block height minus the height of the block containing the transaction. The status of previous transactions need not be queried again if their blockhash remains valid (within the best chain).While working on #35 I noticed some things need to be fixed pertaining to the publicly visible address built from publicHostName
.
var invoiceUrl = config.publicHostName + port + '/invoices/' + invoiceId;
At the bottom of the Invoice and Payments page have a link to open a new window to a URL provided during invoice creation. If they did not provide such a URL then do not display the link. This is needed because different types of invoices will have different terms.
Invoices for $0 or 0 BTC are currently valid. We need to reject invoices like this.
If you specify a callback URL that is not listening it crashes baron.
22:04:37 web.1 | ===========================
22:04:37 web.1 | Processing Last Block: 000000008ec1cb327e1c4512dd8c687ec4b095d53a0c14eac22b797d525266bb
22:04:37 web.1 | ===========================
22:04:37 web.1 | > Block Valid: true
22:04:37 web.1 |
22:04:37 web.1 | events.js:72
22:04:37 web.1 | throw er; // Unhandled 'error' event
22:04:37 web.1 | ^
22:04:37 web.1 | Error: connect ECONNREFUSED
22:04:37 web.1 | at errnoException (net.js:904:11)
22:04:37 web.1 | at Object.afterConnect [as oncomplete] (net.js:895:19)
22:04:37 web.1 | exited with code 8
config.js
should contain the parameters (matching adness):
SENDER_EMAIL
- the From addressADMIN_EMAILS
- array of To addressesDocs should explain the heckler config options:
SMTP_HOST
, SMTP_PORT
, SMTP_USER
, SMTP_PASS
It currently can be used to to easily crash Baron and/or kill bitcoind.
.title
contains the title to replace the "Baron" at the top of invoices and payments.
.text
contains arbitrary text to display at the bottom of invoices and payments. This will usually contain instructions and potentially links to elsewhere to things like Terms and Conditions. It should be sanitized of scripts but allow links.
5e468b016b1f3370af8fdcd84f020690
5e468b016b1f3370af8fdcd84f035034
Two invoices created near each other have a very similar ID. This would be a privacy and security problem where people can too easily find all of the other invoices from other users. The user visible invoice hash must be truly random.
http://docs.couchdb.org/en/latest/config/misc.html#uuids/algorithm
Change algorithm from sequential to random.
curl -v -X POST -H "Content-Type: application/json" -d @BARONTEST http://localhost:5000/invoices
* Adding handle: conn: 0x216db60
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x216db60) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 5000 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 5000 (#0)
> POST /invoices HTTP/1.1
> User-Agent: curl/7.32.0
> Host: localhost:5000
> Accept: */*
> Content-Type: application/json
> Content-Length: 358
>
* upload completely sent off: 358 out of 358 bytes
< HTTP/1.1 400 Bad Request
< X-Powered-By: Express
< Content-Type: text/html
< Content-Length: 479
< Date: Sat, 03 May 2014 07:43:18 GMT
< Connection: keep-alive
<
SyntaxError: Unexpected token p
at Object.parse (native)
at /home/warren/work/baron/node_modules/express/node_modules/connect/lib/middleware/json.js:75:25
at IncomingMessage.onEnd (/home/warren/work/baron/node_modules/express/node_modules/connect/node_modules/raw-body/index.js:113:7)
at IncomingMessage.g (events.js:180:16)
at IncomingMessage.EventEmitter.emit (events.js:92:17)
at _stream_readable.js:920:16
* Connection #0 to host localhost left intact
at process._tickCallback (node.js:415:13)
Currently an attacker can POST at a rapid rate in an attempt to brute force the access_token or at least rapidly fill the log disk after #8. This can be easily improved for internal-only deployments if a unique route is used only to create invoices. That would allow the proxy_pass frontend to block access from the public. If Baron is later to be used as a public service, you probably will need to add DoS rate limiting per IP address, but this isn't a priority for the moment.
Can invoice creation be moved to a separate route like /createinvoice ?
How did you setup walletnotify and blocknotify to signal baron? Would be helpful to add that to README.md. Did you use any helper script?
https://github.com/slickage/baron/blob/master/config.js#L4
port: process.env.PORT || 8080,
Explicitly setting the environment variable PORT succeeds in changing the Baron HTTP listen port number. However if PORT is unset the default should be 8080 but it instead listens on port 5000. (I am not sure where 5000 is coming from.)
Allow defining a fallback instance of Insight, in case your main goes down. This might be important given how often Insight has been crashing for us.
Currently if you post with an invalid access_token the console log is silent. It should probably log the error starting with the IP address of the rejected client.
reorgtest.sh test2
tests double spending to the same address. It correctly identifies the previous transaction as invalid, points at the original blockhash and walletconflict txid. But subsequently the replacement txid appears two or three times as status Paid.
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.