status-go/services/wallet/history/service_test.go

289 lines
5.2 KiB
Go
Raw Normal View History

feat: retrieve balance history for tokens and cache it to DB Extends wallet module with the history package with the following components: BalanceDB (balance_db.go) - Keeps track of balance information (token count, block, block timestamp) for a token identity (chain, address, currency) - The cached data is stored in `balance_history` table. - Uniqueness constrained is enforced by the `balance_history_identify_entry` UNIQUE index. - Optimal DB fetching is ensured by the `balance_history_filter_entries` index Balance (balance.go) - Provides two stages: - Fetch of balance history using RPC calls (Balance.update function) - Retrieving of cached balance data from the DB it exists (Balance.get function) - Fetching and retrieving of data is done for specific time intervals defined by TimeInterval "enumeration" - Update process is done for a token identity by the Balance.Update function - The granularity of data points returned is defined by the constant increment step define in `timeIntervalToStride` for each time interval. - The `blocksStride` values have a common divisor to have cache hit between time intervals. Service (service.go) - Main APIs - StartBalanceHistory: Regularly updates balance history for all enabled networks, available accounts and provided tokens. - GetBalanceHistory: retrieves cached token count for a token identity (chain, address, currency) for multiple chains - UpdateVisibleTokens: will set the list of tokens to have historical balance fetched. This is a simplification to limit tokens to a small list that make sense Fetch balance history for ECR20 tokens - Add token.Manager.GetTokenBalanceAt to fetch balance of a specific block number of ECR20. - Add tokenChainClientSource concrete implementation of DataSource to fetch balance of ECR20 tokens. - Chose the correct DataSource implementation based on the token "is native" property. Tests Tests are implemented using a mock of `DataSource` interface used to intercept the RPC calls. Notes: - the timestamp used for retrieving block balance is constant Closes status-desktop: #8175, #8226, #8862
2022-11-15 12:14:41 +00:00
package history
import (
"math/big"
"reflect"
feat: retrieve balance history for tokens and cache it to DB Extends wallet module with the history package with the following components: BalanceDB (balance_db.go) - Keeps track of balance information (token count, block, block timestamp) for a token identity (chain, address, currency) - The cached data is stored in `balance_history` table. - Uniqueness constrained is enforced by the `balance_history_identify_entry` UNIQUE index. - Optimal DB fetching is ensured by the `balance_history_filter_entries` index Balance (balance.go) - Provides two stages: - Fetch of balance history using RPC calls (Balance.update function) - Retrieving of cached balance data from the DB it exists (Balance.get function) - Fetching and retrieving of data is done for specific time intervals defined by TimeInterval "enumeration" - Update process is done for a token identity by the Balance.Update function - The granularity of data points returned is defined by the constant increment step define in `timeIntervalToStride` for each time interval. - The `blocksStride` values have a common divisor to have cache hit between time intervals. Service (service.go) - Main APIs - StartBalanceHistory: Regularly updates balance history for all enabled networks, available accounts and provided tokens. - GetBalanceHistory: retrieves cached token count for a token identity (chain, address, currency) for multiple chains - UpdateVisibleTokens: will set the list of tokens to have historical balance fetched. This is a simplification to limit tokens to a small list that make sense Fetch balance history for ECR20 tokens - Add token.Manager.GetTokenBalanceAt to fetch balance of a specific block number of ECR20. - Add tokenChainClientSource concrete implementation of DataSource to fetch balance of ECR20 tokens. - Chose the correct DataSource implementation based on the token "is native" property. Tests Tests are implemented using a mock of `DataSource` interface used to intercept the RPC calls. Notes: - the timestamp used for retrieving block balance is constant Closes status-desktop: #8175, #8226, #8862
2022-11-15 12:14:41 +00:00
"testing"
"github.com/ethereum/go-ethereum/common/hexutil"
)
func Test_entriesToDataPoints(t *testing.T) {
type args struct {
chainIDs []uint64
data []*entry
}
tests := []struct {
name string
args args
want []*DataPoint
wantErr bool
}{
{
name: "zeroAllChainsSameTimestamp",
args: args{
chainIDs: []uint64{1, 2},
data: []*entry{
{
chainID: 1,
balance: big.NewInt(0),
timestamp: 1,
block: big.NewInt(1),
},
{
chainID: 2,
balance: big.NewInt(0),
timestamp: 1,
block: big.NewInt(5),
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(0)),
Timestamp: 1,
},
},
wantErr: false,
},
{
name: "oneZeroAllChainsDifferentTimestamp",
args: args{
chainIDs: []uint64{1, 2},
data: []*entry{
{
chainID: 2,
balance: big.NewInt(0),
timestamp: 1,
block: big.NewInt(1),
},
{
chainID: 1,
balance: big.NewInt(2),
timestamp: 2,
block: big.NewInt(2),
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(0)),
Timestamp: 1,
},
{
Balance: (*hexutil.Big)(big.NewInt(2)),
Timestamp: 2,
},
},
wantErr: false,
},
{
name: "nonZeroAllChainsDifferentTimestamp",
args: args{
chainIDs: []uint64{1, 2},
data: []*entry{
{
chainID: 2,
balance: big.NewInt(1),
timestamp: 1,
},
{
chainID: 1,
balance: big.NewInt(2),
timestamp: 2,
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(1)),
Timestamp: 1,
},
{
Balance: (*hexutil.Big)(big.NewInt(2)),
Timestamp: 2,
},
},
wantErr: false,
},
{
name: "sameChainDifferentTimestamp",
args: args{
chainIDs: []uint64{1, 2},
data: []*entry{
{
chainID: 1,
balance: big.NewInt(1),
timestamp: 1,
block: big.NewInt(1),
},
{
chainID: 1,
balance: big.NewInt(2),
timestamp: 2,
block: big.NewInt(2),
},
{
chainID: 1,
balance: big.NewInt(0),
timestamp: 3,
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(1)),
Timestamp: 1,
},
{
Balance: (*hexutil.Big)(big.NewInt(2)),
Timestamp: 2,
},
{
Balance: (*hexutil.Big)(big.NewInt(0)),
Timestamp: 3,
},
},
wantErr: false,
},
{
name: "sameChainDifferentTimestampOtherChainsEmpty",
args: args{
chainIDs: []uint64{1, 2},
data: []*entry{
{
chainID: 1,
balance: big.NewInt(1),
timestamp: 1,
block: big.NewInt(1),
},
{
chainID: 1,
balance: big.NewInt(2),
timestamp: 2,
block: big.NewInt(2),
},
{
chainID: 2,
balance: big.NewInt(0),
timestamp: 2,
block: big.NewInt(2),
},
{
chainID: 1,
balance: big.NewInt(2),
timestamp: 3,
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(1)),
Timestamp: 1,
},
{
Balance: (*hexutil.Big)(big.NewInt(2)),
Timestamp: 2,
},
{
Balance: (*hexutil.Big)(big.NewInt(2)),
Timestamp: 3,
},
},
wantErr: false,
},
{
name: "onlyEdgePointsOnManyChainsWithPadding",
args: args{
chainIDs: []uint64{1, 2, 3},
data: []*entry{
// Left edge - same timestamp
{
chainID: 1,
balance: big.NewInt(1),
timestamp: 1,
},
{
chainID: 2,
balance: big.NewInt(2),
timestamp: 1,
},
{
chainID: 3,
balance: big.NewInt(3),
timestamp: 1,
},
// Padding
{
chainID: 0,
balance: big.NewInt(6),
timestamp: 2,
},
{
chainID: 0,
balance: big.NewInt(6),
timestamp: 3,
},
{
chainID: 0,
balance: big.NewInt(6),
timestamp: 4,
},
// Right edge - same timestamp
{
chainID: 1,
balance: big.NewInt(1),
timestamp: 5,
},
{
chainID: 2,
balance: big.NewInt(2),
timestamp: 5,
},
{
chainID: 3,
balance: big.NewInt(3),
timestamp: 5,
},
},
},
want: []*DataPoint{
{
Balance: (*hexutil.Big)(big.NewInt(6)),
Timestamp: 1,
},
{
Balance: (*hexutil.Big)(big.NewInt(6)),
Timestamp: 2,
},
{
Balance: (*hexutil.Big)(big.NewInt(6)),
Timestamp: 3,
},
{
Balance: (*hexutil.Big)(big.NewInt(6)),
Timestamp: 4,
},
{
Balance: (*hexutil.Big)(big.NewInt(6)),
Timestamp: 5,
},
},
wantErr: false,
},
}
feat: retrieve balance history for tokens and cache it to DB Extends wallet module with the history package with the following components: BalanceDB (balance_db.go) - Keeps track of balance information (token count, block, block timestamp) for a token identity (chain, address, currency) - The cached data is stored in `balance_history` table. - Uniqueness constrained is enforced by the `balance_history_identify_entry` UNIQUE index. - Optimal DB fetching is ensured by the `balance_history_filter_entries` index Balance (balance.go) - Provides two stages: - Fetch of balance history using RPC calls (Balance.update function) - Retrieving of cached balance data from the DB it exists (Balance.get function) - Fetching and retrieving of data is done for specific time intervals defined by TimeInterval "enumeration" - Update process is done for a token identity by the Balance.Update function - The granularity of data points returned is defined by the constant increment step define in `timeIntervalToStride` for each time interval. - The `blocksStride` values have a common divisor to have cache hit between time intervals. Service (service.go) - Main APIs - StartBalanceHistory: Regularly updates balance history for all enabled networks, available accounts and provided tokens. - GetBalanceHistory: retrieves cached token count for a token identity (chain, address, currency) for multiple chains - UpdateVisibleTokens: will set the list of tokens to have historical balance fetched. This is a simplification to limit tokens to a small list that make sense Fetch balance history for ECR20 tokens - Add token.Manager.GetTokenBalanceAt to fetch balance of a specific block number of ECR20. - Add tokenChainClientSource concrete implementation of DataSource to fetch balance of ECR20 tokens. - Chose the correct DataSource implementation based on the token "is native" property. Tests Tests are implemented using a mock of `DataSource` interface used to intercept the RPC calls. Notes: - the timestamp used for retrieving block balance is constant Closes status-desktop: #8175, #8226, #8862
2022-11-15 12:14:41 +00:00
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := entriesToDataPoints(tt.args.chainIDs, tt.args.data)
if (err != nil) != tt.wantErr {
t.Errorf("entriesToDataPoints() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("entriesToDataPoints() = %v, want %v", got, tt.want)
}
feat: retrieve balance history for tokens and cache it to DB Extends wallet module with the history package with the following components: BalanceDB (balance_db.go) - Keeps track of balance information (token count, block, block timestamp) for a token identity (chain, address, currency) - The cached data is stored in `balance_history` table. - Uniqueness constrained is enforced by the `balance_history_identify_entry` UNIQUE index. - Optimal DB fetching is ensured by the `balance_history_filter_entries` index Balance (balance.go) - Provides two stages: - Fetch of balance history using RPC calls (Balance.update function) - Retrieving of cached balance data from the DB it exists (Balance.get function) - Fetching and retrieving of data is done for specific time intervals defined by TimeInterval "enumeration" - Update process is done for a token identity by the Balance.Update function - The granularity of data points returned is defined by the constant increment step define in `timeIntervalToStride` for each time interval. - The `blocksStride` values have a common divisor to have cache hit between time intervals. Service (service.go) - Main APIs - StartBalanceHistory: Regularly updates balance history for all enabled networks, available accounts and provided tokens. - GetBalanceHistory: retrieves cached token count for a token identity (chain, address, currency) for multiple chains - UpdateVisibleTokens: will set the list of tokens to have historical balance fetched. This is a simplification to limit tokens to a small list that make sense Fetch balance history for ECR20 tokens - Add token.Manager.GetTokenBalanceAt to fetch balance of a specific block number of ECR20. - Add tokenChainClientSource concrete implementation of DataSource to fetch balance of ECR20 tokens. - Chose the correct DataSource implementation based on the token "is native" property. Tests Tests are implemented using a mock of `DataSource` interface used to intercept the RPC calls. Notes: - the timestamp used for retrieving block balance is constant Closes status-desktop: #8175, #8226, #8862
2022-11-15 12:14:41 +00:00
})
}
}