Git Product home page Git Product logo

baron's People

Contributors

akinsey avatar kallewoof avatar someoneweird avatar wangbus avatar wtogami avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

baron's Issues

Calculate invoice.balance_due within baron

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.

Limit QR to referrer of its own hostname

(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.

stopWatchingPayment broken by Baron restart

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.

Optional Metadata in Invoice

  • Add optional 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.
  • Extend the expiration time of a reused unpaid invoice to whatever is specified by the new invoice call.
  • If invoice.metadata.id and unpaid subsequent invoice creation with the same ID returns the previously created invoice instead of creating a new invoice.

Missing block hash very rare, make non-fatal

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.

Silent exit if couchdb is down

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.

Error Checking TODO's

  • Check if bitcoind responds. If it fails, send a notification to the admin and wait.
  • DO NOT USE INSIGHT IF BITCOIND IS DOWN.
  • Check if bitcoind's latest block is within the last hour. If it is not, send a notification to the admin and wait.

Upcoming webhook workflow changes

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.

  • Verify that the paid callback was correct. This allows the callback URL to be unprotected (no SSL) because it can verify the invoice with a SSL call to baron.
  • The app should obtain details necessary to construct a receipt to e-mail to the customer.

Handle bitcoind Safe Mode

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."

Use transaction.blocktime in limited cases

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.

Docs: Declare particular API elements as stable

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?

  • Documentation should declare particular API elements as guaranteed to be unchanging in future versions of Baron?
  • Should the API be versioned within the route path?
  • Should stable API elements be within a marked object within views to differentiate from not stable?

Handle Other Weird but Valid Transactions

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.

  • Multiple outputs can be paid to the same address within the same transaction. If this happens, simply add them together. 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.
  • Outputs can be of zero amount. If the total outputs to a watched address is zero, mark the transaction immediately invalid.

The standard client does do the following type of payment, and it is only somewhat rare.

  • Outputs can possibly pay multiple watched addresses. If this happens, the same TXID could satisfy more than one Invoice, or two addresses within the same Invoice. Add tests for both cases.

Add cache busting to routes

Our lack of unique user sessions makes us vulnerable to transparent HTTP caching which would cause weird errors for Baron users.

Stop storing lastBlockHash in CouchDB

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.

Suggested Implementation

  • At startup query CouchDB to find the most recent transaction blockhash. Use that for listSinceBlock and remember it in memory.
    • If no transaction has a blockhash, find the created time of the most recent payment request and approximate a blockhash index from any point prior to that time.
    • If there are no payment requests then just use the current blockhash. There are no incoming payments.

Generate our own random _id

(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.

Remove policy from code

Policy (rules) and Terms & Conditions should be on the vendor's website somewhere, not within the code of the generic auction system.

Void route, Expired and Void view

  • Add a route to void an invoice authenticated by api_key.
  • Both Void and Expired invoices may be viewed. The Pay Now button is hidden. A large Void or Expired message is overlaid upon the invoice to make very clear to the user.

Internalize Block Tracking

Proposed Details

  • Add an internal representation of recent blocks to Baron's database. type: block contains at least...
    • blockhash
    • previous blockhash
    • next blockhash
    • array of relevant incoming transactions contained within this block
    • height
  • When a block is X confirmations in the past there is no reason to keep it any longer. Allow for a configurable pruning threshold?
  • Instead of 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).
  • If a known block becomes invalid, walk to previous until a valid block is found. Any Baron-relevant transactions within blocks that have become invalid have their status changed as part of a reorg.

Local Port not always Public Port

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;

Add Terms and Conditions Link

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.

Crash: Uncaught callback connect failure

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

E-mail admin when payment becomes invalid

config.js should contain the parameters (matching adness):

  • SENDER_EMAIL - the From address
  • ADMIN_EMAILS - array of To addresses

Docs should explain the heckler config options:

  • SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS

Protect /notify and /blocknotify routes

It currently can be used to to easily crash Baron and/or kill bitcoind.

  • Config option to limit POST to particular hosts?
  • Input validation?
  • Rate limiting?

Arbitrary Title and Description per Invoice

.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.

Minor: Handle js parse failure during post

  • Should it detect a javascript parsing failure and not print the traceback to the user?
  • In the console log it might be useful to print the raw submitted javascript along with the err, which would aid the developer in debugging their app that integrates baron.
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)

Unique route for invoice creation

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 ?

Fallback Insight

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.

reorg test 2: Duplicate payments

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.

Get rid of insight

  1. Allow baron to operate with only bitcoind.
  2. Test under synthetic load conditions to be sure RPC does not deadlock.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.