status-go/services/wallet/database_test.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)
}