mirror of
https://github.com/status-im/status-go.git
synced 2025-01-09 14:16:21 +00:00
a67184adbd
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.
236 lines
6.5 KiB
Go
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)
|
|
}
|