Wallet database isolated by the network id

Wallet database refactored so that every query ensures isolation by the network id.
Network id provided when database object is created, thus it is transparent to other parts
of the wallet module.

Additionally every uniqueness index is changed to ensure that it doesn't prevent adding
object with same id but from a different network.
This commit is contained in:
Dmitry 2019-08-08 11:15:07 +03:00 committed by Dmitry Shulyak
parent 494cb5bb33
commit a67184adbd
6 changed files with 56 additions and 42 deletions

View File

@ -305,9 +305,9 @@ func (b *StatusBackend) permissionsService() gethnode.ServiceConstructor {
}
}
func (b *StatusBackend) walletService() gethnode.ServiceConstructor {
func (b *StatusBackend) walletService(network uint64) gethnode.ServiceConstructor {
return func(*gethnode.ServiceContext) (gethnode.Service, error) {
return wallet.NewService(wallet.NewDB(b.appDB)), nil
return wallet.NewService(wallet.NewDB(b.appDB, network)), nil
}
}
@ -328,7 +328,7 @@ func (b *StatusBackend) startNode(config *params.NodeConfig) (err error) {
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())
services = appendIf(config.WalletConfig.Enabled, services, b.walletService(config.NetworkID))
manager := b.accountManager.GetManager()
if manager == nil {

View File

@ -34,7 +34,7 @@ func _0001_app_down_sql() ([]byte, error) {
)
}
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")
var __0001_app_up_sql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x54\x5d\x93\x9a\x30\x14\x7d\xcf\xaf\xb8\x8f\x3a\xc3\x3f\xd8\x27\xd4\xe8\x66\x4a\x43\xcb\x47\x77\xf7\x89\x89\x90\x55\x46\x0c\x34\x89\x75\xfd\xf7\x9d\x00\x01\x74\x11\xbb\xd3\x37\x92\x9c\x1c\xce\x39\xf7\xde\x2c\x03\xec\x46\x18\x22\x77\xe1\x61\x20\x6b\xa0\x7e\x04\xf8\x95\x84\x51\x08\x8a\x6b\x9d\x8b\x9d\x82\x19\xd2\x97\x8a\xc3\x2f\x37\x58\x3e\xbb\x01\xfc\x08\xc8\x77\x37\x78\x83\x6f\xf8\xcd\x41\x7f\x58\x71\xe2\xb0\xf0\xfc\x05\x9a\xc3\x0b\x89\x9e\xfd\x38\x82\xc0\x7f\x21\xab\x27\x84\x26\xc8\x59\x9a\x96\x27\xa1\x0d\x39\xcb\x32\xc9\x95\x1a\xe7\x3f\xb3\xa2\xe0\x1a\x16\xbe\xef\x61\x97\x3a\x28\xdd\xb3\xc1\xaa\xd6\x15\xe1\xd7\xc8\x41\x4a\x97\x92\xed\xec\xaa\x3a\x6d\x0f\xfc\x52\xeb\x72\x50\xc5\xf4\xbe\xdd\x17\xec\x68\x21\x69\x59\x94\xb2\xfe\xbe\xaf\x3c\xa6\xe4\x67\x8c\x81\xd0\x15\x7e\x85\x93\xc8\x7f\x9f\x78\xd2\x28\x4a\xac\x6a\x9f\x0e\xbc\x34\x67\x73\x78\x79\xc6\x01\xee\x96\x4f\x53\x74\xc6\xd0\x38\x99\x39\xe9\xa8\xea\xc5\x74\xa4\x5b\x59\x9e\x15\x97\x26\xd2\x3c\xab\x8d\x5d\x47\xd9\x79\xaf\x2f\xd1\xd8\xf3\x1c\xa4\xf3\x23\x57\x9a\x1d\x2b\x88\xc3\x0d\xd9\x50\xbc\x82\x05\xd9\x10\x1a\x39\x28\x63\x55\x65\x93\x86\x15\x5e\xbb\xb1\x17\xc1\x3b\x2b\x14\x77\xd0\x3e\x37\x71\x5f\x88\xc8\xf8\x07\xc4\x34\x6c\x6e\x12\x3a\x11\xe5\x94\xe2\xa4\xe5\x83\x19\x6a\xb7\x12\xeb\xa0\x97\x6a\x31\x4d\xf5\xd6\x7e\x80\xc9\x86\x1a\x67\xb3\xfe\xce\x1c\x02\xbc\xc6\x01\xa6\x4b\xdc\xb3\xcf\xcc\xbe\x6f\x3c\x78\x38\xc2\xb0\x74\xc3\xa5\xbb\xc2\xe8\x41\x9a\xc6\xbe\x89\xb2\x4f\x6d\x10\xe6\xd7\x6c\x56\x5c\x1e\x73\xa5\xf2\x52\x18\x42\x43\x9c\x8c\xd5\xa2\x87\xdd\x9e\x0c\xcd\x76\xd7\xaf\xbc\xd6\x6a\x67\xcd\xf6\xb8\xd5\x29\x81\x5a\x32\xa1\xde\x9b\xd6\x11\x5c\x9f\x4b\x79\x30\x05\xe8\x0a\xdb\xb4\xc4\xb0\x16\x4c\xed\xbb\x79\xed\xb7\x6f\x27\xb9\x3f\xd9\x16\x87\xe4\xce\x25\xfd\xd1\x8e\xa9\xe2\x22\xe3\x72\x04\x21\x79\xca\xf3\x4a\xb7\xb0\xa2\xdc\xb5\x5f\x57\xaf\xd2\x78\x5a\xbd\x1b\xc7\x4a\xb8\xee\x91\xa2\x4c\x0f\x6a\x08\x6b\x20\x9f\x32\x74\xd0\xd2\xa7\x61\x14\xb8\x26\x88\x76\x74\x6d\x6c\x49\xc5\xa5\x1d\xe1\xfa\xbb\xa5\xb3\xf3\x3e\x33\x9c\x4e\x0b\x70\xfa\x7f\xcd\x1f\xf5\x60\xa3\xee\x3f\x8b\x22\x4e\xc7\x2d\x97\x9f\xe1\x83\xd1\xbf\x4f\xc9\x59\x56\xbf\x01\xdd\x03\xb0\x76\xbd\x70\x34\x8c\x5a\xeb\xa8\xfb\xdb\x70\xef\x5e\x6e\x94\x3e\xe2\x68\x50\x0f\xb3\xb3\xef\x68\xa2\xcb\xe4\x6b\x39\x4e\x77\xf1\xbd\x38\xd5\x45\xa4\x50\x3f\x9c\x13\xfd\xd7\x6a\x9f\xee\x40\x0b\xfa\xa7\x1e\x3c\xb2\xaa\xca\xc5\x2e\x79\x2f\x65\xd2\x5a\xee\x1c\x8f\x26\x69\xdb\xb0\x97\x73\xdb\x91\x7f\x03\x00\x00\xff\xff\xd0\x65\x6e\xd9\x13\x08\x00\x00")
func _0001_app_up_sql() ([]byte, error) {
return bindata_read(

View File

@ -44,7 +44,8 @@ FOREIGN KEY(dapp_name) REFERENCES dapps(name) ON DELETE CASCADE
CREATE TABLE IF NOT EXISTS transfers (
hash VARCHAR UNIQUE,
network_id UNSIGNED BIGINT NOT NULL,
hash VARCHAR NOT NULL,
address VARCHAR NOT NULL,
blk_hash VARCHAR NOT NULL,
tx BLOB,
@ -52,21 +53,25 @@ 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)
FOREIGN KEY(network_id,blk_hash) REFERENCES blocks(network_id,hash) ON DELETE CASCADE,
CONSTRAINT unique_transfer_per_address_per_network UNIQUE (hash,address,network_id)
);
CREATE TABLE IF NOT EXISTS blocks (
hash VARCHAR PRIMARY KEY,
number BIGINT UNIQUE NOT NULL,
network_id UNSIGNED BIGINT NOT NULL,
hash VARCHAR NOT NULL,
number BIGINT NOT NULL,
timestamp UNSIGNED BIGINT NOT NULL,
head BOOL DEFAULT FALSE
) WITHOUT ROWID;
head BOOL DEFAULT FALSE,
CONSTRAINT unique_block_per_network UNIQUE (network_id,hash)
CONSTRAINT unique_block_number_per_network UNIQUE (network_id,number)
);
CREATE TABLE IF NOT EXISTS accounts_to_blocks (
network_id UNSIGNED BIGINT NOT NULL,
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)
FOREIGN KEY(network_id,blk_number) REFERENCES blocks(network_id,number) ON DELETE CASCADE,
CONSTRAINT unique_mapping_for_account_to_block_per_network UNIQUE (address,blk_number,network_id)
);

View File

@ -96,13 +96,14 @@ func (blob *JSONBlob) Value() (driver.Value, error) {
return json.Marshal(blob.data)
}
func NewDB(db *sql.DB) *Database {
return &Database{db}
func NewDB(db *sql.DB, network uint64) *Database {
return &Database{db: db, network: network}
}
// Database sql wrapper for operations with wallet objects.
type Database struct {
db *sql.DB
network uint64
}
// Close closes database.
@ -130,21 +131,21 @@ func (db Database) ProcessTranfers(transfers []Transfer, accounts []common.Addre
if err != nil {
return
}
err = insertHeaders(tx, added)
err = insertHeaders(tx, db.network, added)
if err != nil {
return
}
err = insertTransfers(tx, transfers)
err = insertTransfers(tx, db.network, transfers)
if err != nil {
return
}
err = updateAccounts(tx, accounts, added, option)
err = updateAccounts(tx, db.network, accounts, added, option)
return
}
// GetTransfersByAddress loads transfers for a given address between two blocks.
func (db *Database) GetTransfersByAddress(address common.Address, start, end *big.Int) (rst []Transfer, err error) {
query := newTransfersQuery().FilterAddress(address).FilterStart(start).FilterEnd(end)
query := newTransfersQuery().FilterNetwork(db.network).FilterAddress(address).FilterStart(start).FilterEnd(end)
rows, err := db.db.Query(query.String(), query.Args()...)
if err != nil {
return
@ -155,7 +156,7 @@ func (db *Database) GetTransfersByAddress(address common.Address, start, end *bi
// GetTransfers load transfers transfer betweeen two blocks.
func (db *Database) GetTransfers(start, end *big.Int) (rst []Transfer, err error) {
query := newTransfersQuery().FilterStart(start).FilterEnd(end)
query := newTransfersQuery().FilterNetwork(db.network).FilterStart(start).FilterEnd(end)
rows, err := db.db.Query(query.String(), query.Args()...)
if err != nil {
return
@ -174,7 +175,7 @@ func (db *Database) SaveHeaders(headers []*types.Header) (err error) {
if err != nil {
return
}
insert, err = tx.Prepare("INSERT INTO blocks(number, hash, timestamp) VALUES (?, ?, ?)")
insert, err = tx.Prepare("INSERT INTO blocks(network_id, number, hash, timestamp) VALUES (?, ?, ?, ?)")
if err != nil {
return
}
@ -187,7 +188,7 @@ func (db *Database) SaveHeaders(headers []*types.Header) (err error) {
}()
for _, h := range headers {
_, err = insert.Exec((*SQLBigInt)(h.Number), h.Hash(), h.Time)
_, err = insert.Exec(db.network, (*SQLBigInt)(h.Number), h.Hash(), h.Time)
if err != nil {
return
}
@ -204,7 +205,7 @@ func (db *Database) SaveSyncedHeader(address common.Address, header *types.Heade
if err != nil {
return
}
insert, err = tx.Prepare("INSERT INTO accounts_to_blocks(address, blk_number, sync) VALUES (?,?,?)")
insert, err = tx.Prepare("INSERT INTO accounts_to_blocks(network_id, address, blk_number, sync) VALUES (?, ?,?,?)")
if err != nil {
return
}
@ -215,7 +216,7 @@ func (db *Database) SaveSyncedHeader(address common.Address, header *types.Heade
_ = tx.Rollback()
}
}()
_, err = insert.Exec(address, (*SQLBigInt)(header.Number), option)
_, err = insert.Exec(db.network, address, (*SQLBigInt)(header.Number), option)
if err != nil {
return
}
@ -225,7 +226,7 @@ func (db *Database) SaveSyncedHeader(address common.Address, header *types.Heade
// HeaderExists checks if header with hash exists in db.
func (db *Database) HeaderExists(hash common.Hash) (bool, error) {
var val sql.NullBool
err := db.db.QueryRow("SELECT EXISTS (SELECT hash FROM blocks WHERE hash = ?)", hash).Scan(&val)
err := db.db.QueryRow("SELECT EXISTS (SELECT hash FROM blocks WHERE hash = ? AND network_id = ?)", hash, db.network).Scan(&val)
if err != nil {
return false, err
}
@ -235,7 +236,7 @@ func (db *Database) HeaderExists(hash common.Hash) (bool, error) {
// GetHeaderByNumber selects header using block number.
func (db *Database) GetHeaderByNumber(number *big.Int) (header *DBHeader, err error) {
header = &DBHeader{Hash: common.Hash{}, Number: new(big.Int)}
err = db.db.QueryRow("SELECT hash,number FROM blocks WHERE number = ?", (*SQLBigInt)(number)).Scan(&header.Hash, (*SQLBigInt)(header.Number))
err = db.db.QueryRow("SELECT hash,number FROM blocks WHERE number = ? AND network_id = ?", (*SQLBigInt)(number), db.network).Scan(&header.Hash, (*SQLBigInt)(header.Number))
if err == nil {
return header, nil
}
@ -247,7 +248,7 @@ func (db *Database) GetHeaderByNumber(number *big.Int) (header *DBHeader, err er
func (db *Database) GetLastHead() (header *DBHeader, err error) {
header = &DBHeader{Hash: common.Hash{}, Number: new(big.Int)}
err = db.db.QueryRow("SELECT hash,number FROM blocks WHERE head = 1 AND number = (SELECT MAX(number) FROM blocks)").Scan(&header.Hash, (*SQLBigInt)(header.Number))
err = db.db.QueryRow("SELECT hash,number FROM blocks WHERE network_id = $1 AND head = 1 AND number = (SELECT MAX(number) FROM blocks WHERE network_id = $1)", db.network).Scan(&header.Hash, (*SQLBigInt)(header.Number))
if err == nil {
return header, nil
}
@ -261,8 +262,8 @@ func (db *Database) GetLastHead() (header *DBHeader, err error) {
func (db *Database) GetLatestSynced(address common.Address, option SyncOption) (header *DBHeader, err error) {
header = &DBHeader{Hash: common.Hash{}, Number: new(big.Int)}
err = db.db.QueryRow(`
SELECT blocks.hash, blk_number FROM accounts_to_blocks JOIN blocks ON blk_number = blocks.number WHERE address = $1 AND blk_number
= (SELECT MAX(blk_number) FROM accounts_to_blocks WHERE address = $1 AND sync & $2 = $2)`, address, option).Scan(&header.Hash, (*SQLBigInt)(header.Number))
SELECT blocks.hash, blk_number FROM accounts_to_blocks JOIN blocks ON blk_number = blocks.number WHERE blocks.network_id = $1 AND address = $2 AND blk_number
= (SELECT MAX(blk_number) FROM accounts_to_blocks WHERE network_id = $1 AND address = $2 AND sync & $3 = $3)`, db.network, address, option).Scan(&header.Hash, (*SQLBigInt)(header.Number))
if err == nil {
return header, nil
}
@ -291,13 +292,13 @@ func deleteHeaders(creator statementCreator, headers []*DBHeader) error {
return nil
}
func insertHeaders(creator statementCreator, headers []*DBHeader) error {
insert, err := creator.Prepare("INSERT OR IGNORE INTO blocks(hash, number, timestamp, head) VALUES (?, ?, ?, ?)")
func insertHeaders(creator statementCreator, network uint64, headers []*DBHeader) error {
insert, err := creator.Prepare("INSERT OR IGNORE INTO blocks(network_id, hash, number, timestamp, head) VALUES (?, ?, ?, ?, ?)")
if err != nil {
return err
}
for _, h := range headers {
_, err = insert.Exec(h.Hash, (*SQLBigInt)(h.Number), h.Timestamp, h.Head)
_, err = insert.Exec(network, h.Hash, (*SQLBigInt)(h.Number), h.Timestamp, h.Head)
if err != nil {
return err
}
@ -305,13 +306,13 @@ func insertHeaders(creator statementCreator, headers []*DBHeader) error {
return nil
}
func insertTransfers(creator statementCreator, transfers []Transfer) error {
insert, err := creator.Prepare("INSERT OR IGNORE INTO transfers(hash, blk_hash, address, tx, sender, receipt, log, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?)")
func insertTransfers(creator statementCreator, network uint64, transfers []Transfer) error {
insert, err := creator.Prepare("INSERT OR IGNORE INTO transfers(network_id, hash, blk_hash, address, tx, sender, receipt, log, type) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
if err != nil {
return err
}
for _, t := range transfers {
_, err = insert.Exec(t.ID, t.BlockHash, t.Address, &JSONBlob{t.Transaction}, t.From, &JSONBlob{t.Receipt}, &JSONBlob{t.Log}, t.Type)
_, err = insert.Exec(network, t.ID, t.BlockHash, t.Address, &JSONBlob{t.Transaction}, t.From, &JSONBlob{t.Receipt}, &JSONBlob{t.Log}, t.Type)
if err != nil {
return err
}
@ -319,18 +320,18 @@ func insertTransfers(creator statementCreator, transfers []Transfer) error {
return nil
}
func updateAccounts(creator statementCreator, accounts []common.Address, headers []*DBHeader, option SyncOption) error {
update, err := creator.Prepare("UPDATE accounts_to_blocks SET sync=sync|? WHERE address=? AND blk_number=?")
func updateAccounts(creator statementCreator, network uint64, accounts []common.Address, headers []*DBHeader, option SyncOption) error {
update, err := creator.Prepare("UPDATE accounts_to_blocks SET sync=sync|? WHERE address=? AND blk_number=? AND network_id=?")
if err != nil {
return err
}
insert, err := creator.Prepare("INSERT OR IGNORE INTO accounts_to_blocks(address,blk_number,sync) VALUES(?,?,?)")
insert, err := creator.Prepare("INSERT OR IGNORE INTO accounts_to_blocks(network_id,address,blk_number,sync) VALUES(?,?,?,?)")
if err != nil {
return err
}
for _, acc := range accounts {
for _, h := range headers {
rst, err := update.Exec(option, acc, (*SQLBigInt)(h.Number))
rst, err := update.Exec(option, acc, (*SQLBigInt)(h.Number), network)
if err != nil {
return err
}
@ -341,7 +342,7 @@ func updateAccounts(creator statementCreator, accounts []common.Address, headers
if affected > 0 {
continue
}
_, err = insert.Exec(acc, (*SQLBigInt)(h.Number), option)
_, err = insert.Exec(network, acc, (*SQLBigInt)(h.Number), option)
if err != nil {
return err
}

View File

@ -17,7 +17,7 @@ func setupTestDB(t *testing.T) (*Database, func()) {
require.NoError(t, err)
db, err := appdatabase.InitializeDB(tmpfile.Name(), "wallet-tests")
require.NoError(t, err)
return NewDB(db), func() {
return NewDB(db, 1777), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}

View File

@ -51,6 +51,14 @@ func (q *transfersQuery) FilterEnd(end *big.Int) *transfersQuery {
return q
}
func (q *transfersQuery) FilterNetwork(network uint64) *transfersQuery {
q.andOrWhere()
q.added = true
q.buf.WriteString(" blocks.network_id = ?")
q.args = append(q.args, network)
return q
}
func (q *transfersQuery) FilterAddress(address common.Address) *transfersQuery {
q.andOrWhere()
q.added = true