Create single database appdatase

This commit is contained in:
Dmitry 2019-07-25 08:35:09 +03:00 committed by Dmitry Shulyak
parent be9c55bc16
commit 494cb5bb33
41 changed files with 353 additions and 994 deletions

View file

@ -2,10 +2,10 @@ package api
import (
"context"
"database/sql"
"errors"
"fmt"
"math/big"
"path"
"path/filepath"
"sync"
"time"
@ -19,6 +19,7 @@ import (
gethnode "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/crypto"
"github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/mailserver/registry"
@ -29,10 +30,13 @@ import (
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/rpc"
accountssvc "github.com/status-im/status-go/services/accounts"
"github.com/status-im/status-go/services/browsers"
"github.com/status-im/status-go/services/permissions"
"github.com/status-im/status-go/services/personal"
"github.com/status-im/status-go/services/rpcfilters"
"github.com/status-im/status-go/services/subscriptions"
"github.com/status-im/status-go/services/typeddata"
"github.com/status-im/status-go/services/wallet"
"github.com/status-im/status-go/signal"
"github.com/status-im/status-go/transactions"
)
@ -60,7 +64,7 @@ type StatusBackend struct {
mu sync.Mutex
// rootDataDir is the same for all networks.
rootDataDir string
accountsDB *accounts.Database
appDB *sql.DB
statusNode *node.StatusNode
personalAPI *personal.PublicAPI
rpcFilters *rpcfilters.Service
@ -167,22 +171,25 @@ func (b *StatusBackend) SaveAccount(account multiaccounts.Account) error {
return b.multiaccountsDB.SaveAccount(account)
}
func (b *StatusBackend) ensureAccountsDBOpened(account multiaccounts.Account, password string) (err error) {
func (b *StatusBackend) ensureAppDBOpened(account multiaccounts.Account, password string) (err error) {
b.mu.Lock()
defer b.mu.Unlock()
if b.accountsDB != nil {
if b.appDB != nil {
return nil
}
if len(b.rootDataDir) == 0 {
return errors.New("root datadir wasn't provided")
}
path := filepath.Join(b.rootDataDir, fmt.Sprintf("accounts-%x.sql", account.Address))
b.accountsDB, err = accounts.InitializeDB(path, password)
return err
path := filepath.Join(b.rootDataDir, fmt.Sprintf("app-%x.sql", account.Address))
b.appDB, err = appdatabase.InitializeDB(path, password)
if err != nil {
return err
}
return nil
}
func (b *StatusBackend) StartNodeWithAccount(acc multiaccounts.Account, password string) error {
err := b.ensureAccountsDBOpened(acc, password)
err := b.ensureAppDBOpened(acc, password)
if err != nil {
return err
}
@ -193,15 +200,16 @@ func (b *StatusBackend) StartNodeWithAccount(acc multiaccounts.Account, password
if err := logutils.OverrideRootLogWithConfig(conf, false); err != nil {
return err
}
chatAddr, err := b.accountsDB.GetChatAddress()
accountsDB := accounts.NewDB(b.appDB)
chatAddr, err := accountsDB.GetChatAddress()
if err != nil {
return err
}
walletAddr, err := b.accountsDB.GetWalletAddress()
walletAddr, err := accountsDB.GetWalletAddress()
if err != nil {
return err
}
watchAddrs, err := b.accountsDB.GetAddresses()
watchAddrs, err := accountsDB.GetAddresses()
if err != nil {
return err
}
@ -235,7 +243,7 @@ func (b *StatusBackend) StartNodeWithAccountAndConfig(account multiaccounts.Acco
if err != nil {
return err
}
err = b.ensureAccountsDBOpened(account, password)
err = b.ensureAppDBOpened(account, password)
if err != nil {
return err
}
@ -243,7 +251,7 @@ func (b *StatusBackend) StartNodeWithAccountAndConfig(account multiaccounts.Acco
if err != nil {
return err
}
err = b.accountsDB.SaveAccounts(subaccs)
err = accounts.NewDB(b.appDB).SaveAccounts(subaccs)
if err != nil {
return err
}
@ -253,14 +261,14 @@ func (b *StatusBackend) StartNodeWithAccountAndConfig(account multiaccounts.Acco
func (b *StatusBackend) saveNodeConfig(config *params.NodeConfig) error {
b.mu.Lock()
defer b.mu.Unlock()
return b.accountsDB.SaveConfig(accounts.NodeConfigTag, config)
return accounts.NewDB(b.appDB).SaveConfig(accounts.NodeConfigTag, config)
}
func (b *StatusBackend) loadNodeConfig() (*params.NodeConfig, error) {
b.mu.Lock()
defer b.mu.Unlock()
conf := params.NodeConfig{}
err := b.accountsDB.GetConfig(accounts.NodeConfigTag, &conf)
err := accounts.NewDB(b.appDB).GetConfig(accounts.NodeConfigTag, &conf)
if err != nil {
return nil, err
}
@ -281,7 +289,25 @@ func (b *StatusBackend) subscriptionService() gethnode.ServiceConstructor {
func (b *StatusBackend) accountsService() gethnode.ServiceConstructor {
return func(*gethnode.ServiceContext) (gethnode.Service, error) {
return accountssvc.NewService(b.accountsDB, b.multiaccountsDB, b.AccountManager()), nil
return accountssvc.NewService(accounts.NewDB(b.appDB), b.multiaccountsDB, b.accountManager), nil
}
}
func (b *StatusBackend) browsersService() gethnode.ServiceConstructor {
return func(*gethnode.ServiceContext) (gethnode.Service, error) {
return browsers.NewService(browsers.NewDB(b.appDB)), nil
}
}
func (b *StatusBackend) permissionsService() gethnode.ServiceConstructor {
return func(*gethnode.ServiceContext) (gethnode.Service, error) {
return permissions.NewService(permissions.NewDB(b.appDB)), nil
}
}
func (b *StatusBackend) walletService() gethnode.ServiceConstructor {
return func(*gethnode.ServiceContext) (gethnode.Service, error) {
return wallet.NewService(wallet.NewDB(b.appDB)), nil
}
}
@ -299,7 +325,10 @@ func (b *StatusBackend) startNode(config *params.NodeConfig) (err error) {
services := []gethnode.ServiceConstructor{}
services = appendIf(config.UpstreamConfig.Enabled, services, b.rpcFiltersService())
services = append(services, b.subscriptionService())
services = appendIf(b.accountsDB != nil, services, b.accountsService())
services = appendIf(b.appDB != nil && b.multiaccountsDB != nil, services, b.accountsService())
services = appendIf(config.BrowsersConfig.Enabled, services, b.browsersService())
services = appendIf(config.PermissionsConfig.Enabled, services, b.permissionsService())
services = appendIf(config.WalletConfig.Enabled, services, b.walletService())
manager := b.accountManager.GetManager()
if manager == nil {
@ -645,7 +674,7 @@ func (b *StatusBackend) Logout() error {
if err != nil {
return err
}
err = b.stopAccountsDB()
err = b.closeAppDB()
if err != nil {
return err
}
@ -680,28 +709,17 @@ func (b *StatusBackend) cleanupServices() error {
return err
}
}
if b.statusNode.Config().BrowsersConfig.Enabled {
svc, err := b.statusNode.BrowsersService()
switch err {
case node.ErrServiceUnknown:
case nil:
err = svc.StopDatabase()
if err != nil {
return err
}
default:
return err
}
}
return nil
}
func (b *StatusBackend) stopAccountsDB() error {
if b.accountsDB != nil {
err := b.accountsDB.Close()
b.accountsDB = nil
return err
func (b *StatusBackend) closeAppDB() error {
if b.appDB != nil {
err := b.appDB.Close()
if err != nil {
return err
}
b.appDB = nil
return nil
}
return nil
}
@ -768,18 +786,7 @@ func (b *StatusBackend) SelectAccount(loginParams account.LoginParams) error {
return err
}
}
err = b.startWallet(loginParams.Password)
if err != nil {
return err
}
err = b.startBrowsers(loginParams.Password)
if err != nil {
return err
}
return b.startPermissions(loginParams.Password)
return b.startWallet(loginParams.Password)
}
func (b *StatusBackend) startWallet(password string) error {
@ -801,47 +808,12 @@ func (b *StatusBackend) startWallet(password string) error {
allAddresses := make([]common.Address, len(watchAddresses)+1)
allAddresses[0] = mainAccountAddress
copy(allAddresses[1:], watchAddresses)
path := path.Join(b.statusNode.Config().DataDir, fmt.Sprintf("wallet-%x.sql", mainAccountAddress))
return wallet.StartReactor(path, password,
return wallet.StartReactor(
b.statusNode.RPCClient().Ethclient(),
allAddresses,
new(big.Int).SetUint64(b.statusNode.Config().NetworkID))
}
func (b *StatusBackend) startBrowsers(password string) error {
if !b.statusNode.Config().BrowsersConfig.Enabled {
return nil
}
svc, err := b.statusNode.BrowsersService()
if err != nil {
return err
}
mainAccountAddress, err := b.accountManager.MainAccountAddress()
if err != nil {
return err
}
path := path.Join(b.statusNode.Config().DataDir, fmt.Sprintf("browsers-%x.sql", mainAccountAddress))
return svc.StartDatabase(path, password)
}
func (b *StatusBackend) startPermissions(password string) error {
if !b.statusNode.Config().PermissionsConfig.Enabled {
return nil
}
svc, err := b.statusNode.PermissionsService()
if err != nil {
return err
}
mainAccountAddress, err := b.accountManager.MainAccountAddress()
if err != nil {
return err
}
path := path.Join(b.statusNode.Config().DataDir, fmt.Sprintf("permissions-%x.sql", mainAccountAddress))
return svc.StartDatabase(path, password)
}
// SendDataNotification sends data push notifications to users.
// dataPayloadJSON is a JSON string that looks like this:
// {

21
appdatabase/database.go Normal file
View file

@ -0,0 +1,21 @@
package appdatabase
import (
"database/sql"
"github.com/status-im/status-go/appdatabase/migrations"
"github.com/status-im/status-go/sqlite"
)
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string) (*sql.DB, error) {
db, err := sqlite.OpenDB(path, password)
if err != nil {
return nil, err
}
err = migrations.Migrate(db)
if err != nil {
return nil, err
}
return db, nil
}

View file

@ -0,0 +1,127 @@
package migrations
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var __0001_app_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x28\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x42\x12\x4c\x4c\x4e\xce\x2f\xcd\x2b\x41\x15\x4c\x2a\xca\x2f\x2f\x4e\x2d\xc2\x2e\x18\x9f\x91\x59\x5c\x92\x5f\x54\x89\x22\x99\x92\x58\x50\x80\xaa\xbc\x20\xb5\x28\x37\xb3\xb8\x38\x33\x3f\x0f\x55\xbc\xa4\x28\x31\xaf\x38\x0d\xc3\xf0\x9c\xfc\xe4\x6c\xec\x2e\x8b\x2f\xc9\x8f\x87\x49\x03\x02\x00\x00\xff\xff\xe3\xa7\x2d\xc9\xce\x00\x00\x00")
func _0001_app_down_sql() ([]byte, error) {
return bindata_read(
__0001_app_down_sql,
"0001_app.down.sql",
)
}
var __0001_app_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x54\x4d\x73\x9b\x30\x14\xbc\xeb\x57\xbc\xa3\x3d\xc3\x3f\xc8\x09\xdb\xb2\xa3\x29\x15\x2d\x88\x26\x39\x31\x32\x28\x36\x13\xbe\x8a\x44\x13\xff\xfb\x8e\x40\xe2\x23\xa1\xa4\xed\x0d\x49\xef\xad\x76\xf7\x69\xd9\x07\xd8\x65\x18\x98\xbb\xf3\x30\x90\x23\x50\x9f\x01\x7e\x24\x21\x0b\x41\x0a\xa5\xb2\xf2\x22\x61\x83\xd4\xad\x16\xf0\xc3\x0d\xf6\xf7\x6e\x00\xdf\x02\xf2\xd5\x0d\x9e\xe0\x0b\x7e\x72\xd0\x2f\x9e\xb7\x02\x76\x9e\xbf\x43\x5b\x78\x20\xec\xde\x8f\x18\x04\xfe\x03\x39\xdc\x21\xb4\x02\xce\x93\xa4\x6a\x4b\xa5\xc1\x79\x9a\x36\x42\xca\x65\xfc\x57\x9e\xe7\x42\xc1\xce\xf7\x3d\xec\x52\x07\x25\x57\x3e\x59\x75\xbc\x18\x7e\x64\x0e\x92\xaa\x6a\xf8\xc5\xae\xea\xf6\xfc\x22\x6e\x1d\x2f\x07\xd5\x5c\x5d\xcd\x7e\xc9\x0b\x5b\x92\x54\x79\xd5\x74\xdf\x7f\x66\x1e\x51\xf2\x3d\xc2\x40\xe8\x01\x3f\x42\x5b\x66\x3f\x5b\x11\xf7\x8c\x62\xcb\xda\xa7\x13\x2d\xfd\xd9\x16\x1e\xee\x71\x80\x87\xe5\xdd\x1a\x9c\x16\xb4\x0c\xa6\x4f\x06\xa8\x6e\xb1\x6e\xe9\xb9\xa9\x5e\xa5\x68\xb4\xa5\x59\xda\x09\x9b\x5b\x39\x68\xef\x9a\x68\xe4\x79\x0e\x52\x59\x21\xa4\xe2\x45\x0d\x51\x78\x22\x27\x8a\x0f\xb0\x23\x27\x42\x99\x83\x52\x5e\xd7\xd6\x69\x38\xe0\xa3\x1b\x79\x0c\x9e\x79\x2e\x85\x83\xae\x99\xb6\xfb\x46\xca\x54\xbc\x41\x44\xc3\xbe\x93\xd0\x15\x2b\xd7\x18\xc7\x06\x0f\x36\xc8\x6c\xc5\x56\xc1\x48\xd5\xd6\xf4\xd3\x3b\xfa\x01\x26\x27\xaa\x95\x6d\xc6\x9e\x2d\x04\xf8\x88\x03\x4c\xf7\x78\x44\xdf\xe8\x7d\x5f\x6b\xf0\x30\xc3\xb0\x77\xc3\xbd\x7b\xc0\xe8\x13\x37\xb5\x7c\x6d\xe5\xe8\xda\xc4\xcc\x7f\x93\x59\x8b\xa6\xc8\xa4\xcc\xaa\x52\x03\x6a\xe0\x78\x69\x16\x63\xd9\xfb\x93\xa9\xd8\xa1\x7d\xa6\xb5\x63\xbb\xe9\xb7\x97\xa5\xae\x11\x54\x0d\x2f\xe5\x73\xff\x74\xae\x5c\x5e\x87\x28\xf6\x0f\xd6\xf9\x10\xd1\x91\xda\x39\x7f\x89\x67\x2d\x93\xb7\xf5\x66\xf2\x27\x45\x99\x8a\x66\xa1\xa2\x11\x89\xc8\x6a\x65\xca\xf2\xea\x62\xbe\x66\xbf\x9b\x65\x1b\xec\xbd\xf3\x89\xe7\x55\xf2\x22\x37\xfd\xfe\x07\x1b\x1c\xb4\xf7\x69\xc8\x02\x97\x50\x66\xd3\x67\x95\xc7\x55\xd9\xc1\x0d\x49\x34\x51\xed\xb0\x1c\xb3\xb9\xfd\xec\xcd\xf4\xf7\xbf\x37\x71\x1e\xc2\xb6\x38\x8b\xc6\x84\xcc\xde\xb2\x98\x47\x9b\x2a\x53\x3a\x09\x82\xe0\x69\x17\xcc\x21\x95\x47\xd7\x0b\xf1\xff\xfd\x7f\x63\x55\xc5\x03\xed\xf5\x31\xcf\xa9\x8f\x67\xf2\x56\x26\xd0\xfd\x32\xde\x0f\xa8\xef\x58\x1a\x91\x3d\xf9\xab\x21\x15\xbc\xae\xb3\xf2\xa2\x67\x64\x18\xf6\x94\x2d\x23\x3b\x2b\x73\xe8\x4c\xae\xd6\x13\xfb\x1d\x00\x00\xff\xff\xee\x99\x61\xca\xe3\x06\x00\x00")
func _0001_app_up_sql() ([]byte, error) {
return bindata_read(
__0001_app_up_sql,
"0001_app.up.sql",
)
}
var _doc_go = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func doc_go() ([]byte, error) {
return bindata_read(
_doc_go,
"doc.go",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"0001_app.down.sql": _0001_app_down_sql,
"0001_app.up.sql": _0001_app_up_sql,
"doc.go": doc_go,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"0001_app.down.sql": &_bintree_t{_0001_app_down_sql, map[string]*_bintree_t{
}},
"0001_app.up.sql": &_bintree_t{_0001_app_up_sql, map[string]*_bintree_t{
}},
"doc.go": &_bintree_t{doc_go, map[string]*_bintree_t{
}},
}}

View file

@ -0,0 +1,9 @@
DROP TABLE settings;
DROP TABLE accounts;
DROP TABLE browsers;
DROP TABLE browsers_history;
DROP TABLE dapps;
DROP TABLE permissions;
DROP TABLE transfers;
DROP TABLE blocks;
DROP TABLE accounts_to_blocks;

View file

@ -0,0 +1,72 @@
CREATE TABLE IF NOT EXISTS settings (
type VARCHAR PRIMARY KEY,
value BLOB
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS accounts (
address VARCHAR PRIMARY KEY,
wallet BOOLEAN,
chat BOOLEAN,
type TEXT,
storage TEXT,
pubkey BLOB,
path TEXT,
name TEXT,
color TEXT
) WITHOUT ROWID;
CREATE UNIQUE INDEX unique_wallet_address ON accounts (wallet) WHERE (wallet);
CREATE UNIQUE INDEX unique_chat_address ON accounts (chat) WHERE (chat);
CREATE TABLE IF NOT EXISTS browsers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
timestamp USGIGNED BIGINT,
dapp BOOLEAN DEFAULT false,
historyIndex UNSIGNED INT
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS browsers_history (
browser_id TEXT NOT NULL,
history TEXT,
FOREIGN KEY(browser_id) REFERENCES browsers(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS dapps (
name TEXT PRIMARY KEY
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS permissions (
dapp_name TEXT NOT NULL,
permission TEXT NOT NULL,
FOREIGN KEY(dapp_name) REFERENCES dapps(name) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS transfers (
hash VARCHAR UNIQUE,
address VARCHAR NOT NULL,
blk_hash VARCHAR NOT NULL,
tx BLOB,
sender VARCHAR NOT NULL,
receipt BLOB,
log BLOB,
type VARCHAR NOT NULL,
FOREIGN KEY(blk_hash) REFERENCES blocks(hash) ON DELETE CASCADE,
CONSTRAINT unique_transfer_on_hash_address UNIQUE (hash,address)
);
CREATE TABLE IF NOT EXISTS blocks (
hash VARCHAR PRIMARY KEY,
number BIGINT UNIQUE NOT NULL,
timestamp UNSIGNED BIGINT NOT NULL,
head BOOL DEFAULT FALSE
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS accounts_to_blocks (
address VARCHAR NOT NULL,
blk_number BIGINT NOT NULL,
sync INT,
FOREIGN KEY(blk_number) REFERENCES blocks(number) ON DELETE CASCADE,
CONSTRAINT unique_mapping_on_address_block_number UNIQUE (address,blk_number)
);

View file

@ -6,7 +6,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/status-im/status-go/multiaccounts/accounts/migrations"
"github.com/status-im/status-go/sqlite"
)
@ -34,6 +33,10 @@ type Account struct {
Color string `json:"color"`
}
func NewDB(db *sql.DB) *Database {
return &Database{db: db}
}
// Database sql wrapper for operations with browser objects.
type Database struct {
db *sql.DB
@ -44,19 +47,6 @@ func (db Database) Close() error {
return db.db.Close()
}
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string) (*Database, error) {
db, err := sqlite.OpenDB(path, password)
if err != nil {
return nil, err
}
err = migrations.Migrate(db)
if err != nil {
return nil, err
}
return &Database{db: db}, nil
}
func (db *Database) SaveConfig(typ string, value interface{}) error {
_, err := db.db.Exec("INSERT OR REPLACE INTO settings (type, value) VALUES (?, ?)", typ, &sqlite.JSONBlob{value})
return err

View file

@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/status-im/status-go/appdatabase"
"github.com/status-im/status-go/params"
"github.com/stretchr/testify/require"
)
@ -16,9 +17,9 @@ import (
func setupTestDB(t *testing.T) (*Database, func()) {
tmpfile, err := ioutil.TempFile("", "settings-tests-")
require.NoError(t, err)
db, err := InitializeDB(tmpfile.Name(), "settings-tests")
db, err := appdatabase.InitializeDB(tmpfile.Name(), "settings-tests")
require.NoError(t, err)
return db, func() {
return NewDB(db), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}

View file

@ -1,127 +0,0 @@
package migrations
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var __0001_settings_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x28\x4e\x2d\x29\xc9\xcc\x4b\x2f\xb6\xe6\x42\x12\x4c\x4c\x4e\xce\x2f\xcd\x2b\x29\xb6\xe6\x02\x04\x00\x00\xff\xff\x2c\x0a\x12\xf1\x2a\x00\x00\x00")
func _0001_settings_down_sql() ([]byte, error) {
return bindata_read(
__0001_settings_down_sql,
"0001_settings.down.sql",
)
}
var __0001_settings_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8f\xb1\x4e\xc3\x30\x10\x40\xf7\xfb\x8a\x1b\xa9\x94\x3f\xc8\xe4\xb4\x87\x62\x11\x6c\x70\x1d\x92\x4e\x95\x49\xad\xb6\x22\x24\x21\xb6\x41\xfd\x7b\x14\x97\x54\x1d\x4a\x37\x3f\xdf\xe9\xe9\xdd\x52\x11\xd3\x84\x9a\x65\x05\x21\x7f\x44\x21\x35\x52\xcd\xd7\x7a\x8d\xce\x7a\x7f\xec\xf6\x0e\x1f\xc0\x9f\x06\x8b\x6f\x4c\x2d\x73\xa6\xf0\x45\xf1\x67\xa6\x36\xf8\x44\x9b\x04\xbe\x4d\x1b\x2c\x66\x85\xcc\x60\x81\x15\xd7\xb9\x2c\x35\x2a\x59\xf1\x55\x0a\x70\x47\x6e\x9a\xa6\x0f\x9d\x9f\xe4\x66\xb7\x1b\xad\x73\xb7\xfd\x3f\xa6\x6d\xad\xc7\x4c\xca\x82\x98\x48\xa0\x39\x98\x2b\x8a\x5d\x9a\x6a\x9d\x80\xf3\xfd\x68\xf6\x33\x0d\xe1\xfd\xc3\x9e\x62\x57\x02\x83\xf1\x87\xbf\xff\xce\x7c\xce\x2b\x4d\xdf\xf6\x63\x7c\xff\x5f\x5e\x0a\xfe\x5a\x12\x72\xb1\xa2\x1a\x43\x77\xfc\x0a\x76\x7b\x2e\xda\xce\xd5\x52\x5c\xdd\x72\x9e\x2d\xb0\xca\x49\xd1\x05\xd3\x7b\xba\xe9\xa0\xdb\xb2\x69\x72\x51\x45\x48\xe1\x37\x00\x00\xff\xff\xfe\xcd\xfe\xc2\xaf\x01\x00\x00")
func _0001_settings_up_sql() ([]byte, error) {
return bindata_read(
__0001_settings_up_sql,
"0001_settings.up.sql",
)
}
var _doc_go = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func doc_go() ([]byte, error) {
return bindata_read(
_doc_go,
"doc.go",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"0001_settings.down.sql": _0001_settings_down_sql,
"0001_settings.up.sql": _0001_settings_up_sql,
"doc.go": doc_go,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"0001_settings.down.sql": &_bintree_t{_0001_settings_down_sql, map[string]*_bintree_t{
}},
"0001_settings.up.sql": &_bintree_t{_0001_settings_up_sql, map[string]*_bintree_t{
}},
"doc.go": &_bintree_t{doc_go, map[string]*_bintree_t{
}},
}}

View file

@ -1,2 +0,0 @@
DROP TABLE settings;
DROP TABLE accounts;

View file

@ -1,19 +0,0 @@
CREATE TABLE IF NOT EXISTS settings (
type VARCHAR PRIMARY KEY,
value BLOB
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS accounts (
address VARCHAR PRIMARY KEY,
wallet BOOLEAN,
chat BOOLEAN,
type TEXT,
storage TEXT,
pubkey BLOB,
path TEXT,
name TEXT,
color TEXT
) WITHOUT ROWID;
CREATE UNIQUE INDEX unique_wallet_address ON accounts (wallet) WHERE (wallet);
CREATE UNIQUE INDEX unique_chat_address ON accounts (chat) WHERE (chat);

View file

@ -25,14 +25,11 @@ import (
"github.com/ethereum/go-ethereum/p2p/nat"
"github.com/status-im/status-go/mailserver"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/browsers"
"github.com/status-im/status-go/services/incentivisation"
"github.com/status-im/status-go/services/peer"
"github.com/status-im/status-go/services/permissions"
"github.com/status-im/status-go/services/personal"
"github.com/status-im/status-go/services/shhext"
"github.com/status-im/status-go/services/status"
"github.com/status-im/status-go/services/wallet"
"github.com/status-im/status-go/static"
"github.com/status-im/status-go/timesource"
whisper "github.com/status-im/whisper/whisperv6"
@ -49,9 +46,6 @@ var (
ErrStatusServiceRegistrationFailure = errors.New("failed to register the Status service")
ErrPeerServiceRegistrationFailure = errors.New("failed to register the Peer service")
ErrIncentivisationServiceRegistrationFailure = errors.New("failed to register the Incentivisation service")
ErrWalletServiceRegistrationFailure = errors.New("failed to register the Wallet service")
ErrBrowsersServiceRegistrationFailure = errors.New("failed to register the Browsers service")
ErrPermissionsServiceRegistrationFailure = errors.New("failed to register the Permissions service")
)
// All general log messages in this package should be routed through this logger.
@ -140,19 +134,6 @@ func activateNodeServices(stack *node.Node, config *params.NodeConfig, db *level
if err := activatePeerService(stack); err != nil {
return fmt.Errorf("%v: %v", ErrPeerServiceRegistrationFailure, err)
}
if err := activateWalletService(stack, config.WalletConfig); err != nil {
return fmt.Errorf("%v: %v", ErrWalletServiceRegistrationFailure, err)
}
if err := activateBrowsersService(stack, config.BrowsersConfig); err != nil {
return fmt.Errorf("%v: %v", ErrBrowsersServiceRegistrationFailure, err)
}
if err := activatePermissionsService(stack, config.PermissionsConfig); err != nil {
return fmt.Errorf("%v: %v", ErrPermissionsServiceRegistrationFailure, err)
}
return nil
}
@ -309,36 +290,6 @@ func activatePeerService(stack *node.Node) error {
})
}
func activateWalletService(stack *node.Node, config params.WalletConfig) error {
if !config.Enabled {
logger.Info("wallet service is disabled")
return nil
}
return stack.Register(func(*node.ServiceContext) (node.Service, error) {
return wallet.NewService(), nil
})
}
func activateBrowsersService(stack *node.Node, config params.BrowsersConfig) error {
if !config.Enabled {
logger.Info("browsers service is disabled")
return nil
}
return stack.Register(func(*node.ServiceContext) (node.Service, error) {
return browsers.NewService(), nil
})
}
func activatePermissionsService(stack *node.Node, config params.PermissionsConfig) error {
if !config.Enabled {
logger.Info("dapps permissions service is disabled")
return nil
}
return stack.Register(func(*node.ServiceContext) (node.Service, error) {
return permissions.NewService(), nil
})
}
func registerMailServer(whisperService *whisper.Whisper, config *params.WhisperConfig) (err error) {
var mailServer mailserver.WMailServer
whisperService.RegisterServer(&mailServer)

View file

@ -2,40 +2,25 @@ package browsers
import (
"context"
"errors"
)
var (
// ErrServiceNotInitialized returned when wallet is not initialized/started,.
ErrServiceNotInitialized = errors.New("browsers service is not initialized")
)
func NewAPI(s *Service) *API {
return &API{s}
func NewAPI(db *Database) *API {
return &API{db: db}
}
// API is class with methods available over RPC.
type API struct {
s *Service
db *Database
}
func (api *API) AddBrowser(ctx context.Context, browser Browser) error {
if api.s.db == nil {
return ErrServiceNotInitialized
}
return api.s.db.InsertBrowser(browser)
return api.db.InsertBrowser(browser)
}
func (api *API) GetBrowsers(ctx context.Context) ([]*Browser, error) {
if api.s.db == nil {
return nil, ErrServiceNotInitialized
}
return api.s.db.GetBrowsers()
return api.db.GetBrowsers()
}
func (api *API) DeleteBrowser(ctx context.Context, id string) error {
if api.s.db == nil {
return ErrServiceNotInitialized
}
return api.s.db.DeleteBrowser(id)
return api.db.DeleteBrowser(id)
}

View file

@ -7,15 +7,16 @@ import (
"sort"
"testing"
"github.com/status-im/status-go/appdatabase"
"github.com/stretchr/testify/require"
)
func setupTestDB(t *testing.T) (*Database, func()) {
tmpfile, err := ioutil.TempFile("", "browsers-tests-")
require.NoError(t, err)
db, err := InitializeDB(tmpfile.Name(), "browsers-tests")
db, err := appdatabase.InitializeDB(tmpfile.Name(), "browsers-tests")
require.NoError(t, err)
return db, func() {
return NewDB(db), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}
@ -23,7 +24,7 @@ func setupTestDB(t *testing.T) (*Database, func()) {
func setupTestAPI(t *testing.T) (*API, func()) {
db, cancel := setupTestDB(t)
return &API{s: &Service{db: db}}, cancel
return &API{db: db}, cancel
}
func TestBrowsersOrderedNewestFirst(t *testing.T) {

View file

@ -2,9 +2,6 @@ package browsers
import (
"database/sql"
"github.com/status-im/status-go/services/browsers/migrations"
"github.com/status-im/status-go/sqlite"
)
// Database sql wrapper for operations with browser objects.
@ -17,17 +14,8 @@ func (db Database) Close() error {
return db.db.Close()
}
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string) (*Database, error) {
db, err := sqlite.OpenDB(path, password)
if err != nil {
return nil, err
}
err = migrations.Migrate(db)
if err != nil {
return nil, err
}
return &Database{db: db}, nil
func NewDB(db *sql.DB) *Database {
return &Database{db: db}
}
type Browser struct {

View file

@ -1,127 +0,0 @@
package migrations
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var __0001_browsers_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x48\x2a\xca\x2f\x2f\x4e\x2d\x2a\xb6\xe6\xc2\x22\x18\x9f\x91\x59\x5c\x92\x5f\x54\x69\xcd\x05\x08\x00\x00\xff\xff\x5b\xe2\x78\xbe\x32\x00\x00\x00")
func _0001_browsers_down_sql() ([]byte, error) {
return bindata_read(
__0001_browsers_down_sql,
"0001_browsers.down.sql",
)
}
var __0001_browsers_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x8f\xc1\x6a\x83\x40\x10\x86\xef\xf3\x14\xff\x51\xc1\x37\xe8\x69\xd5\xd1\x0e\xdd\xee\x96\x75\x24\xc9\x29\x58\xb4\x54\xa8\x89\xa8\xd0\xf6\xed\xcb\x92\x04\xaf\xbd\x7e\xcc\x37\xfc\x5f\x11\xd8\x28\x43\x4d\x6e\x19\x52\xc1\x79\x05\x1f\xa5\xd1\x06\xef\xcb\xf5\x7b\x1d\x96\x15\x09\x8d\x3d\x94\x8f\x8a\xb7\x20\xaf\x26\x9c\xf0\xc2\xa7\x8c\x2e\xdd\x34\xdc\x70\x94\x5c\x6b\x6d\x46\xdb\x38\x0d\xeb\xd6\x4d\x33\xda\xa6\x96\xda\x71\x89\x5c\x6a\x71\x9a\x51\xdf\xcd\x33\x72\xef\x2d\x1b\x87\x92\x2b\xd3\x5a\xc5\x47\xf7\xb5\x0e\x19\x7d\x8e\xeb\x76\x5d\x7e\xe5\xd2\x0f\x3f\x68\x5d\x73\x33\xc5\x29\xa5\x38\x88\x3e\xfb\x56\x11\xfc\x41\xca\x27\xa2\x7f\x2c\x3e\xdf\xff\x21\xa1\x3b\x3a\x3f\x0a\xf6\xa9\x8f\x9b\x88\x33\xaa\x7c\x60\xa9\x5d\x2c\x4b\x76\x27\x45\xe0\x8a\x03\xbb\x82\xf7\xef\x49\xe4\x3e\x36\x58\x56\x46\x61\x9a\xc2\x94\x4c\x29\xfd\x05\x00\x00\xff\xff\x69\xa0\xeb\xdb\x4c\x01\x00\x00")
func _0001_browsers_up_sql() ([]byte, error) {
return bindata_read(
__0001_browsers_up_sql,
"0001_browsers.up.sql",
)
}
var _doc_go = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func doc_go() ([]byte, error) {
return bindata_read(
_doc_go,
"doc.go",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"0001_browsers.down.sql": _0001_browsers_down_sql,
"0001_browsers.up.sql": _0001_browsers_up_sql,
"doc.go": doc_go,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"0001_browsers.down.sql": &_bintree_t{_0001_browsers_down_sql, map[string]*_bintree_t{
}},
"0001_browsers.up.sql": &_bintree_t{_0001_browsers_up_sql, map[string]*_bintree_t{
}},
"doc.go": &_bintree_t{doc_go, map[string]*_bintree_t{
}},
}}

View file

@ -1,18 +0,0 @@
package migrations
import (
"database/sql"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
"github.com/status-im/status-go/sqlite"
)
// Migrate applies migrations.
func Migrate(db *sql.DB) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
))
}

View file

@ -1,2 +0,0 @@
DROP TABLE browsers;
DROP TABLE browsers_history;

View file

@ -1,13 +0,0 @@
CREATE TABLE IF NOT EXISTS browsers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
timestamp USGIGNED BIGINT,
dapp BOOLEAN DEFAULT false,
historyIndex UNSIGNED INT
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS browsers_history (
browser_id TEXT NOT NULL,
history TEXT,
FOREIGN KEY(browser_id) REFERENCES browsers(id) ON DELETE CASCADE
)

View file

@ -1,3 +0,0 @@
package sql
//go:generate go-bindata -pkg migrations -o ../bindata.go ./

View file

@ -1,20 +1,17 @@
package browsers
import (
"sync"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
)
// NewService initializes service instance.
func NewService() *Service {
return &Service{}
func NewService(db *Database) *Service {
return &Service{db: db}
}
// Service is a browsers service.
type Service struct {
mu sync.Mutex
db *Database
}
@ -23,26 +20,9 @@ func (s *Service) Start(*p2p.Server) error {
return nil
}
// Start database after dbpath and password will become known.
func (s *Service) StartDatabase(dbpath, password string) (err error) {
s.mu.Lock()
defer s.mu.Unlock()
s.db, err = InitializeDB(dbpath, password)
return err
}
func (s *Service) StopDatabase() error {
s.mu.Lock()
defer s.mu.Unlock()
if s.db != nil {
return s.db.Close()
}
return nil
}
// Stop a service.
func (s *Service) Stop() error {
return s.StopDatabase()
return nil
}
// APIs returns list of available RPC APIs.
@ -51,7 +31,7 @@ func (s *Service) APIs() []rpc.API {
{
Namespace: "browsers",
Version: "0.1.0",
Service: NewAPI(s),
Service: NewAPI(s.db),
Public: true,
},
}

View file

@ -2,40 +2,25 @@ package permissions
import (
"context"
"errors"
)
var (
// ErrServiceNotInitialized returned when permissions is not initialized/started,.
ErrServiceNotInitialized = errors.New("permissions service is not initialized")
)
func NewAPI(s *Service) *API {
return &API{s}
func NewAPI(db *Database) *API {
return &API{db}
}
// API is class with methods available over RPC.
type API struct {
s *Service
db *Database
}
func (api *API) AddDappPermissions(ctx context.Context, perms DappPermissions) error {
if api.s.db == nil {
return ErrServiceNotInitialized
}
return api.s.db.AddPermissions(perms)
return api.db.AddPermissions(perms)
}
func (api *API) GetDappPermissions(ctx context.Context) ([]DappPermissions, error) {
if api.s.db == nil {
return nil, ErrServiceNotInitialized
}
return api.s.db.GetPermissions()
return api.db.GetPermissions()
}
func (api *API) DeleteDappPermissions(ctx context.Context, name string) error {
if api.s.db == nil {
return ErrServiceNotInitialized
}
return api.s.db.DeletePermission(name)
return api.db.DeletePermission(name)
}

View file

@ -9,15 +9,16 @@ import (
"sort"
"testing"
"github.com/status-im/status-go/appdatabase"
"github.com/stretchr/testify/require"
)
func setupTestDB(t *testing.T) (*Database, func()) {
tmpfile, err := ioutil.TempFile("", "perm-tests-")
require.NoError(t, err)
db, err := InitializeDB(tmpfile.Name(), "perm-tests")
db, err := appdatabase.InitializeDB(tmpfile.Name(), "perm-tests")
require.NoError(t, err)
return db, func() {
return NewDB(db), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}
@ -25,7 +26,7 @@ func setupTestDB(t *testing.T) (*Database, func()) {
func setupTestAPI(t *testing.T) (*API, func()) {
db, cancel := setupTestDB(t)
return &API{s: &Service{db: db}}, cancel
return &API{db: db}, cancel
}
func TestDappPermissionsStored(t *testing.T) {

View file

@ -2,9 +2,6 @@ package permissions
import (
"database/sql"
"github.com/status-im/status-go/services/permissions/migrations"
"github.com/status-im/status-go/sqlite"
)
// Database sql wrapper for operations with browser objects.
@ -17,17 +14,8 @@ func (db Database) Close() error {
return db.db.Close()
}
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string) (*Database, error) {
db, err := sqlite.OpenDB(path, password)
if err != nil {
return nil, err
}
err = migrations.Migrate(db)
if err != nil {
return nil, err
}
return &Database{db: db}, nil
func NewDB(db *sql.DB) *Database {
return &Database{db: db}
}
type DappPermissions struct {

View file

@ -1,127 +0,0 @@
package migrations
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var __0001_permissions_down_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x48\x49\x2c\x28\x28\xb6\xe6\x42\x12\x29\x48\x2d\xca\xcd\x2c\x2e\xce\xcc\xcf\x2b\xb6\xe6\x02\x04\x00\x00\xff\xff\xeb\x21\xe7\xd0\x2a\x00\x00\x00")
func _0001_permissions_down_sql() ([]byte, error) {
return bindata_read(
__0001_permissions_down_sql,
"0001_permissions.down.sql",
)
}
var __0001_permissions_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\xce\x31\x0f\x82\x30\x10\x05\xe0\xbd\xbf\xe2\x8d\x90\xf8\x0f\x9c\x6a\x79\x68\x63\x6d\x4d\x39\x02\x4c\x86\x44\x06\x06\x90\xc8\xff\x4f\x4c\xa3\x91\xc4\xc1\xf5\xee\xdd\x77\xcf\x44\x6a\x21\x44\x1f\x1c\x61\x4b\xf8\x20\x60\x6b\x2b\xa9\x70\xef\x97\x65\x45\xa6\xe6\x7e\x1a\x20\x6c\x05\xd7\x68\x2f\x3a\x76\x38\xb3\x53\x39\x1a\x2b\xa7\x50\x0b\x62\x68\x6c\xb1\x57\xea\x0f\xb5\x0c\xcf\x69\x5c\xd7\xf1\x31\x27\x30\xc1\xb7\x4d\x4d\x39\x5f\x3b\xb7\x53\x5b\xec\x77\x53\x86\x48\x7b\xf4\xe9\x73\xf6\x3d\xcf\x11\x59\x32\xd2\x1b\x7e\xda\x66\xef\x71\xf0\x28\xe8\x28\x84\xd1\x95\xd1\x05\x55\xfe\x0a\x00\x00\xff\xff\x9e\x9a\xc6\xf0\xe8\x00\x00\x00")
func _0001_permissions_up_sql() ([]byte, error) {
return bindata_read(
__0001_permissions_up_sql,
"0001_permissions.up.sql",
)
}
var _doc_go = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func doc_go() ([]byte, error) {
return bindata_read(
_doc_go,
"doc.go",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"0001_permissions.down.sql": _0001_permissions_down_sql,
"0001_permissions.up.sql": _0001_permissions_up_sql,
"doc.go": doc_go,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"0001_permissions.down.sql": &_bintree_t{_0001_permissions_down_sql, map[string]*_bintree_t{
}},
"0001_permissions.up.sql": &_bintree_t{_0001_permissions_up_sql, map[string]*_bintree_t{
}},
"doc.go": &_bintree_t{doc_go, map[string]*_bintree_t{
}},
}}

View file

@ -1,18 +0,0 @@
package migrations
import (
"database/sql"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
"github.com/status-im/status-go/sqlite"
)
// Migrate applies migrations.
func Migrate(db *sql.DB) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
))
}

View file

@ -1,2 +0,0 @@
DROP TABLE dapps;
DROP TABLE permissions;

View file

@ -1,9 +0,0 @@
CREATE TABLE IF NOT EXISTS dapps (
name TEXT PRIMARY KEY
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS permissions (
dapp_name TEXT NOT NULL,
permission TEXT NOT NULL,
FOREIGN KEY(dapp_name) REFERENCES dapps(name) ON DELETE CASCADE
)

View file

@ -1,3 +0,0 @@
package sql
//go:generate go-bindata -pkg migrations -o ../bindata.go ./

View file

@ -1,19 +1,16 @@
package permissions
import (
"sync"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
)
// NewService initializes service instance.
func NewService() *Service {
return &Service{}
func NewService(db *Database) *Service {
return &Service{db: db}
}
type Service struct {
mu sync.Mutex
db *Database
}
@ -22,26 +19,9 @@ func (s *Service) Start(*p2p.Server) error {
return nil
}
// StartDatabase after dbpath and password will become known.
func (s *Service) StartDatabase(dbpath, password string) (err error) {
s.mu.Lock()
defer s.mu.Unlock()
s.db, err = InitializeDB(dbpath, password)
return err
}
func (s *Service) StopDatabase() error {
s.mu.Lock()
defer s.mu.Unlock()
if s.db != nil {
return s.db.Close()
}
return nil
}
// Stop a service.
func (s *Service) Stop() error {
return s.StopDatabase()
return nil
}
// APIs returns list of available RPC APIs.
@ -50,7 +30,7 @@ func (s *Service) APIs() []rpc.API {
{
Namespace: "permissions",
Version: "0.1.0",
Service: NewAPI(s),
Service: NewAPI(s.db),
Public: true,
},
}

View file

@ -10,8 +10,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/services/wallet/migrations"
"github.com/status-im/status-go/sqlite"
)
// DBHeader fields from header that are stored in database.
@ -46,19 +44,6 @@ const (
erc20Sync SyncOption = 2
)
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string) (*Database, error) {
db, err := sqlite.OpenDB(path, password)
if err != nil {
return nil, err
}
err = migrations.Migrate(db)
if err != nil {
return nil, err
}
return &Database{db: db}, nil
}
// SQLBigInt type for storing uint256 in the databse.
// FIXME(dshulyak) SQL big int is max 64 bits. Maybe store as bytes in big endian and hope
// that lexographical sorting will work.
@ -111,6 +96,10 @@ func (blob *JSONBlob) Value() (driver.Value, error) {
return json.Marshal(blob.data)
}
func NewDB(db *sql.DB) *Database {
return &Database{db}
}
// Database sql wrapper for operations with wallet objects.
type Database struct {
db *sql.DB

View file

@ -8,15 +8,16 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/appdatabase"
"github.com/stretchr/testify/require"
)
func setupTestDB(t *testing.T) (*Database, func()) {
tmpfile, err := ioutil.TempFile("", "wallet-tests-")
require.NoError(t, err)
db, err := InitializeDB(tmpfile.Name(), "wallet-tests")
db, err := appdatabase.InitializeDB(tmpfile.Name(), "wallet-tests")
require.NoError(t, err)
return db, func() {
return NewDB(db), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}

View file

@ -1,127 +0,0 @@
package migrations
import (
"bytes"
"compress/gzip"
"fmt"
"io"
"strings"
)
func bindata_read(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
_, err = io.Copy(&buf, gz)
gz.Close()
if err != nil {
return nil, fmt.Errorf("Read %q: %v", name, err)
}
return buf.Bytes(), nil
}
var __0001_transfers_down_db_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x28\x29\x4a\xcc\x2b\x4e\x4b\x2d\x2a\xb6\xe6\x42\x12\x4d\xca\xc9\x4f\xce\x46\x15\x4a\x4c\x4e\xce\x2f\xcd\x2b\x29\x8e\x2f\xc9\x8f\x87\x49\x03\x02\x00\x00\xff\xff\xe1\x80\x1c\xac\x48\x00\x00\x00")
func _0001_transfers_down_db_sql() ([]byte, error) {
return bindata_read(
__0001_transfers_down_db_sql,
"0001_transfers.down.db.sql",
)
}
var __0001_transfers_up_db_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x91\xcd\xae\x9b\x30\x10\x85\xf7\x7e\x8a\x59\x06\x89\x37\xe8\xca\xc0\x90\x58\x75\xed\xd6\x98\xa6\x59\x21\x02\x6e\x82\x12\x0c\xc5\x20\x35\x6f\x5f\x11\x20\x3f\xbd\x51\x74\x77\xd6\xcc\x19\x9f\x6f\xe6\x84\x0a\xa9\x46\xd0\x34\xe0\x08\x2c\x06\x21\x35\xe0\x2f\x96\xe8\x04\xfa\x2e\xb7\xee\xb7\xe9\x1c\xac\xc8\x31\x77\x47\xf8\x49\x55\xb8\xa1\x0a\x52\xc1\x7e\xa4\xe8\x93\xbc\x2c\x3b\xe3\xdc\xad\x3e\xce\x8a\x94\x73\x9f\xec\xcf\xa7\xec\x69\xe4\xde\xea\xff\x42\xc0\x65\xe0\x13\x67\x6c\x69\xba\x17\x8a\xce\x14\xa6\x6a\xfb\x59\x76\x6e\x0e\xf3\xab\xbf\xb4\xe6\x85\x3c\x96\x0a\xd9\x5a\xc0\x57\xdc\xad\x16\x5f\x0f\x14\xc6\xa8\x50\x84\x98\xc0\xfe\xdc\x14\x27\xb7\x9a\xea\x52\x40\x84\x1c\x35\x42\x48\x93\x90\x46\xe8\x93\x50\x8a\x44\x2b\xca\x84\x86\xc1\x56\x7f\x06\x93\x2d\x9b\x67\x8d\xbd\x7e\x97\x2d\x9b\x4e\x9b\xc3\xf5\x2f\x7f\x2e\x7a\xc4\xfb\x42\xc8\x9b\x3b\x4e\xfe\xff\x1f\xf1\xbb\x62\xdf\xa8\xda\x8d\xd8\x3e\xb1\x43\xbd\x37\x1d\x04\x6c\x3d\x52\xcc\x2e\x0f\x37\xab\x6a\xe3\xfa\xbc\x6e\x21\x15\x09\x5b\x0b\x8c\x16\xe9\x5d\x73\x34\x79\x09\x81\x94\x1c\x22\x8c\x69\xca\x35\xc4\x94\x27\x48\x3c\xd8\x32\xbd\x91\xa9\x06\x25\xb7\x2c\x7a\x8f\x9a\x17\x45\x33\xd8\xde\x65\x7d\x93\xdd\xb0\xdf\xc7\xfc\x8c\x7e\xef\xb9\x8b\x2d\x80\x09\xfd\x31\xa0\x69\xe2\x55\x44\x4b\xe7\x53\x21\xd5\x79\xdb\x56\xf6\x30\x66\x34\x13\x4e\xc8\x0b\xd1\x92\xd5\xdc\xf4\x1f\xac\xc7\xc4\xfe\x05\x00\x00\xff\xff\x69\x7c\xa5\x4c\xf9\x02\x00\x00")
func _0001_transfers_up_db_sql() ([]byte, error) {
return bindata_read(
__0001_transfers_up_db_sql,
"0001_transfers.up.db.sql",
)
}
var _doc_go = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00")
func doc_go() ([]byte, error) {
return bindata_read(
_doc_go,
"doc.go",
)
}
// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
cannonicalName := strings.Replace(name, "\\", "/", -1)
if f, ok := _bindata[cannonicalName]; ok {
return f()
}
return nil, fmt.Errorf("Asset %s not found", name)
}
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
for name := range _bindata {
names = append(names, name)
}
return names
}
// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() ([]byte, error){
"0001_transfers.down.db.sql": _0001_transfers_down_db_sql,
"0001_transfers.up.db.sql": _0001_transfers_up_db_sql,
"doc.go": doc_go,
}
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
// data/
// foo.txt
// img/
// a.png
// b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
cannonicalName := strings.Replace(name, "\\", "/", -1)
pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
}
}
if node.Func != nil {
return nil, fmt.Errorf("Asset %s not found", name)
}
rv := make([]string, 0, len(node.Children))
for name := range node.Children {
rv = append(rv, name)
}
return rv, nil
}
type _bintree_t struct {
Func func() ([]byte, error)
Children map[string]*_bintree_t
}
var _bintree = &_bintree_t{nil, map[string]*_bintree_t{
"0001_transfers.down.db.sql": &_bintree_t{_0001_transfers_down_db_sql, map[string]*_bintree_t{
}},
"0001_transfers.up.db.sql": &_bintree_t{_0001_transfers_up_db_sql, map[string]*_bintree_t{
}},
"doc.go": &_bintree_t{doc_go, map[string]*_bintree_t{
}},
}}

View file

@ -1,18 +0,0 @@
package migrations
import (
"database/sql"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
"github.com/status-im/status-go/sqlite"
)
// Migrate applies migrations.
func Migrate(db *sql.DB) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
))
}

View file

@ -1,3 +0,0 @@
DROP TABLE transfers;
DROP TABLE blocks;
DROP TABLE accounts_to_blocks;

View file

@ -1,27 +0,0 @@
CREATE TABLE IF NOT EXISTS transfers (
hash VARCHAR UNIQUE,
address VARCHAR NOT NULL,
blk_hash VARCHAR NOT NULL,
tx BLOB,
sender VARCHAR NOT NULL,
receipt BLOB,
log BLOB,
type VARCHAR NOT NULL,
FOREIGN KEY(blk_hash) REFERENCES blocks(hash) ON DELETE CASCADE,
CONSTRAINT unique_transfer_on_hash_address UNIQUE (hash,address)
);
CREATE TABLE IF NOT EXISTS blocks (
hash VARCHAR PRIMARY KEY,
number BIGINT UNIQUE NOT NULL,
timestamp UNSIGNED BIGINT NOT NULL,
head BOOL DEFAULT FALSE
) WITHOUT ROWID;
CREATE TABLE IF NOT EXISTS accounts_to_blocks (
address VARCHAR NOT NULL,
blk_number BIGINT NOT NULL,
sync INT,
FOREIGN KEY(blk_number) REFERENCES blocks(number) ON DELETE CASCADE,
CONSTRAINT unique_mapping_on_address_block_number UNIQUE (address,blk_number)
);

View file

@ -1,3 +0,0 @@
package sql
//go:generate go-bindata -pkg migrations -o ../bindata.go ./

View file

@ -12,9 +12,10 @@ import (
)
// NewService initializes service instance.
func NewService() *Service {
func NewService(db *Database) *Service {
feed := &event.Feed{}
return &Service{
db: db,
feed: feed,
signals: &SignalsTransmitter{publisher: feed},
}
@ -35,17 +36,12 @@ func (s *Service) Start(*p2p.Server) error {
}
// StartReactor separately because it requires known ethereum address, which will become available only after login.
func (s *Service) StartReactor(dbpath, password string, client *ethclient.Client, accounts []common.Address, chain *big.Int) error {
db, err := InitializeDB(dbpath, password)
func (s *Service) StartReactor(client *ethclient.Client, accounts []common.Address, chain *big.Int) error {
reactor := NewReactor(s.db, s.feed, client, accounts, chain)
err := reactor.Start()
if err != nil {
return err
}
reactor := NewReactor(db, s.feed, client, accounts, chain)
err = reactor.Start()
if err != nil {
return err
}
s.db = db
s.reactor = reactor
s.client = client
return nil
@ -57,10 +53,7 @@ func (s *Service) StopReactor() error {
return nil
}
s.reactor.Stop()
if s.db == nil {
return nil
}
return s.db.Close()
return nil
}
// Stop reactor, signals transmitter and close db.

View file

@ -11,6 +11,8 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/rpc"
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/params"
statusrpc "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/t/devtests/miner"
@ -56,7 +58,14 @@ func (s *DevNodeSuite) SetupTest() {
config.UpstreamConfig.URL = s.miner.IPCEndpoint()
s.backend = api.NewStatusBackend()
s.Require().NoError(s.backend.AccountManager().InitKeystore(config.KeyStoreDir))
s.Require().NoError(s.backend.StartNode(config))
_, err = s.backend.AccountManager().ImportAccount(s.DevAccount, "test")
s.Require().NoError(err)
s.backend.UpdateRootDataDir(s.dir)
s.Require().NoError(s.backend.OpenAccounts())
s.Require().NoError(s.backend.StartNodeWithAccountAndConfig(multiaccounts.Account{
Name: "main",
Address: s.DevAccountAddress,
}, "test", config, []accounts.Account{{Address: s.DevAccountAddress, Wallet: true, Chat: true}}))
s.Remote, err = s.miner.Attach()
s.Require().NoError(err)
s.Eth = ethclient.NewClient(s.Remote)
@ -70,7 +79,7 @@ func (s *DevNodeSuite) TearDownTest() {
s.miner = nil
}
if s.backend != nil {
s.Require().NoError(s.backend.StopNode())
s.Require().NoError(s.backend.Logout())
s.backend = nil
}
if len(s.dir) != 0 {

View file

@ -11,7 +11,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/services/wallet"
"github.com/status-im/status-go/t/utils"
"github.com/stretchr/testify/suite"
@ -23,43 +22,10 @@ func TestTransfersSuite(t *testing.T) {
type TransfersSuite struct {
DevNodeSuite
Password string
Info account.Info
Address common.Address
}
func (s *TransfersSuite) SelectAccount() {
loginParams := account.LoginParams{
ChatAddress: common.HexToAddress(s.Info.ChatAddress),
Password: s.Password,
MainAccount: common.HexToAddress(s.Info.WalletAddress),
}
s.Require().NoError(s.backend.SelectAccount(loginParams))
_, err := s.backend.AccountManager().MainAccountAddress()
s.Require().NoError(err)
_, err = s.backend.AccountManager().SelectedChatAccount()
s.Require().NoError(err)
}
func (s *TransfersSuite) SetupTest() {
s.DevNodeSuite.SetupTest()
s.Password = "test"
info, _, err := s.backend.AccountManager().CreateAccount(s.Password)
s.Require().NoError(err)
s.Info = info
s.Address = common.HexToAddress(info.WalletAddress)
}
func (s *TransfersSuite) TearDownTest() {
s.Require().NoError(s.backend.Logout())
s.DevNodeSuite.TearDownTest()
}
func (s *TransfersSuite) getAllTranfers() (rst []wallet.TransferView, err error) {
return rst, s.Local.Call(&rst, "wallet_getTransfersByAddress", s.Address, (*hexutil.Big)(big.NewInt(0)))
return rst, s.Local.Call(&rst, "wallet_getTransfersByAddress", s.DevAccountAddress, (*hexutil.Big)(big.NewInt(0)))
}
func (s *TransfersSuite) sendTx(nonce uint64, to common.Address) {
@ -75,8 +41,7 @@ func (s *TransfersSuite) sendTx(nonce uint64, to common.Address) {
}
func (s *TransfersSuite) TestNewTransfers() {
s.SelectAccount()
s.sendTx(0, s.Address)
s.sendTx(0, s.DevAccountAddress)
s.Require().NoError(utils.Eventually(func() error {
all, err := s.getAllTranfers()
if err != nil {
@ -90,7 +55,7 @@ func (s *TransfersSuite) TestNewTransfers() {
go func() {
for i := 1; i < 10; i++ {
s.sendTx(uint64(i), s.Address)
s.sendTx(uint64(i), s.DevAccountAddress)
}
}()
s.Require().NoError(utils.Eventually(func() error {
@ -107,9 +72,8 @@ func (s *TransfersSuite) TestNewTransfers() {
func (s *TransfersSuite) TestHistoricalTransfers() {
for i := 0; i < 30; i++ {
s.sendTx(uint64(i), s.Address)
s.sendTx(uint64(i), s.DevAccountAddress)
}
s.SelectAccount()
s.Require().NoError(utils.Eventually(func() error {
all, err := s.getAllTranfers()
if err != nil {