mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 23:08:32 +00:00 
			
		
		
		
	Migration: reset bep3 swap heights (#1013)
* add null bep3 migration * add bep3 height resets * minor refactor * add test using real genesis state
This commit is contained in:
		
							parent
							
								
									8d0bb5a5b0
								
							
						
					
					
						commit
						8691ac44ed
					
				
							
								
								
									
										34
									
								
								migrate/v0_15/bep3.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								migrate/v0_15/bep3.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| package v0_15 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	v0_15bep3 "github.com/kava-labs/kava/x/bep3/types" | ||||
| ) | ||||
| 
 | ||||
| // Bep3 resets the swap expire/close heights for a chain starting at height 0.
 | ||||
| func Bep3(genesisState v0_15bep3.GenesisState) v0_15bep3.GenesisState { | ||||
| 
 | ||||
| 	var newSwaps v0_15bep3.AtomicSwaps | ||||
| 	for _, swap := range genesisState.AtomicSwaps { | ||||
| 
 | ||||
| 		switch status := swap.Status; status { | ||||
| 		case v0_15bep3.Completed: | ||||
| 			// reset closed block to one so completed swaps are removed from long term storage properly
 | ||||
| 			swap.ClosedBlock = 1 | ||||
| 
 | ||||
| 		case v0_15bep3.Open, v0_15bep3.Expired: | ||||
| 			swap.Status = v0_15bep3.Expired // set open swaps to expired so they can be refunded (by tx) after chain start
 | ||||
| 			swap.ExpireHeight = 1           // set expire on first block as well to be safe
 | ||||
| 
 | ||||
| 		default: | ||||
| 			panic(fmt.Sprintf("unknown bep3 swap status '%s'", status)) | ||||
| 		} | ||||
| 
 | ||||
| 		newSwaps = append(newSwaps, swap) | ||||
| 	} | ||||
| 
 | ||||
| 	genesisState.AtomicSwaps = newSwaps | ||||
| 
 | ||||
| 	return genesisState | ||||
| } | ||||
							
								
								
									
										99
									
								
								migrate/v0_15/bep3_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								migrate/v0_15/bep3_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | ||||
| package v0_15 | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/bep3" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	exampleExportTime = time.Date(1998, 1, 1, 0, 0, 0, 0, time.UTC) | ||||
| 	exampleBep3Params = bep3.NewParams(bep3.AssetParams{ | ||||
| 		bep3.NewAssetParam( | ||||
| 			"xrpb", | ||||
| 			144, | ||||
| 			bep3.SupplyLimit{}, | ||||
| 			true, | ||||
| 			sdk.AccAddress("testAddress"), | ||||
| 			sdk.NewInt(1e4), | ||||
| 			sdk.NewInt(1e4), | ||||
| 			sdk.NewInt(1e14), | ||||
| 			24686, | ||||
| 			86400, | ||||
| 		), | ||||
| 	}) | ||||
| 	exampleAssetSupplies = bep3.AssetSupplies{ | ||||
| 		bep3.NewAssetSupply( | ||||
| 			sdk.NewInt64Coin("xrpb", 1e10), | ||||
| 			sdk.NewInt64Coin("xrpb", 1e9), | ||||
| 			sdk.NewInt64Coin("xrpb", 1e15), | ||||
| 			sdk.NewInt64Coin("xrpb", 0), | ||||
| 			0, | ||||
| 		), | ||||
| 	} | ||||
| 	exampleBep3GenState = bep3.NewGenesisState( | ||||
| 		exampleBep3Params, | ||||
| 		bep3.AtomicSwaps{}, | ||||
| 		exampleAssetSupplies, | ||||
| 		exampleExportTime, | ||||
| 	) | ||||
| ) | ||||
| 
 | ||||
| func exampleBep3Swap(expireHeight uint64, closeHeight int64, status bep3.SwapStatus) bep3.AtomicSwap { | ||||
| 	return bep3.NewAtomicSwap( | ||||
| 		sdk.NewCoins(sdk.NewInt64Coin("xrpb", 1e10)), | ||||
| 		[]byte("random number hash"), | ||||
| 		expireHeight, | ||||
| 		exampleExportTime.Unix(), | ||||
| 		sdk.AccAddress("sender address"), | ||||
| 		sdk.AccAddress("recipient address"), | ||||
| 		"sender other chain address", | ||||
| 		"recipient other chain address", | ||||
| 		closeHeight, | ||||
| 		status, | ||||
| 		true, | ||||
| 		bep3.Outgoing, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func TestBep3_SwapHeightsAreReset(t *testing.T) { | ||||
| 
 | ||||
| 	oldState := bep3.NewGenesisState( | ||||
| 		exampleBep3Params, | ||||
| 		bep3.AtomicSwaps{ | ||||
| 			exampleBep3Swap(7e5, 6e5, bep3.Open), | ||||
| 			exampleBep3Swap(4e5, 3e5, bep3.Expired), | ||||
| 			exampleBep3Swap(2e5, 1e5, bep3.Completed), | ||||
| 		}, | ||||
| 		exampleAssetSupplies, | ||||
| 		exampleExportTime, | ||||
| 	) | ||||
| 
 | ||||
| 	newState := Bep3(oldState) | ||||
| 
 | ||||
| 	expectedSwaps := bep3.AtomicSwaps{ | ||||
| 		exampleBep3Swap(1, 6e5, bep3.Expired), | ||||
| 		exampleBep3Swap(1, 3e5, bep3.Expired), | ||||
| 		exampleBep3Swap(2e5, 1, bep3.Completed), | ||||
| 	} | ||||
| 
 | ||||
| 	require.Equal(t, expectedSwaps, newState.AtomicSwaps) | ||||
| } | ||||
| 
 | ||||
| func TestBep3_OnlySwapHeightsModified(t *testing.T) { | ||||
| 
 | ||||
| 	oldState := bep3.NewGenesisState( | ||||
| 		exampleBep3Params, | ||||
| 		nil, | ||||
| 		exampleAssetSupplies, | ||||
| 		exampleExportTime, | ||||
| 	) | ||||
| 
 | ||||
| 	newState := Bep3(oldState) | ||||
| 
 | ||||
| 	require.Equal(t, oldState, newState) | ||||
| } | ||||
| @ -15,6 +15,7 @@ import ( | ||||
| 	tmtypes "github.com/tendermint/tendermint/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	v0_15bep3 "github.com/kava-labs/kava/x/bep3/types" | ||||
| 	v0_15cdp "github.com/kava-labs/kava/x/cdp/types" | ||||
| 	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14" | ||||
| 	v0_15committee "github.com/kava-labs/kava/x/committee/types" | ||||
| @ -27,7 +28,6 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// TODO: update GenesisTime and chain-id for kava-8 launch
 | ||||
| 	GenesisTime                  = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC) | ||||
| 	ChainID                      = "kava-8" | ||||
| 	SwpDelegatorRewardsPerSecond = sdk.NewCoin("swp", sdk.NewInt(198186)) | ||||
| @ -114,6 +114,16 @@ func MigrateAppState(v0_14AppState genutil.AppMap) { | ||||
| 		v0_14AppState[v0_15committee.ModuleName] = v0_15Codec.MustMarshalJSON(Committee(committeeGS)) | ||||
| 	} | ||||
| 
 | ||||
| 	// Migrate bep3 app state
 | ||||
| 	if v0_14AppState[v0_15bep3.ModuleName] != nil { | ||||
| 		// Unmarshal genesis state and delete it. The genesis format was not changed between v0.14 and v0.15.
 | ||||
| 		var bep3GenState v0_15bep3.GenesisState | ||||
| 		v0_14Codec.MustUnmarshalJSON(v0_14AppState[v0_15bep3.ModuleName], &bep3GenState) | ||||
| 		delete(v0_14AppState, v0_15bep3.ModuleName) | ||||
| 
 | ||||
| 		v0_14AppState[v0_15bep3.ModuleName] = v0_15Codec.MustMarshalJSON(Bep3(bep3GenState)) | ||||
| 	} | ||||
| 
 | ||||
| 	v0_14AppState[v0_15swap.ModuleName] = v0_15Codec.MustMarshalJSON(Swap()) | ||||
| } | ||||
| 
 | ||||
| @ -127,6 +137,7 @@ func makeV014Codec() *codec.Codec { | ||||
| 	v0_14validator_vesting.RegisterCodec(cdc) | ||||
| 	v0_14committee.RegisterCodec(cdc) | ||||
| 	v0_14incentive.RegisterCodec(cdc) | ||||
| 	// TODO bep3?
 | ||||
| 	return cdc | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -19,6 +19,7 @@ import ( | ||||
| 	tmtypes "github.com/tendermint/tendermint/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	v0_15bep3 "github.com/kava-labs/kava/x/bep3/types" | ||||
| 	v0_15cdp "github.com/kava-labs/kava/x/cdp/types" | ||||
| 	v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14" | ||||
| 	v0_15committee "github.com/kava-labs/kava/x/committee/types" | ||||
| @ -728,3 +729,45 @@ func TestAuth_SwpSupply_SpendableCoins(t *testing.T) { | ||||
| 	require.True(t, foundEcosystem) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func TestBep3_Full(t *testing.T) { | ||||
| 	t.Skip() // skip to avoid having to commit a large genesis file to the repo
 | ||||
| 
 | ||||
| 	genDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "genesis.json")) | ||||
| 	require.NoError(t, err) | ||||
| 
 | ||||
| 	cdc := makeV014Codec() | ||||
| 
 | ||||
| 	var oldState genutil.AppMap | ||||
| 	cdc.MustUnmarshalJSON(genDoc.AppState, &oldState) | ||||
| 
 | ||||
| 	var oldGenState v0_15bep3.GenesisState | ||||
| 	cdc.MustUnmarshalJSON(oldState[v0_15bep3.ModuleName], &oldGenState) | ||||
| 
 | ||||
| 	newGenState := Bep3(oldGenState) | ||||
| 
 | ||||
| 	require.NoError(t, newGenState.Validate()) | ||||
| 
 | ||||
| 	require.Equal(t, oldGenState.Params, newGenState.Params) | ||||
| 	require.Equal(t, oldGenState.Supplies, newGenState.Supplies) | ||||
| 	require.Equal(t, oldGenState.PreviousBlockTime, newGenState.PreviousBlockTime) | ||||
| 
 | ||||
| 	require.Equal(t, len(oldGenState.AtomicSwaps), len(newGenState.AtomicSwaps)) | ||||
| 
 | ||||
| 	for i, swap := range oldGenState.AtomicSwaps { | ||||
| 		newSwap := newGenState.AtomicSwaps[i] | ||||
| 
 | ||||
| 		require.Equal(t, swap.Amount, newSwap.Amount) | ||||
| 		require.Equal(t, swap.GetSwapID(), newSwap.GetSwapID()) | ||||
| 
 | ||||
| 		// check heights were reset
 | ||||
| 		switch newSwap.Status { | ||||
| 		case v0_15bep3.Completed: | ||||
| 			require.Equal(t, int64(1), newSwap.ClosedBlock) | ||||
| 		case v0_15bep3.Expired: | ||||
| 			require.Equal(t, uint64(1), newSwap.ExpireHeight) | ||||
| 		default: | ||||
| 			t.Fatalf(fmt.Sprintf("found swap with unexpected state '%s'", newSwap.Status)) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Ruaridh
						Ruaridh