Add persistence for account
This commit is contained in:
parent
c5aba2ac8e
commit
28e20809c8
93
dev/api.go
93
dev/api.go
@ -6,11 +6,15 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
"git.defalsify.org/vise.git/logging"
|
"git.defalsify.org/vise.git/logging"
|
||||||
|
"git.defalsify.org/vise.git/db"
|
||||||
|
fsdb "git.defalsify.org/vise.git/db/fs"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
|
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
||||||
)
|
)
|
||||||
@ -42,6 +46,7 @@ type Account struct {
|
|||||||
Nonce int `json: "nonce"`
|
Nonce int `json: "nonce"`
|
||||||
DefaultVoucher string `json: "defaultVoucher"`
|
DefaultVoucher string `json: "defaultVoucher"`
|
||||||
Balances map[string]int `json: "balances"`
|
Balances map[string]int `json: "balances"`
|
||||||
|
Alias string
|
||||||
Txs []string `json: "txs"`
|
Txs []string `json: "txs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +61,8 @@ type Voucher struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DevAccountService struct {
|
type DevAccountService struct {
|
||||||
|
dir string
|
||||||
|
db db.Db
|
||||||
accounts map[string]Account
|
accounts map[string]Account
|
||||||
accountsTrack map[string]string
|
accountsTrack map[string]string
|
||||||
accountsAlias map[string]string
|
accountsAlias map[string]string
|
||||||
@ -70,8 +77,10 @@ type DevAccountService struct {
|
|||||||
// accountsSession map[string]string
|
// accountsSession map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDevAccountService() *DevAccountService {
|
func NewDevAccountService(ctx context.Context, d string) *DevAccountService {
|
||||||
return &DevAccountService{
|
svc := &DevAccountService{
|
||||||
|
dir: d,
|
||||||
|
db: fsdb.NewFsDb(),
|
||||||
accounts: make(map[string]Account),
|
accounts: make(map[string]Account),
|
||||||
accountsTrack: make(map[string]string),
|
accountsTrack: make(map[string]string),
|
||||||
accountsAlias: make(map[string]string),
|
accountsAlias: make(map[string]string),
|
||||||
@ -81,6 +90,65 @@ func NewDevAccountService() *DevAccountService {
|
|||||||
txsTrack: make(map[string]string),
|
txsTrack: make(map[string]string),
|
||||||
autoVoucherValue: make(map[string]int),
|
autoVoucherValue: make(map[string]int),
|
||||||
}
|
}
|
||||||
|
err := svc.db.Connect(ctx, d)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
svc.db.SetPrefix(db.DATATYPE_USERDATA)
|
||||||
|
err = svc.loadAll(ctx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return svc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (das *DevAccountService) loadAccount(ctx context.Context, pubKey string, v []byte) error {
|
||||||
|
var acc Account
|
||||||
|
|
||||||
|
err := json.Unmarshal(v, &acc)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("malformed account: %v", pubKey)
|
||||||
|
}
|
||||||
|
das.accounts[pubKey] = acc
|
||||||
|
das.accountsTrack[acc.Track] = pubKey
|
||||||
|
if acc.Alias != "" {
|
||||||
|
das.accountsAlias[acc.Alias] = pubKey
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte) error {
|
||||||
|
var err error
|
||||||
|
s := string(k)
|
||||||
|
ss := strings.SplitN(s, "_", 2)
|
||||||
|
if len(ss) != 2 {
|
||||||
|
return fmt.Errorf("malformed key: %s", s)
|
||||||
|
}
|
||||||
|
if ss[0] == "account" {
|
||||||
|
err = das.loadAccount(ctx, ss[1], v)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (das *DevAccountService) loadAll(ctx context.Context) error {
|
||||||
|
d, err := os.ReadDir(das.dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, v := range(d) {
|
||||||
|
// TODO: move decoding to vise
|
||||||
|
fp := v.Name()
|
||||||
|
k := []byte(fp[1:])
|
||||||
|
v, err := das.db.Get(ctx, k)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = das.loadItem(ctx, k, v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (das *DevAccountService) WithAutoVoucher(ctx context.Context, symbol string, value int) *DevAccountService {
|
func (das *DevAccountService) WithAutoVoucher(ctx context.Context, symbol string, value int) *DevAccountService {
|
||||||
@ -94,6 +162,7 @@ func (das *DevAccountService) WithAutoVoucher(ctx context.Context, symbol string
|
|||||||
return das
|
return das
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: add persistence for vouchers
|
||||||
func (das *DevAccountService) AddVoucher(ctx context.Context, symbol string) error {
|
func (das *DevAccountService) AddVoucher(ctx context.Context, symbol string) error {
|
||||||
if symbol == "" {
|
if symbol == "" {
|
||||||
return fmt.Errorf("cannot add empty sym voucher")
|
return fmt.Errorf("cannot add empty sym voucher")
|
||||||
@ -154,6 +223,15 @@ func (das *DevAccountService) balanceAuto(ctx context.Context, pubKey string) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (das *DevAccountService) saveAccount(ctx context.Context, acc Account) error {
|
||||||
|
k := "account_" + acc.Address
|
||||||
|
v, err := json.Marshal(acc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return das.db.Put(ctx, []byte(k), v)
|
||||||
|
}
|
||||||
|
|
||||||
func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.AccountResult, error) {
|
func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.AccountResult, error) {
|
||||||
var b [pubKeyLen]byte
|
var b [pubKeyLen]byte
|
||||||
uid, err := uuid.NewV4()
|
uid, err := uuid.NewV4()
|
||||||
@ -168,16 +246,25 @@ func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.Accoun
|
|||||||
return nil, fmt.Errorf("short read: %d", c)
|
return nil, fmt.Errorf("short read: %d", c)
|
||||||
}
|
}
|
||||||
pubKey := fmt.Sprintf("0x%x", b)
|
pubKey := fmt.Sprintf("0x%x", b)
|
||||||
das.accounts[pubKey] = Account{
|
acc := Account{
|
||||||
Track: uid.String(),
|
Track: uid.String(),
|
||||||
Address: pubKey,
|
Address: pubKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = das.saveAccount(ctx, acc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
das.accounts[pubKey] = acc
|
||||||
das.accountsTrack[uid.String()] = pubKey
|
das.accountsTrack[uid.String()] = pubKey
|
||||||
das.balanceAuto(ctx, pubKey)
|
das.balanceAuto(ctx, pubKey)
|
||||||
|
|
||||||
if das.defaultAccount == zeroAccount {
|
if das.defaultAccount == zeroAccount {
|
||||||
das.defaultAccount = pubKey
|
das.defaultAccount = pubKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return &models.AccountResult{
|
return &models.AccountResult{
|
||||||
PublicKey: pubKey,
|
PublicKey: pubKey,
|
||||||
TrackingId: uid.String(),
|
TrackingId: uid.String(),
|
||||||
|
1
go.mod
1
go.mod
@ -12,6 +12,7 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -2,6 +2,8 @@ git.defalsify.org/vise.git v0.2.3-0.20250103172917-3e190a44568d h1:bPAOVZOX4frSG
|
|||||||
git.defalsify.org/vise.git v0.2.3-0.20250103172917-3e190a44568d/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
git.defalsify.org/vise.git v0.2.3-0.20250103172917-3e190a44568d/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250112121325-9e4c65c8b4d1 h1:RfU5/WFfPxDptlkyx4MT+4YmO79sY6HvIngUq5uwQPU=
|
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250112121325-9e4c65c8b4d1 h1:RfU5/WFfPxDptlkyx4MT+4YmO79sY6HvIngUq5uwQPU=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250112121325-9e4c65c8b4d1/go.mod h1:E6W7ZOa7ZvVr0Bc5ot0LNSwpSPYq4hXlAIvEPy3AJ7U=
|
git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250112121325-9e4c65c8b4d1/go.mod h1:E6W7ZOa7ZvVr0Bc5ot0LNSwpSPYq4hXlAIvEPy3AJ7U=
|
||||||
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
|
||||||
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||||
|
Loading…
Reference in New Issue
Block a user