mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 08:15:19 +00:00
6c68e41758
* most audit revisions * remove expected income * update begin block spec * filter queryAtomicSwaps, add queryAssetSupplies * update old address * update test * Remove legacy method * remove legacy comment * address PR comments * IsValid for SwapDirection, SwapStatus * fix rng logging * query asset supplies * return [64]byte from rng * remove cross chain field from MsgCreateAtomicSwap * move swap filtering to querier * rename Limit field to SupplyLimit
374 lines
11 KiB
Go
374 lines
11 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
tmtime "github.com/tendermint/tendermint/types/time"
|
|
|
|
"github.com/kava-labs/kava/app"
|
|
"github.com/kava-labs/kava/x/bep3/keeper"
|
|
"github.com/kava-labs/kava/x/bep3/types"
|
|
)
|
|
|
|
const LongtermStorageDuration = 86400
|
|
|
|
type KeeperTestSuite struct {
|
|
suite.Suite
|
|
|
|
keeper keeper.Keeper
|
|
app app.TestApp
|
|
ctx sdk.Context
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) SetupTest() {
|
|
config := sdk.GetConfig()
|
|
app.SetBech32AddressPrefixes(config)
|
|
suite.ResetChain()
|
|
return
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) ResetChain() {
|
|
tApp := app.NewTestApp()
|
|
ctx := tApp.NewContext(true, abci.Header{Height: 1, Time: tmtime.Now()})
|
|
keeper := tApp.GetBep3Keeper()
|
|
|
|
suite.app = tApp
|
|
suite.ctx = ctx
|
|
suite.keeper = keeper
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestGetSetAtomicSwap() {
|
|
suite.ResetChain()
|
|
|
|
// Set new atomic swap
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
suite.keeper.SetAtomicSwap(suite.ctx, atomicSwap)
|
|
|
|
// Check atomic swap in store
|
|
s, found := suite.keeper.GetAtomicSwap(suite.ctx, atomicSwap.GetSwapID())
|
|
suite.True(found)
|
|
suite.Equal(atomicSwap, s)
|
|
|
|
// Check fake atomic swap not in store
|
|
fakeSwapID := types.CalculateSwapID(atomicSwap.RandomNumberHash, TestUser2, "otheraddress")
|
|
_, found = suite.keeper.GetAtomicSwap(suite.ctx, fakeSwapID)
|
|
suite.False(found)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestRemoveAtomicSwap() {
|
|
suite.ResetChain()
|
|
|
|
// Set new atomic swap
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
suite.keeper.SetAtomicSwap(suite.ctx, atomicSwap)
|
|
|
|
// Check atomic swap in store
|
|
s, found := suite.keeper.GetAtomicSwap(suite.ctx, atomicSwap.GetSwapID())
|
|
suite.True(found)
|
|
suite.Equal(atomicSwap, s)
|
|
|
|
suite.keeper.RemoveAtomicSwap(suite.ctx, atomicSwap.GetSwapID())
|
|
|
|
// Check atomic swap not in store
|
|
_, found = suite.keeper.GetAtomicSwap(suite.ctx, atomicSwap.GetSwapID())
|
|
suite.False(found)
|
|
}
|
|
func (suite *KeeperTestSuite) TestIterateAtomicSwaps() {
|
|
suite.ResetChain()
|
|
|
|
// Set atomic swaps
|
|
atomicSwaps := atomicSwaps(suite.ctx, 4)
|
|
for _, s := range atomicSwaps {
|
|
suite.keeper.SetAtomicSwap(suite.ctx, s)
|
|
}
|
|
|
|
// Read each atomic swap from the store
|
|
var readAtomicSwaps types.AtomicSwaps
|
|
suite.keeper.IterateAtomicSwaps(suite.ctx, func(a types.AtomicSwap) bool {
|
|
readAtomicSwaps = append(readAtomicSwaps, a)
|
|
return false
|
|
})
|
|
|
|
// Check expected values
|
|
suite.Equal(len(atomicSwaps), len(readAtomicSwaps))
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestGetAllAtomicSwaps() {
|
|
suite.ResetChain()
|
|
|
|
// Set atomic swaps
|
|
atomicSwaps := atomicSwaps(suite.ctx, 4)
|
|
for _, s := range atomicSwaps {
|
|
suite.keeper.SetAtomicSwap(suite.ctx, s)
|
|
}
|
|
|
|
// Get and check atomic swaps
|
|
res := suite.keeper.GetAllAtomicSwaps(suite.ctx)
|
|
suite.Equal(4, len(res))
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestInsertIntoByBlockIndex() {
|
|
suite.ResetChain()
|
|
|
|
// Set new atomic swap in by block index
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
suite.keeper.InsertIntoByBlockIndex(suite.ctx, atomicSwap)
|
|
|
|
// Block index lacks getter methods, must use iteration to get count of swaps in store
|
|
var swapIDs [][]byte
|
|
suite.keeper.IterateAtomicSwapsByBlock(suite.ctx, atomicSwap.ExpireHeight+1, func(id []byte) bool {
|
|
swapIDs = append(swapIDs, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDs), 1)
|
|
|
|
// Marshal the expected swapID
|
|
cdc := suite.app.Codec()
|
|
res, _ := cdc.MarshalBinaryBare(atomicSwap.GetSwapID())
|
|
expectedSwapID := res[1:]
|
|
|
|
suite.Equal(expectedSwapID, swapIDs[0])
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestRemoveFromByBlockIndex() {
|
|
suite.ResetChain()
|
|
|
|
// Set new atomic swap in by block index
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
suite.keeper.InsertIntoByBlockIndex(suite.ctx, atomicSwap)
|
|
|
|
// Check stored data in block index
|
|
var swapIDsPre [][]byte
|
|
suite.keeper.IterateAtomicSwapsByBlock(suite.ctx, atomicSwap.ExpireHeight+1, func(id []byte) bool {
|
|
swapIDsPre = append(swapIDsPre, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDsPre), 1)
|
|
|
|
suite.keeper.RemoveFromByBlockIndex(suite.ctx, atomicSwap)
|
|
|
|
// Check stored data not in block index
|
|
var swapIDsPost [][]byte
|
|
suite.keeper.IterateAtomicSwapsByBlock(suite.ctx, atomicSwap.ExpireHeight+1, func(id []byte) bool {
|
|
swapIDsPost = append(swapIDsPost, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDsPost), 0)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestIterateAtomicSwapsByBlock() {
|
|
suite.ResetChain()
|
|
|
|
type args struct {
|
|
blockCtx sdk.Context
|
|
swap types.AtomicSwap
|
|
}
|
|
|
|
var testCases []args
|
|
for i := 0; i < 8; i++ {
|
|
// Set up context 100 blocks apart
|
|
blockCtx := suite.ctx.WithBlockHeight(int64(i) * 100)
|
|
|
|
// Initialize a new atomic swap (different randomNumberHash = different swap IDs)
|
|
timestamp := tmtime.Now().Add(time.Duration(i) * time.Minute).Unix()
|
|
randomNumber, _ := types.GenerateSecureRandomNumber()
|
|
randomNumberHash := types.CalculateRandomHash(randomNumber[:], timestamp)
|
|
|
|
atomicSwap := types.NewAtomicSwap(cs(c("bnb", 50000)), randomNumberHash,
|
|
uint64(blockCtx.BlockHeight()), timestamp, TestUser1, TestUser2,
|
|
TestSenderOtherChain, TestRecipientOtherChain, 0, types.Open,
|
|
true, types.Incoming)
|
|
|
|
// Insert into block index
|
|
suite.keeper.InsertIntoByBlockIndex(blockCtx, atomicSwap)
|
|
// Add to local block index
|
|
testCases = append(testCases, args{blockCtx, atomicSwap})
|
|
}
|
|
|
|
// Set up the expected swap IDs for a given cutoff block
|
|
cutoffBlock := int64(450)
|
|
var expectedSwapIDs [][]byte
|
|
for _, tc := range testCases {
|
|
if tc.blockCtx.BlockHeight() < cutoffBlock || tc.blockCtx.BlockHeight() == cutoffBlock {
|
|
expectedSwapIDs = append(expectedSwapIDs, tc.swap.GetSwapID())
|
|
}
|
|
}
|
|
|
|
// Read the swap IDs from store for a given cutoff block
|
|
var readSwapIDs [][]byte
|
|
suite.keeper.IterateAtomicSwapsByBlock(suite.ctx, uint64(cutoffBlock), func(id []byte) bool {
|
|
readSwapIDs = append(readSwapIDs, id)
|
|
return false
|
|
})
|
|
|
|
suite.Equal(expectedSwapIDs, readSwapIDs)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestInsertIntoLongtermStorage() {
|
|
suite.ResetChain()
|
|
|
|
// Set atomic swap in longterm storage
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
atomicSwap.ClosedBlock = suite.ctx.BlockHeight()
|
|
suite.keeper.InsertIntoLongtermStorage(suite.ctx, atomicSwap)
|
|
|
|
// Longterm storage lacks getter methods, must use iteration to get count of swaps in store
|
|
var swapIDs [][]byte
|
|
suite.keeper.IterateAtomicSwapsLongtermStorage(suite.ctx, uint64(atomicSwap.ClosedBlock+LongtermStorageDuration), func(id []byte) bool {
|
|
swapIDs = append(swapIDs, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDs), 1)
|
|
|
|
// Marshal the expected swapID
|
|
cdc := suite.app.Codec()
|
|
res, _ := cdc.MarshalBinaryBare(atomicSwap.GetSwapID())
|
|
expectedSwapID := res[1:]
|
|
|
|
suite.Equal(expectedSwapID, swapIDs[0])
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestRemoveFromLongtermStorage() {
|
|
suite.ResetChain()
|
|
|
|
// Set atomic swap in longterm storage
|
|
atomicSwap := atomicSwap(suite.ctx, 1)
|
|
atomicSwap.ClosedBlock = suite.ctx.BlockHeight()
|
|
suite.keeper.InsertIntoLongtermStorage(suite.ctx, atomicSwap)
|
|
|
|
// Longterm storage lacks getter methods, must use iteration to get count of swaps in store
|
|
var swapIDs [][]byte
|
|
suite.keeper.IterateAtomicSwapsLongtermStorage(suite.ctx, uint64(atomicSwap.ClosedBlock+LongtermStorageDuration), func(id []byte) bool {
|
|
swapIDs = append(swapIDs, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDs), 1)
|
|
|
|
suite.keeper.RemoveFromLongtermStorage(suite.ctx, atomicSwap)
|
|
|
|
// Check stored data not in block index
|
|
var swapIDsPost [][]byte
|
|
suite.keeper.IterateAtomicSwapsLongtermStorage(suite.ctx, uint64(atomicSwap.ClosedBlock+LongtermStorageDuration), func(id []byte) bool {
|
|
swapIDsPost = append(swapIDsPost, id)
|
|
return false
|
|
})
|
|
suite.Equal(len(swapIDsPost), 0)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestIterateAtomicSwapsLongtermStorage() {
|
|
suite.ResetChain()
|
|
|
|
// Set up atomic swaps with stagged closed blocks
|
|
var swaps types.AtomicSwaps
|
|
for i := 0; i < 8; i++ {
|
|
timestamp := tmtime.Now().Unix()
|
|
randomNumber, _ := types.GenerateSecureRandomNumber()
|
|
randomNumberHash := types.CalculateRandomHash(randomNumber[:], timestamp)
|
|
|
|
atomicSwap := types.NewAtomicSwap(cs(c("bnb", 50000)), randomNumberHash,
|
|
uint64(suite.ctx.BlockHeight()), timestamp, TestUser1, TestUser2,
|
|
TestSenderOtherChain, TestRecipientOtherChain, 100, types.Open,
|
|
true, types.Incoming)
|
|
|
|
// Set closed block staggered by 100 blocks and insert into longterm storage
|
|
atomicSwap.ClosedBlock = int64(i) * 100
|
|
suite.keeper.InsertIntoLongtermStorage(suite.ctx, atomicSwap)
|
|
// Add to local longterm storage
|
|
swaps = append(swaps, atomicSwap)
|
|
}
|
|
|
|
// Set up the expected swap IDs for a given cutoff block.
|
|
cutoffBlock := int64(LongtermStorageDuration + 350)
|
|
var expectedSwapIDs [][]byte
|
|
for _, swap := range swaps {
|
|
if swap.ClosedBlock+LongtermStorageDuration < cutoffBlock ||
|
|
swap.ClosedBlock+LongtermStorageDuration == cutoffBlock {
|
|
expectedSwapIDs = append(expectedSwapIDs, swap.GetSwapID())
|
|
}
|
|
}
|
|
|
|
// Read the swap IDs from store for a given cutoff block
|
|
var readSwapIDs [][]byte
|
|
suite.keeper.IterateAtomicSwapsLongtermStorage(suite.ctx, uint64(cutoffBlock), func(id []byte) bool {
|
|
readSwapIDs = append(readSwapIDs, id)
|
|
return false
|
|
})
|
|
|
|
// At the cutoff block, iteration should return half of the swap IDs
|
|
suite.Equal(len(swaps)/2, len(expectedSwapIDs))
|
|
suite.Equal(len(swaps)/2, len(readSwapIDs))
|
|
// Should be the same IDs
|
|
suite.Equal(expectedSwapIDs, readSwapIDs)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestGetSetAssetSupply() {
|
|
suite.ResetChain()
|
|
|
|
denom := "bnb"
|
|
// Put asset supply in store
|
|
assetSupply := types.NewAssetSupply(denom, c(denom, 0), c(denom, 0), c(denom, 50000), c(denom, 100000))
|
|
suite.keeper.SetAssetSupply(suite.ctx, assetSupply, []byte(denom))
|
|
|
|
// Check asset in store
|
|
storedAssetSupply, found := suite.keeper.GetAssetSupply(suite.ctx, []byte(denom))
|
|
suite.True(found)
|
|
suite.Equal(assetSupply, storedAssetSupply)
|
|
|
|
// Check fake asset supply not in store
|
|
fakeDenom := "xyz"
|
|
_, found = suite.keeper.GetAssetSupply(suite.ctx, []byte(fakeDenom))
|
|
suite.False(found)
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestIterateAssetSupplies() {
|
|
suite.ResetChain()
|
|
|
|
// Set asset supplies
|
|
supplies := assetSupplies(5)
|
|
for _, supply := range supplies {
|
|
suite.keeper.SetAssetSupply(suite.ctx, supply, []byte(supply.Denom))
|
|
}
|
|
|
|
// Read each asset supply from the store
|
|
var readSupplies types.AssetSupplies
|
|
suite.keeper.IterateAssetSupplies(suite.ctx, func(a types.AssetSupply) bool {
|
|
readSupplies = append(readSupplies, a)
|
|
return false
|
|
})
|
|
|
|
// Check expected values
|
|
for i := 0; i < len(supplies); i++ {
|
|
suite.Contains(readSupplies, supplies[i])
|
|
}
|
|
}
|
|
|
|
func (suite *KeeperTestSuite) TestGetAllAssetSupplies() {
|
|
suite.ResetChain()
|
|
|
|
// Set asset supplies
|
|
count := 3
|
|
supplies := assetSupplies(count)
|
|
for _, supply := range supplies {
|
|
suite.keeper.SetAssetSupply(suite.ctx, supply, []byte(supply.Denom))
|
|
}
|
|
|
|
// Get all asset supplies
|
|
readSupplies := suite.keeper.GetAllAssetSupplies(suite.ctx)
|
|
suite.Equal(count, len(readSupplies))
|
|
|
|
// Check expected values
|
|
for i := 0; i < count; i++ {
|
|
suite.Contains(readSupplies, supplies[i])
|
|
}
|
|
}
|
|
|
|
func TestKeeperTestSuite(t *testing.T) {
|
|
suite.Run(t, new(KeeperTestSuite))
|
|
}
|