| This is a hacky patch for a problem that runs more deeply: the use of
floating-point for Mana calculations, along with the associated rounding
errors.
Consider the following example:
```typescript
const balance = 1000
const bet = 5.6e-14
const newBalance = balance - bet
if (newBalance == balance) {
  alert(`I placed a bet of ${bet} without changing my balance.`)
}
```
This will actually print a message, because floating-point numbers can
only represent so many digits, and thus we get 1000.0 rather than
999.99999999999994.
This is a purely theoretical attack at this point; nobody could create
enough pico-bets to actually affect their balance using this technique.
However, I believe is worth ensuring a minimum bet amount, and might
prevent other problems such as the UI showing messages like "User Foo
bought M0 of YES", which could confuse users.
For a more definite solution, we would probably need to change some
computation to integers, where addition is always commutative and
value-preserving. This is similar to what most financial software does
(e.g., Bitcoin uses 1 Satoshi = 0.00000001 BTC as their unit). | ||
|---|---|---|
| .. | ||
| src | ||
| .eslintrc.js | ||
| .gitignore | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
NOTE: Adapted from One Word's /functions doc. Fix any errors you see!
Firestore Cloud Functions
This is code that doesn't make sense on the frontend client, e.g.
- Long-running or slow operation (database)
- Tasks that need to be run every so often (syncing email list to Mailjet)
- Anything we should't trust to clients (secrets, auth)
If you want to make and test changes, you'll have to do a bit of setup...
Installing
Adapted from https://firebase.google.com/docs/functions/get-started
- $ cd functionsto switch to this folder
- $ yarn global add firebase-toolsto install the Firebase CLI globally
- $ yarnto install JS dependencies
- $ firebase loginto authenticate the CLI tools to Firebase
- $ firebase use devto choose the dev project
For local development
- $ firebase functions:config:get > .runtimeconfig.jsonto cache secrets for local dev
- Install gcloud CLI
- $ brew install javato install java if you don't already have it- $ echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrcto add java to your path
 
- $ gcloud auth loginto authenticate the CLI tools to Google Cloud
- $ gcloud config set project <project-id>to choose the project (- $ gcloud projects listto see options)
- $ mkdir firestore_exportto create a folder to store the exported database
- $ yarn db:update-local-from-remoteto pull the remote db from Firestore to local- TODO: this won't work when open source, we'll have to point to the public db
 
Developing locally
- $ firebase use devif you haven't already
- $ yarn serveto spin up the emulators- The Emulator UI is at http://localhost:4000; the functions are hosted on :5001. Note: You have to kill and restart emulators when you change code; no hot reload =(
 
- $ yarn dev:emulatein- /webto connect to emulators with the frontend- Note: emulated database is cleared after every shutdown
 
Firestore Commands
- db:update-local-from-remote- Pull the remote db from Firestore to local, also calls:- db:backup-remote- Exports the remote dev db to the backup folder on Google Cloud Storage (called on every- db:update-local-from-remote)
- db:rename-remote-backup-folder- Renames the remote backup folder (called on every- db:backup-remoteto preserve the previous db backup)
 
- db:backup-local- Save the local db changes to the disk (overwrites existing)
Debugging
- Find local logs directly in the shell that ran $ yarn dev
- Find deployed logs here
Deploying
- $ firebase use prodto switch to prod
- $ yarn deployto push your changes live! (Future TODO: auto-deploy functions on Git push)
Secrets management
Secrets are strings that shouldn't be checked into Git (eg API keys, passwords). We store these using environment config on Firebase Functions. Some useful workflows:
- Set a secret: $ firebase functions:config:set stripe.test_secret="THE-API-KEY"
- Preview all secrets: $ firebase functions:config:get
- Cache for local dev:$ firebase functions:config:get > .runtimeconfig.json