Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(appchain): add unit tests #225

Closed
Closed
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
53177cf
feat(appchain): scaffold coordinator
MaxMustermann2 Aug 25, 2024
8ee1253
feat(appchain): scaffold subscriber
MaxMustermann2 Aug 25, 2024
a1158d5
feat(epochs): create number + id structure
MaxMustermann2 Aug 26, 2024
7c1922a
feat(appchain): add coordinator params
MaxMustermann2 Aug 26, 2024
f1bca4d
fix(epochs): invalidate negative duration
MaxMustermann2 Aug 27, 2024
9f9e994
fix(avs): stateful validation of staking assets
MaxMustermann2 Aug 27, 2024
0e1cd06
refactor(dogfood): carve `sortByPower` out
MaxMustermann2 Aug 27, 2024
9073b71
fix(dogfood): avoid duplicate validation
MaxMustermann2 Aug 27, 2024
e06c529
fix(dogfood): replace with max unbonding duration
MaxMustermann2 Aug 27, 2024
04e0d67
doc(app): add comment about slashing frac storage
MaxMustermann2 Aug 27, 2024
2f594b7
feat(appchain): allow sub chain creation
MaxMustermann2 Aug 27, 2024
4bd8948
chore(lint)
MaxMustermann2 Aug 31, 2024
13e6a72
Merge `develop`
MaxMustermann2 Aug 31, 2024
571c65e
fix(test): make avs test pass
MaxMustermann2 Aug 31, 2024
6f4cfa0
fix(appchain): remove superfluous test
MaxMustermann2 Aug 31, 2024
19ce74a
fix(epochs): update expected test message
MaxMustermann2 Aug 31, 2024
0a0688c
chore(lint)
MaxMustermann2 Aug 31, 2024
6cb92fc
chore(lint): proto lint
MaxMustermann2 Aug 31, 2024
ca8b2ee
chore: run proto gen
MaxMustermann2 Aug 31, 2024
cfba037
fix(appchain): remove floating point arithmetic
MaxMustermann2 Aug 31, 2024
013f938
fix(appchain): remove wrong comment
MaxMustermann2 Aug 31, 2024
dc7915d
doc(appchain): add comment about params expect
MaxMustermann2 Aug 31, 2024
607e12e
fix(appchain): remove superfluous fmt
MaxMustermann2 Aug 31, 2024
4a275d3
feat(appchain): report invalid json
MaxMustermann2 Aug 31, 2024
e9d8fc0
fix(utils): remove SliceStable and use Slice
MaxMustermann2 Aug 31, 2024
3be6882
doc(appchain): add more logging
MaxMustermann2 Aug 31, 2024
4401e3f
chore(lint)
MaxMustermann2 Aug 31, 2024
47714fc
fix(ci): pin the golang lint version
MaxMustermann2 Aug 31, 2024
2904a40
chore(lint): remove unused timestamp proto
MaxMustermann2 Aug 31, 2024
8d0db6c
refactor(dogfood,operator): carve out wrapped key
MaxMustermann2 Sep 1, 2024
079953e
feat(subscriber): load genesis validators
MaxMustermann2 Sep 1, 2024
eb18ccb
fix: unnecessary parent code import
MaxMustermann2 Sep 1, 2024
f99dbca
fix: remove double proto warning
MaxMustermann2 Sep 1, 2024
79833d5
refactor(operator): carve out AppendMany
MaxMustermann2 Sep 2, 2024
b12b362
feat(appchain): load subscriber genesis, ibc
MaxMustermann2 Sep 2, 2024
e2b541d
part 2 commit including handling
MaxMustermann2 Sep 9, 2024
0d235bb
Merge develop
MaxMustermann2 Sep 9, 2024
9b21e48
fix build
MaxMustermann2 Sep 9, 2024
a8a8d1f
chore: lint the proto file
MaxMustermann2 Sep 9, 2024
05cee6d
attempt to fix tests
MaxMustermann2 Sep 9, 2024
bd43d6a
fix retry
MaxMustermann2 Sep 9, 2024
f080f54
Merge develop
MaxMustermann2 Sep 9, 2024
5acf528
Fix tests
MaxMustermann2 Sep 9, 2024
00c8707
chore: fix lint by removing duplicated imports
MaxMustermann2 Sep 9, 2024
5438d85
chore: proto lint
MaxMustermann2 Sep 9, 2024
617d774
feat(appchains): part 4 PR
MaxMustermann2 Sep 10, 2024
8262852
Merge develop
MaxMustermann2 Sep 10, 2024
075fccf
fix: golang lint
MaxMustermann2 Sep 10, 2024
7b7058a
Merge branch 'develop' into appchains-pt2
MaxMustermann2 Oct 13, 2024
985e606
fix: respond to AI comments
MaxMustermann2 Oct 13, 2024
b52b87a
chore(appchain): golang lint
MaxMustermann2 Oct 13, 2024
dd499d1
respond to more AI comments
MaxMustermann2 Oct 13, 2024
14d4cb8
Merge branch 'appchains-pt2' into appchains-pt3
MaxMustermann2 Oct 13, 2024
2e88063
asd
MaxMustermann2 Oct 14, 2024
8e931aa
app: introduce coordinator module
MaxMustermann2 Oct 18, 2024
7ecbfbf
Merge `develop`
MaxMustermann2 Oct 18, 2024
ccacb00
app: introduce coordinator module
MaxMustermann2 Oct 18, 2024
dd31488
fix: use NST instead of LST (#213)
leonz789 Oct 14, 2024
0ba5f43
add rest api to query token-index, update price-feeder to panic at er…
leonz789 Oct 14, 2024
14a69e5
fix: update cache when assetID updated in params (#214)
leonz789 Oct 14, 2024
75b6b09
fix(abci): adjust the error handling in beginBlock and endBlock (#207)
TimmyExogenous Oct 15, 2024
5b55dab
add oracle_env_beaconchain yaml config in local_node (#215)
cloud8little Oct 15, 2024
1cc8dfb
fix(audit): Fix audit issues (#188)
trestinlsd Oct 15, 2024
19d48dd
feat(operator): Add cli to query opt info (#216)
TimmyExogenous Oct 17, 2024
875ab5a
fix(audit): resolve more audit findings (#217)
MaxMustermann2 Oct 18, 2024
9ae4d76
tests(coordinator): add unit tests
MaxMustermann2 Oct 22, 2024
b317602
test(subscriber): add subscriber unit tests
MaxMustermann2 Oct 22, 2024
7e167be
fix(test): fix the reward unit test
MaxMustermann2 Oct 22, 2024
c0a5c0b
Merge `develop` into this branch
MaxMustermann2 Oct 22, 2024
c59c3e2
fix(app): add module correctly
MaxMustermann2 Oct 22, 2024
6d05c8b
Merge branch 'appchains-pt3' into appchains-pt4
MaxMustermann2 Oct 22, 2024
cfca848
refactor: rename function param for clarity
MaxMustermann2 Oct 28, 2024
0ca361d
refactor: rename object for clarity
MaxMustermann2 Oct 28, 2024
f9554f2
Merge `develop`
MaxMustermann2 Oct 28, 2024
e7a6165
Merge branch 'appchains-pt2' into appchains-pt3
MaxMustermann2 Oct 28, 2024
4243cd8
Merge branch 'appchains-pt3' into appchains-pt4
MaxMustermann2 Oct 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 44 additions & 16 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ import (
// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
_ "github.com/ethereum/go-ethereum/eth/tracers/native"

"github.com/ExocoreNetwork/exocore/x/appchain/coordinator"
coordinatorkeeper "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/keeper"
coordinatortypes "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"
)

// Name defines the application binary name
Expand Down Expand Up @@ -274,6 +278,7 @@ var (
avs.AppModuleBasic{},
oracle.AppModuleBasic{},
distr.AppModuleBasic{},
coordinator.AppModuleBasic{},
)

// module account permissions
Expand Down Expand Up @@ -351,15 +356,16 @@ type ExocoreApp struct {
EpochsKeeper epochskeeper.Keeper

// exocore assets module keepers
AssetsKeeper assetsKeeper.Keeper
DelegationKeeper delegationKeeper.Keeper
RewardKeeper rewardKeeper.Keeper
OperatorKeeper operatorKeeper.Keeper
ExoSlashKeeper slashKeeper.Keeper
AVSManagerKeeper avsManagerKeeper.Keeper
OracleKeeper oracleKeeper.Keeper
ExomintKeeper exomintkeeper.Keeper
DistrKeeper distrkeeper.Keeper
AssetsKeeper assetsKeeper.Keeper
DelegationKeeper delegationKeeper.Keeper
RewardKeeper rewardKeeper.Keeper
OperatorKeeper operatorKeeper.Keeper
ExoSlashKeeper slashKeeper.Keeper
AVSManagerKeeper avsManagerKeeper.Keeper
OracleKeeper oracleKeeper.Keeper
ExomintKeeper exomintkeeper.Keeper
DistrKeeper distrkeeper.Keeper
CoordinatorKeeper coordinatorkeeper.Keeper

// the module manager
mm *module.Manager
Expand Down Expand Up @@ -445,6 +451,7 @@ func NewExocoreApp(
oracleTypes.StoreKey,
exominttypes.StoreKey,
distrtypes.StoreKey,
coordinatortypes.StoreKey,
)

tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey)
Expand Down Expand Up @@ -621,6 +628,7 @@ func NewExocoreApp(
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName)
scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName)
scopedIBCProviderKeeper := app.CapabilityKeeper.ScopeToModule(coordinatortypes.ModuleName)
// Applications that wish to enforce statically created ScopedKeepers should call `Seal`
// after creating their scoped modules in `NewApp` with `ScopeToModule`
app.CapabilityKeeper.Seal()
Expand Down Expand Up @@ -787,22 +795,42 @@ func NewExocoreApp(

app.IBCKeeper.SetRouter(ibcRouter)

// we are the x/appchain coordinator chain, so we add the keeper, but
// it's added after IBC to allow communication between chains.
app.CoordinatorKeeper = coordinatorkeeper.NewKeeper(
appCodec, keys[coordinatortypes.StoreKey],
app.AVSManagerKeeper, app.EpochsKeeper, app.OperatorKeeper,
app.StakingKeeper, app.DelegationKeeper,
app.IBCKeeper.ClientKeeper, &app.IBCKeeper.PortKeeper,
scopedIBCProviderKeeper, app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ConnectionKeeper, app.AccountKeeper,
)

// set the hooks at the end, after all modules are instantiated.
(&app.OperatorKeeper).SetHooks(
app.StakingKeeper.OperatorHooks(),
operatorTypes.NewMultiOperatorHooks(
// the order is not super relevant because these functions are independent
app.StakingKeeper.OperatorHooks(),
app.CoordinatorKeeper.OperatorHooks(),
),
)

(&app.DelegationKeeper).SetHooks(
app.StakingKeeper.DelegationHooks(),
delegationTypes.NewMultiDelegationHooks(
// the order is not super relevant because these functions are independent
app.StakingKeeper.DelegationHooks(),
app.CoordinatorKeeper.DelegationHooks(),
),
)

(&app.EpochsKeeper).SetHooks(
epochstypes.NewMultiEpochHooks(
app.DistrKeeper.EpochsHooks(), // come first for using the voting power of last epoch
app.OperatorKeeper.EpochsHooks(), // must come before staking keeper so it can set the USD value
app.StakingKeeper.EpochsHooks(), // at this point, the order is irrelevant.
app.ExomintKeeper.EpochsHooks(), // however, this may change once we have distribution
app.AVSManagerKeeper.EpochsHooks(), // no-op for now
app.DistrKeeper.EpochsHooks(), // come first for using the voting power of last epoch
app.OperatorKeeper.EpochsHooks(), // must come before staking keeper so it can set the USD value
app.ExomintKeeper.EpochsHooks(), // must happen after distribution but not relevant otherwise
app.StakingKeeper.EpochsHooks(), // after operator == good
app.AVSManagerKeeper.EpochsHooks(), // after operator == good
app.CoordinatorKeeper.EpochsHooks(), // after operator == good
),
)

Expand Down
5 changes: 3 additions & 2 deletions precompiles/avs/avs_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package avs_test

import (
"math/big"
"time"

"cosmossdk.io/math"
assetstypes "github.com/ExocoreNetwork/exocore/x/assets/types"
avskeeper "github.com/ExocoreNetwork/exocore/x/avs/keeper"
"github.com/ExocoreNetwork/exocore/x/avs/types"
"math/big"
"time"

sdkmath "cosmossdk.io/math"
operatorKeeper "github.com/ExocoreNetwork/exocore/x/operator/keeper"
Expand Down
23 changes: 21 additions & 2 deletions proto/exocore/appchain/common/v1/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ syntax = "proto3";
package exocore.appchain.common.v1;

import "amino/amino.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "ibc/lightclients/tendermint/v1/tendermint.proto";
import "tendermint/abci/types.proto";
Expand All @@ -26,7 +28,7 @@ message SubscriberParams {
// the rewards from the subscriber to the coordinator. It is used in the event
// that a channel between coordinator and subscriber exists prior to the
// provision of security from Exocore to the appchain. Until a changeover
// process is implemented, it is currently unused. (TODO). The advantage
// process is implemented, it is currently unused (TODO). The advantage
// of reusing a channel that was already in place is that the coin denomination
// which contains a hash of the channel name will remain unchanged.
string distribution_transmission_channel = 2;
Expand Down Expand Up @@ -101,7 +103,24 @@ message CoordinatorInfo {
ibc.lightclients.tendermint.v1.ClientState client_state = 1;
// consensus_state is the consensus state of the coordinator chain.
ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2;
// initial_val_set is the initial validator set of the coordinator chain.
// initial_val_set is the initial validator set of the subscriber chain.
repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3
[ (gogoproto.nullable) = false ];
}

// SubscriberValidator is a validator structure on the subscriber chain. It is stored
// within the subscriber module, indexed by a prefix + consensus address, and
// within the coordinator module, indexed by a prefix + chain id + consensus address.
message SubscriberValidator {
// address, as derived from the consensus key. No correlation with the operator
// address on Exocore.
bytes cons_address = 1;
// power is the vote power of the validator
int64 power = 2;
// pubkey is the consensus public key of the validator, as a Protobuf Any.
// this type is chosen to match the x/staking/validator type.
google.protobuf.Any pubkey = 3 [
(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey",
(gogoproto.moretags) = "yaml:\"consensus_pubkey\""
];
}
87 changes: 87 additions & 0 deletions proto/exocore/appchain/common/v1/wire.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
syntax = "proto3";

package exocore.appchain.common.v1;

import "cosmos/staking/v1beta1/staking.proto";
import "gogoproto/gogo.proto";
import "tendermint/abci/types.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types";

// This file containts all of the information that is sent over the wire by either
// the coordinator or each of the subcribers.

message HandshakeMetadata {
// coordinator_fee_pool_addr is the address on the coordinator to which the
// subscriber chain will send the fees proportionally and periodically.
string coordinator_fee_pool_addr = 1;
// version is the version of the appchain protocol
string version = 2;
}

// SlashPacketData is sent from the subscriber chain to the coordinator chain
// to request the slashing of a validator as a result of an infraction committed
// on the subscriber chain.
message SlashPacketData {
// validator is the validator to be slashed
tendermint.abci.Validator validator = 1 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"validator\""
];
// valset_update_id is the id of the validator set change during which
// the infraction was committed
uint64 valset_update_id = 2 [ (gogoproto.customname) = "ValsetUpdateID" ];
// infraction refers to the type of infraction committed
cosmos.staking.v1beta1.Infraction infraction = 3;
}

// VscMaturedPacketData is sent from the subscriber chain to the coordinator chain
// to indicate that a VSC has matured and unbondings associated with that VSC
// can now be released.
message VscMaturedPacketData {
// valset_update_id is the id of the validator set change to mature.
uint64 valset_update_id = 1 [ (gogoproto.customname) = "ValsetUpdateID" ];
}

// SubscriberPacketData is the enum to identify the type of packet sent.
enum SubscriberPacketDataType {
option (gogoproto.goproto_enum_prefix) = false;
// SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED is the default value
SUBSCRIBER_PACKET_DATA_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "UnspecifiedPacket" ];
// SUBSCRIBER_PACKET_DATA_TYPE_SLASH is the type of packet sent when a subscriber
// chain wants to request the slashing of a validator on the coordinator chain.
SUBSCRIBER_PACKET_DATA_TYPE_SLASH = 1 [ (gogoproto.enumvalue_customname) = "SlashPacket" ];
// SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED is the type of packet sent when a subscriber
// chain wants to indicate that a VSC has matured and unbondings associated with
// that VSC can now be released.
SUBSCRIBER_PACKET_DATA_TYPE_VSC_MATURED = 2 [ (gogoproto.enumvalue_customname) = "VscMaturedPacket" ];
}

// SubscriberPacketData is a wrapped message that contains the type of packet
// and the data associated with that packet.
message SubscriberPacketData {
// type is the type of packet sent
SubscriberPacketDataType type = 1;
// data is the data associated with the packet
oneof data {
// slash_packet_data is the data associated with a SlashPacket
SlashPacketData slash_packet_data = 2;
// vsc_matured_packet_data is the data associated with a VscMaturedPacket
VscMaturedPacketData vsc_matured_packet_data = 3;
}
}

// ValidatorSetChangePacketData is sent from the coordinator chain to the subscriber chain
// containing the new validator set and the id of the validator set change.
message ValidatorSetChangePacketData {
// validator_updates is the edits to the existing validator set
repeated .tendermint.abci.ValidatorUpdate validator_updates = 1 [
(gogoproto.nullable) = false,
(gogoproto.moretags) = "yaml:\"validator_updates\""
];
// valset_update_id is the id of the validator set change
uint64 valset_update_id = 2 [(gogoproto.customname) = "ValsetUpdateID"];
// slash_acks is the list of consensus addresses slashed on the coordinator chain,
// in response to such requests from the subscriber chain.
repeated bytes slash_acks = 3;
}
19 changes: 19 additions & 0 deletions proto/exocore/appchain/coordinator/v1/coordinator.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";

package exocore.appchain.coordinator.v1;

import "exocore/appchain/common/v1/wire.proto";
import "exocore/appchain/coordinator/v1/tx.proto";
import "gogoproto/gogo.proto";

Expand All @@ -21,3 +22,21 @@ message ChainIDs {
repeated string list = 1;
}

// ConsensusAddresses is a list of consensus addresses.
message ConsensusAddresses {
// list is the list of consensus addresses.
repeated bytes list = 1;
}

// ValidatorSetChangePackets is a helper structure to store a list of packets
message ValidatorSetChangePackets {
// list is the list of packets to be sent to the subscriber chain.
repeated .exocore.appchain.common.v1.ValidatorSetChangePacketData list = 1
[(gogoproto.nullable) = false];
}

// UndelegationRecordKeys is a collection of undelegation record keys.
message UndelegationRecordKeys {
// list is the list of undelegation record keys.
repeated bytes list = 1;
}
26 changes: 25 additions & 1 deletion proto/exocore/appchain/subscriber/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,35 @@ package exocore.appchain.subscriber.v1;

import "exocore/appchain/common/v1/common.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types";

// GenesisState is the genesis state for the appchain subscriber module.
message GenesisState {
// Params is the parameters for the appchain subscriber module.
// The first two fields are word-for-word pulled from `common.proto`, to be
// filled by the coordinator module (or an export).
// params is the parameters for the appchain subscriber module.
exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false];
// coordinator is the coordinator information for the subscriber.
exocore.appchain.common.v1.CoordinatorInfo coordinator = 2 [ (gogoproto.nullable) = false ];
// Below are the IBC parameters
// coordinator_client_id is the client id of the coordinator chain.
string coordinator_client_id = 3 [ (gogoproto.customname) = "CoordinatorClientID" ];
// coordinator_channel_id is the channel id of the coordinator chain.
string coordinator_channel_id = 4 [ (gogoproto.customname) = "CoordinatorChannelID" ];
// operational parameters that are to be exported can go here.
}

// MaturingVSCPacket represents a vsc packet that is maturing internal to the
// subscriber module, where it has not yet relayed a VSCMatured packet back.
// While it is technically feasible to store this just as a key in the state,
// keeping it as a separate type allows exporting the genesis data.
// The key used is prefix + time + vscId.
message MaturingVSCPacket {
// vsc_id is the id of the VSC that is maturing.
uint64 vsc_id = 1 [ (gogoproto.customname) = "ValidatorSetChangeID" ];
// maturity_time is the time at which the VSC will mature.
google.protobuf.Timestamp maturity_time = 2
[ (gogoproto.stdtime) = true, (gogoproto.nullable) = false ];
}
Loading
Loading