Example #1
0
// Create or updates an existing Payment, associated with the given block.
// When updating, sets the status to GOOD and sets the block* if not already set.
func createOrUpdatePayment(rpcPayment *rpc.RPCPayment, block *Block) *Payment {
	// SANITY CHECK
	if block == nil {
		if rpcPayment.Blockhash != "" || rpcPayment.Blockheight != 0 {
			panic(NewError("Something is wrong, a rpcPayment with no block should have no hash or height"))
		}
	} else {
		if rpcPayment.Blockhash != block.Hash || rpcPayment.Blockheight != block.Height {
			panic(NewError("Something is wrong, expected rpcPayment.Blockhash to match block.Hash"))
		}
	}
	// END SANITY CHECK

	payment := FromRPCPayment(rpcPayment)
	_, err := SavePayment(db.GetModelDB(), payment)
	switch db.GetErrorType(err) {
	case db.ERR_DUPLICATE_ENTRY:
		UpdatePayment(db.GetModelDB(), payment)
	default:
		if err != nil {
			panic(err)
		}
	}
	return payment
}
Example #2
0
// This just creates a new row in the accounts_deposits table.
// It doesn't actually credit the account, etc.
// Must be idempotent.
func LoadOrCreateDepositForPayment(payment *bitcoin.Payment) *Deposit {

	if payment.Id == 0 {
		panic(NewError("Cannot add deposit for unsaved payment"))
	}

	addr := bitcoin.LoadAddress(payment.Address)
	if addr == nil {
		panic(NewError("Expected address for payment to deposit"))
	}

	deposit := &Deposit{
		Type:      DEPOSIT_TYPE_CRYPTO,
		UserId:    addr.UserId,
		Wallet:    addr.Wallet,
		Coin:      addr.Coin,
		Amount:    payment.Amount,
		PaymentId: payment.Id,
		Status:    DEPOSIT_STATUS_PENDING,
	}
	_, err := SaveDeposit(db.GetModelDB(), deposit)
	switch db.GetErrorType(err) {
	case db.ERR_DUPLICATE_ENTRY:
		return LoadDepositForPayment(db.GetModelDB(), payment.Id)
	default:
		if err != nil {
			panic(err)
		}
	}

	return deposit
}
Example #3
0
func LoadMPKByPubKey(pubKey string) *MPK {
	var mpk MPK
	err := db.QueryRow(
		`SELECT `+MPKModel.FieldsSimple+`
         FROM mpk WHERE pubkey=?`,
		pubKey,
	).Scan(&mpk)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &mpk
	default:
		panic(err)
	}
}
Example #4
0
func LoadBlockAtHeight(coin string, height uint32) *Block {
	var block Block
	err := db.QueryRow(
		`SELECT `+BlockModel.FieldsSimple+`
         FROM block WHERE coin=? AND height=? AND (status=0 OR status=1 OR status=10)`,
		coin, height,
	).Scan(&block)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &block
	default:
		panic(err)
	}
}
Example #5
0
func LoadBlock(hash string) *Block {
	var block Block
	err := db.QueryRow(
		`SELECT `+BlockModel.FieldsSimple+`
         FROM block WHERE hash=?`,
		hash,
	).Scan(&block)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &block
	default:
		panic(err)
	}
}
Example #6
0
func LoadMPK(mpkId int64) *MPK {
	var mpk MPK
	err := db.QueryRow(
		`SELECT `+MPKModel.FieldsSimple+`
         FROM mpk WHERE id=?`,
		mpkId,
	).Scan(&mpk)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &mpk
	default:
		panic(err)
	}
}
Example #7
0
func SaveOrUpdatePriceLog(tx *db.ModelTx, plog *PriceLog) {
	var exists int
	err := tx.QueryRow(
		`SELECT 1 FROM exchange_price_log
         WHERE market=? AND interval=? AND time=?`,
		plog.Market, plog.Interval, plog.Time,
	).Scan(&exists)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		SavePriceLog(tx, plog)
	case nil:
		UpdatePriceLog(tx, plog)
	default:
		panic(err)
	}
}
Example #8
0
func Get(key string) string {
	var value string
	err := db.QueryRow(
		`SELECT value
         FROM kvstore WHERE key_=?`,
		key,
	).Scan(&value)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return ""
	case nil:
		return value
	default:
		panic(err)
	}
}
Example #9
0
func LoadOrder(id int64) *Order {
	var order Order
	err := db.QueryRow(
		`SELECT `+OrderModel.FieldsSimple+`
         FROM exchange_order
         WHERE id=?`, id,
	).Scan(&order)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &order
	default:
		panic(err)
	}
}
Example #10
0
func LoadAddress(address string) *Address {
	var addr Address
	err := db.QueryRow(
		`SELECT `+AddressModel.FieldsSimple+`
         FROM address
         WHERE address=?`,
		address,
	).Scan(&addr)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &addr
	default:
		panic(err)
	}
}
Example #11
0
// Gets the last executed order id, or 0 if none.
func LastCompletedOrderId(basisCoin string, coin string) int64 {
	var lastCompletedOrderId int64
	err := db.QueryRow(
		`SELECT id FROM exchange_order
         WHERE basis_coin=? AND coin=? AND status=3
         ORDER BY id DESC limit 1`,
		basisCoin, coin,
	).Scan(&lastCompletedOrderId)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return 0
	case nil:
		return lastCompletedOrderId
	default:
		panic(err)
	}
}
Example #12
0
func LoadLastAddressByWallet(userId int64, wallet string, coin string) *Address {
	var addr Address
	err := db.QueryRow(
		`SELECT `+AddressModel.FieldsSimple+`
         FROM address
         WHERE user_id=? AND wallet=? AND coin=?
         ORDER BY chain_idx DESC LIMIT 1`,
		userId, wallet, coin,
	).Scan(&addr)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &addr
	default:
		panic(err)
	}
}
Example #13
0
func LoadUserByEmail(email string) *User {
	var user User
	err := db.QueryRow(
		`SELECT `+UserModel.FieldsSimple+`
         FROM auth_user WHERE email=?`,
		email,
	).Scan(
		&user,
	)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &user
	default:
		panic(err)
	}
}
Example #14
0
func LoadAPIKey(key string) *APIKey {
	var apiKey APIKey
	err := db.QueryRow(
		`SELECT `+APIKeyModel.FieldsSimple+`
         FROM auth_api_key WHERE key=?`,
		key,
	).Scan(
		&apiKey,
	)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &apiKey
	default:
		panic(err)
	}
}
Example #15
0
func LoadUser(userId int64) *User {
	var user User
	err := db.QueryRow(
		`SELECT `+UserModel.FieldsSimple+`
         FROM auth_user WHERE id=?`,
		userId,
	).Scan(
		&user,
	)
	switch db.GetErrorType(err) {
	case sql.ErrNoRows:
		return nil
	case nil:
		return &user
	default:
		panic(err)
	}
}
Example #16
0
// Keeps trying until one is created in the path.
// The resulting address's path will be 'chainpath/x'
// where 'x' is the smallest nonnegative integer.
func CreateNewAddress(coin string, userId int64, wallet string, mpk *MPK, chainPath string) *Address {
	now := time.Now().Unix()
	index := GetMaxAddressIndex(coin, mpk.Id, chainPath)
	for {
		index += 1
		address := ComputeAddress(coin, mpk.PubKey, mpk.Chain, chainPath, index)
		addr := &Address{address, coin, userId, wallet, mpk.Id, chainPath, index, now}
		addr, err := SaveAddress(addr)
		Info("[%v] Created new address: wallet:%v/%v mpkId:%v chainPath:%v/%v",
			coin, userId, wallet, mpk.Id, chainPath, index)
		switch db.GetErrorType(err) {
		case db.ERR_DUPLICATE_ENTRY:
			continue
		case nil:
			return addr
		default:
			panic(err)
		}
	}
}
Example #17
0
func Set(key, value string) {
	_, err := db.Exec(
		`INSERT INTO kvstore (key_, value)
         VALUES (?, ?)`,
		key, value,
	)
	switch db.GetErrorType(err) {
	case nil:
		return
	case db.ERR_DUPLICATE_ENTRY:
		// Update instead
		_, err := db.Exec(
			`UPDATE kvstore SET value=? WHERE key=?`,
			value, key,
		)
		if err != nil {
			panic(err)
		}
		return
	default:
		panic(err)
	}
}
Example #18
0
// Create a new user.
func SaveUser(user *User) (*User, error) {

	// Create email confirmation code.
	if user.EmailCode == "" {
		user.EmailCode = RandId(24)
	}
	// Create TOTPKey.
	if len(user.TOTPKey) == 0 {
		user.TOTPKey = RandBytes(10)
	}

	// Scrypt the password.
	if user.Password != "" {
		salt := RandId(12)
		scryptPass, err := scrypt.Key([]byte(user.Password), []byte(salt), 16384, 8, 1, 32)
		if err != nil {
			return nil, err
		}
		user.Salt = []byte(salt)
		user.Scrypt = scryptPass
	}

	err := db.DoBeginSerializable(func(tx *db.ModelTx) {
		// Insert into users table.
		err := tx.QueryRow(
			`INSERT INTO auth_user (`+UserModel.FieldsInsert+`)
             VALUES (`+UserModel.Placeholders+`)
             RETURNING id`,
			user,
		).Scan(&user.Id)
		if err != nil {
			panic(err)
		}

		// Set the chain_idx
		if user.Id > math.MaxInt32 {
			panic("User autoinc id has exceeded MaxInt32")
		}
		user.ChainIdx = int32(user.Id)
		_, err = tx.Exec(
			`UPDATE auth_user
             SET chain_idx = id
             WHERE id=?`,
			user.Id,
		)
		if err != nil {
			panic(err)
		}

		// Generate an API key for the user
		apiKey := &APIKey{Key: RandId(24), UserId: user.Id}
		SaveAPIKey(tx, apiKey)

	})
	switch db.GetErrorType(err) {
	case db.ERR_DUPLICATE_ENTRY:
		return nil, ERR_DUPLICATE_ADDRESS
	case nil:
		break
	default:
		panic(err)
	}

	return user, nil
}