Browse Source

Add statsd reporting, extra error type

master
Teran McKinney 2 years ago
parent
commit
16d2d0def0
  1. 2
      cmd/settlersd/balance.go
  2. 58
      cmd/settlersd/cmd_test.go
  3. 2
      cmd/settlersd/deposit_only_token_enabled.go
  4. 3
      cmd/settlersd/enable.go
  5. 78
      cmd/settlersd/stats.go
  6. 2
      cmd/settlersd/web.go
  7. 3
      errors.go

2
cmd/settlersd/balance.go

@ -24,7 +24,7 @@ func balance(token string, db *sqlite3.Conn) (amount uint64, userErr, err error)
return
}
if !hasRow {
userErr = settlers.ErrorAccountNotEnabled
userErr = settlers.ErrorTokenNotEnabled
return
}
// sqlite3 only supports signed integers

58
cmd/settlersd/cmd_test.go

@ -9,6 +9,7 @@ import (
const testAdminToken = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
const testToken = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
const testToken2 = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
var testConfiguration = Configuration{SqliteFilename: inMemoryDatabase, AdminToken: testAdminToken, Port: ":2828"}
@ -22,7 +23,7 @@ func TestSettlers(t *testing.T) {
_, userErr, err := balance(testToken, db)
if err != nil {
t.Error(err.Error())
} else if userErr != settlers.ErrorAccountNotEnabled {
} else if userErr != settlers.ErrorTokenNotEnabled {
t.Error("Account should not be enabled.")
} else {
log.Print("Non-enabled account balance shows not enabled.")
@ -30,7 +31,7 @@ func TestSettlers(t *testing.T) {
depositToken := settlers.DepositToken(testToken)
err, userErr = enable(testToken, depositToken, testAdminToken, db, testConfiguration)
userErr, err = enable(testToken, depositToken, testAdminToken, db, testConfiguration)
if err != nil {
t.Error(err.Error())
} else if userErr != nil {
@ -39,6 +40,26 @@ func TestSettlers(t *testing.T) {
log.Print("Enable worked.")
}
// Try to enable the same token again.
userErr, err = enable(testToken, depositToken, testAdminToken, db, testConfiguration)
if err != nil {
t.Error(err.Error())
} else if userErr != settlers.ErrorTokenAlreadyEnabled {
t.Error("Did not get TokenAlreadyEnabled error for twice enabled token.")
} else {
log.Print("Second enable for identical token errored correctly.")
}
depositToken2 := settlers.DepositToken(testToken2)
userErr, err = enable(testToken2, depositToken2, testAdminToken, db, testConfiguration)
if err != nil {
t.Error(err.Error())
} else if userErr != nil {
t.Error(userErr.Error())
} else {
log.Print("Enable worked for token 2.")
}
amount, userErr, err := balance(testToken, db)
if err != nil {
t.Error(err.Error())
@ -122,7 +143,7 @@ func TestSettlers(t *testing.T) {
_, userErr, err = balance(depositToken, db)
if err != nil {
t.Error(err.Error())
} else if userErr != settlers.ErrorAccountNotEnabled {
} else if userErr != settlers.ErrorTokenNotEnabled {
t.Error(userErr.Error())
} else {
log.Print("Deposit token can't check balance.")
@ -131,7 +152,7 @@ func TestSettlers(t *testing.T) {
userErr, err = add(depositToken, 10, db)
if err != nil {
t.Error(err.Error())
} else if userErr != settlers.ErrorAccountNotEnabled {
} else if userErr != settlers.ErrorTokenNotEnabled {
t.Error(userErr.Error())
} else {
log.Print("Deposit token can't do regular add.")
@ -140,9 +161,36 @@ func TestSettlers(t *testing.T) {
userErr, err = subtract(depositToken, 10, db)
if err != nil {
t.Error(err.Error())
} else if userErr != settlers.ErrorAccountNotEnabled {
} else if userErr != settlers.ErrorTokenNotEnabled {
t.Error(userErr.Error())
} else {
log.Print("Deposit token can't do subtract.")
}
userErr, err = add(testToken2, 100, db)
if err != nil {
t.Error(err.Error())
} else if userErr != nil {
t.Error(userErr.Error())
} else {
log.Print("Able to add 100 to token 2.")
}
sumBalance, err := totalLiabilities(db)
if err != nil {
t.Error(err.Error())
} else if sumBalance != 260 {
t.Errorf("Total Balance is %d, not 260.", sumBalance)
} else {
log.Print("Total balance is correct.")
}
sumTokens, err := totalTokens(db)
if err != nil {
t.Error(err.Error())
} else if sumTokens != 2 {
t.Errorf("Total tokens is %d, not 2.", sumTokens)
} else {
log.Print("Total tokens is correct.")
}
}

2
cmd/settlersd/deposit_only_token_enabled.go

@ -23,7 +23,7 @@ func depositOnlyTokenEnabled(depositOnlyToken string, db *sqlite3.Conn) (userErr
return
}
if !hasRow {
userErr = settlers.ErrorAccountNotEnabled
userErr = settlers.ErrorTokenNotEnabled
return
}
return

3
cmd/settlersd/enable.go

@ -30,6 +30,9 @@ func enable(token, depositOnlyToken, adminToken string, db *sqlite3.Conn, conf C
// userErr because of constraint issues but debatable.
// If the user tries to add two tokens, it should fail and not be considered our failure.
userErr = db.Exec("INSERT INTO balances (combined_token, combined_deposit_only_token, balance) VALUES (?, ?, ?)", token, depositOnlyToken, startingBalance)
if userErr != nil {
userErr = settlers.ErrorTokenAlreadyEnabled
}
return
}

78
cmd/settlersd/stats.go

@ -0,0 +1,78 @@
package main
import (
"log"
"time"
"github.com/bvinc/go-sqlite-lite/sqlite3"
"gopkg.in/alexcesaro/statsd.v2"
)
// Seconds
const statsdReportingInterval = 60
func totalLiabilities(db *sqlite3.Conn) (amount uint64, err error) {
// This gets the total amount of "liabilities" from all tokens.
statement, err := db.Prepare("SELECT SUM(balance) FROM balances")
if err != nil {
return
}
defer statement.Close()
hasRow, err := statement.Step()
if err != nil {
return
}
if !hasRow {
return
}
// sqlite3 only supports signed integers
var signedAmount int64
if err = statement.Scan(&signedAmount); err != nil {
return
}
amount = uint64(signedAmount)
return
}
func totalTokens(db *sqlite3.Conn) (tokens uint64, err error) {
// This gets the total tokens of tokens in the database.
statement, err := db.Prepare("SELECT COUNT(*) FROM balances")
if err != nil {
return
}
defer statement.Close()
hasRow, err := statement.Step()
if err != nil {
return
}
if !hasRow {
return
}
// sqlite3 only supports signed integers
var signedAmount int64
if err = statement.Scan(&signedAmount); err != nil {
return
}
tokens = uint64(signedAmount)
return
}
func statsdLoop(s *statsd.Client, db *sqlite3.Conn) {
for true {
liabilitiesSum, err := totalLiabilities(db)
if err != nil {
log.Print(err.Error())
} else {
log.Printf("Liabilities count: %d", liabilitiesSum)
s.Gauge("liabilities.sum", liabilitiesSum)
}
tokensCount, err := totalTokens(db)
if err != nil {
log.Print(err.Error())
} else {
log.Printf("Tokens count: %d", tokensCount)
s.Gauge("tokens.sum", tokensCount)
}
time.Sleep(statsdReportingInterval * time.Second)
}
}

2
cmd/settlersd/web.go

@ -74,6 +74,8 @@ func web(conf Configuration) (err error) {
return
})
go statsdLoop(s, db)
err = http.ListenAndServe(conf.Port, nil)
return
}

3
errors.go

@ -4,7 +4,8 @@ import (
"errors"
)
var ErrorAccountNotEnabled = errors.New("Account not enabled.")
var ErrorTokenNotEnabled = errors.New("Token not enabled.")
var ErrorInsufficientBalance = errors.New("Balance insufficient.")
var ErrorIncorrectAdminToken = errors.New("Incorrect admin token.")
var ErrorInvalidToken = errors.New("Token must be exactly 64 lowercase hex characters in length.")
var ErrorTokenAlreadyEnabled = errors.New("Token already enabled.")
Loading…
Cancel
Save