status-go/services/wallet/database_test.go
Dmitry a67184adbd 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.
2019-08-21 10:44:50 +03:00

236 lines
6.5 KiB
Go

package wallet
import (
"io/ioutil"
"math/big"
"os"
"testing"
"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 := appdatabase.InitializeDB(tmpfile.Name(), "wallet-tests")
require.NoError(t, err)
return NewDB(db, 1777), func() {
require.NoError(t, db.Close())
require.NoError(t, os.Remove(tmpfile.Name()))
}
}
func TestDBGetHeaderByNumber(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
header := &types.Header{
Number: big.NewInt(10),
Difficulty: big.NewInt(1),
Time: 1,
}
require.NoError(t, db.SaveHeaders([]*types.Header{header}))
rst, err := db.GetHeaderByNumber(header.Number)
require.NoError(t, err)
require.Equal(t, header.Hash(), rst.Hash)
}
func TestDBGetHeaderByNumberNoRows(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
rst, err := db.GetHeaderByNumber(big.NewInt(1))
require.NoError(t, err)
require.Nil(t, rst)
}
func TestDBHeaderExists(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
header := &types.Header{
Number: big.NewInt(10),
Difficulty: big.NewInt(1),
Time: 1,
}
require.NoError(t, db.SaveHeaders([]*types.Header{header}))
rst, err := db.HeaderExists(header.Hash())
require.NoError(t, err)
require.True(t, rst)
}
func TestDBHeaderDoesntExist(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
rst, err := db.HeaderExists(common.Hash{1})
require.NoError(t, err)
require.False(t, rst)
}
func TestDBProcessTransfer(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
header := &DBHeader{
Number: big.NewInt(1),
Hash: common.Hash{1},
}
tx := types.NewTransaction(1, common.Address{1}, nil, 10, big.NewInt(10), nil)
transfers := []Transfer{
{
ID: common.Hash{1},
Type: ethTransfer,
BlockHash: header.Hash,
BlockNumber: header.Number,
Transaction: tx,
Receipt: types.NewReceipt(nil, false, 100),
},
}
require.NoError(t, db.ProcessTranfers(transfers, nil, []*DBHeader{header}, nil, 0))
}
func TestDBReorgTransfers(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
rcpt := types.NewReceipt(nil, false, 100)
rcpt.Logs = []*types.Log{}
original := &DBHeader{
Number: big.NewInt(1),
Hash: common.Hash{1},
}
replaced := &DBHeader{
Number: big.NewInt(1),
Hash: common.Hash{2},
}
originalTX := types.NewTransaction(1, common.Address{1}, nil, 10, big.NewInt(10), nil)
replacedTX := types.NewTransaction(2, common.Address{1}, nil, 10, big.NewInt(10), nil)
require.NoError(t, db.ProcessTranfers([]Transfer{
{ethTransfer, common.Hash{1}, *originalTX.To(), original.Number, original.Hash, 100, originalTX, common.Address{1}, rcpt, nil},
}, nil, []*DBHeader{original}, nil, 0))
require.NoError(t, db.ProcessTranfers([]Transfer{
{ethTransfer, common.Hash{2}, *replacedTX.To(), replaced.Number, replaced.Hash, 100, replacedTX, common.Address{1}, rcpt, nil},
}, nil, []*DBHeader{replaced}, []*DBHeader{original}, 0))
all, err := db.GetTransfers(big.NewInt(0), nil)
require.NoError(t, err)
require.Len(t, all, 1)
require.Equal(t, replacedTX.Hash(), all[0].Transaction.Hash())
}
func TestDBGetTransfersFromBlock(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
headers := []*DBHeader{}
transfers := []Transfer{}
for i := 1; i < 10; i++ {
header := &DBHeader{
Number: big.NewInt(int64(i)),
Hash: common.Hash{byte(i)},
}
headers = append(headers, header)
tx := types.NewTransaction(uint64(i), common.Address{1}, nil, 10, big.NewInt(10), nil)
receipt := types.NewReceipt(nil, false, 100)
receipt.Logs = []*types.Log{}
transfer := Transfer{
ID: tx.Hash(),
Type: ethTransfer,
BlockNumber: header.Number,
BlockHash: header.Hash,
Transaction: tx,
Receipt: receipt,
}
transfers = append(transfers, transfer)
}
require.NoError(t, db.ProcessTranfers(transfers, nil, headers, nil, 0))
rst, err := db.GetTransfers(big.NewInt(7), nil)
require.NoError(t, err)
require.Len(t, rst, 3)
rst, err = db.GetTransfers(big.NewInt(2), big.NewInt(5))
require.NoError(t, err)
require.Len(t, rst, 4)
}
func TestDBLatestSynced(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
address := common.Address{1}
h1 := &types.Header{
Number: big.NewInt(10),
Difficulty: big.NewInt(1),
Time: 1,
}
h2 := &types.Header{
Number: big.NewInt(9),
Difficulty: big.NewInt(1),
Time: 1,
}
require.NoError(t, db.SaveHeaders([]*types.Header{h1, h2}))
require.NoError(t, db.SaveSyncedHeader(address, h1, ethSync))
require.NoError(t, db.SaveSyncedHeader(address, h2, ethSync))
latest, err := db.GetLatestSynced(address, ethSync)
require.NoError(t, err)
require.NotNil(t, latest)
require.Equal(t, h1.Number, latest.Number)
require.Equal(t, h1.Hash(), latest.Hash)
}
func TestDBLatestSyncedDoesntExist(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
latest, err := db.GetLatestSynced(common.Address{1}, ethSync)
require.NoError(t, err)
require.Nil(t, latest)
}
func TestDBProcessTransfersUpdate(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
address := common.Address{1}
header := &DBHeader{
Number: big.NewInt(10),
Hash: common.Hash{1},
}
transfer := Transfer{
ID: common.Hash{1},
BlockNumber: header.Number,
BlockHash: header.Hash,
Transaction: types.NewTransaction(0, common.Address{}, nil, 0, nil, nil),
Address: address,
}
require.NoError(t, db.ProcessTranfers([]Transfer{transfer}, []common.Address{address}, []*DBHeader{header}, nil, ethSync))
require.NoError(t, db.ProcessTranfers([]Transfer{transfer}, []common.Address{address}, []*DBHeader{header}, nil, erc20Sync))
latest, err := db.GetLatestSynced(address, ethSync|erc20Sync)
require.NoError(t, err)
require.Equal(t, header.Hash, latest.Hash)
}
func TestDBLastHeadExist(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
headers := []*DBHeader{
{Number: big.NewInt(1), Hash: common.Hash{1}, Head: true},
{Number: big.NewInt(2), Hash: common.Hash{2}, Head: true},
{Number: big.NewInt(3), Hash: common.Hash{3}, Head: true},
}
require.NoError(t, db.ProcessTranfers(nil, nil, headers, nil, 0))
last, err := db.GetLastHead()
require.NoError(t, err)
require.Equal(t, headers[2].Hash, last.Hash)
}
func TestDBLastHeadDoesntExist(t *testing.T) {
db, stop := setupTestDB(t)
defer stop()
last, err := db.GetLastHead()
require.NoError(t, err)
require.Nil(t, last)
}