mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 03:07:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package keeper_test
 | 
						|
 | 
						|
import (
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/stretchr/testify/suite"
 | 
						|
 | 
						|
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
						|
 | 
						|
	tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
 | 
						|
	tmtime "github.com/cometbft/cometbft/types/time"
 | 
						|
 | 
						|
	"github.com/0glabs/0g-chain/app"
 | 
						|
	"github.com/0glabs/0g-chain/chaincfg"
 | 
						|
	"github.com/0glabs/0g-chain/x/bep3/keeper"
 | 
						|
	"github.com/0glabs/0g-chain/x/bep3/types"
 | 
						|
)
 | 
						|
 | 
						|
const LongtermStorageDuration = 86400
 | 
						|
 | 
						|
type KeeperTestSuite struct {
 | 
						|
	suite.Suite
 | 
						|
 | 
						|
	keeper keeper.Keeper
 | 
						|
	app    app.TestApp
 | 
						|
	ctx    sdk.Context
 | 
						|
}
 | 
						|
 | 
						|
func (suite *KeeperTestSuite) SetupTest() {
 | 
						|
	chaincfg.SetSDKConfig()
 | 
						|
	suite.ResetChain()
 | 
						|
}
 | 
						|
 | 
						|
func (suite *KeeperTestSuite) ResetChain() {
 | 
						|
	tApp := app.NewTestApp()
 | 
						|
	ctx := tApp.NewContext(true, tmproto.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.LegacyAmino()
 | 
						|
	res, _ := cdc.Amino.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.SWAP_STATUS_OPEN,
 | 
						|
			true, types.SWAP_DIRECTION_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.LegacyAmino()
 | 
						|
	res, _ := cdc.Amino.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.SWAP_STATUS_OPEN,
 | 
						|
			true, types.SWAP_DIRECTION_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() {
 | 
						|
	denom := "bnb"
 | 
						|
	// Put asset supply in store
 | 
						|
	assetSupply := types.NewAssetSupply(c(denom, 0), c(denom, 0), c(denom, 50000), c(denom, 0), time.Duration(0))
 | 
						|
	suite.keeper.SetAssetSupply(suite.ctx, assetSupply, denom)
 | 
						|
 | 
						|
	// Check asset in store
 | 
						|
	storedAssetSupply, found := suite.keeper.GetAssetSupply(suite.ctx, denom)
 | 
						|
	suite.True(found)
 | 
						|
	suite.Equal(assetSupply, storedAssetSupply)
 | 
						|
 | 
						|
	// Check fake asset supply not in store
 | 
						|
	fakeDenom := "xyz"
 | 
						|
	_, found = suite.keeper.GetAssetSupply(suite.ctx, fakeDenom)
 | 
						|
	suite.False(found)
 | 
						|
}
 | 
						|
 | 
						|
func (suite *KeeperTestSuite) TestGetAllAssetSupplies() {
 | 
						|
	// Put asset supply in store
 | 
						|
	assetSupply := types.NewAssetSupply(c("bnb", 0), c("bnb", 0), c("bnb", 50000), c("bnb", 0), time.Duration(0))
 | 
						|
	suite.keeper.SetAssetSupply(suite.ctx, assetSupply, "bnb")
 | 
						|
	assetSupply = types.NewAssetSupply(c("inc", 0), c("inc", 0), c("inc", 50000), c("inc", 0), time.Duration(0))
 | 
						|
	suite.keeper.SetAssetSupply(suite.ctx, assetSupply, "inc")
 | 
						|
 | 
						|
	supplies := suite.keeper.GetAllAssetSupplies(suite.ctx)
 | 
						|
	suite.Equal(2, len(supplies))
 | 
						|
}
 | 
						|
 | 
						|
func TestKeeperTestSuite(t *testing.T) {
 | 
						|
	suite.Run(t, new(KeeperTestSuite))
 | 
						|
}
 |