Skip to content

Commit

Permalink
feat: add raw checkpoint creation (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
gitferry authored Jul 8, 2022
1 parent 209dcdc commit 66c0338
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 113 deletions.
18 changes: 12 additions & 6 deletions proto/babylon/checkpointing/checkpoint.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,24 @@ message RawCheckpointWithMeta {
RawCheckpoint ckpt = 1;
// status defines the status of the checkpoint
CheckpointStatus status = 2;
// power_sum defines the accumulated voting power for the checkpoint
uint64 power_sum = 3;
}

// CkptStatus is the status of a checkpoint.
enum CheckpointStatus {
option (gogoproto.goproto_enum_prefix) = false;

// UNCHECKPOINTED defines a checkpoint that is checkpointed on BTC.
CKPT_STATUS_UNCHECKPOINTED = 0 [(gogoproto.enumvalue_customname) = "Uncheckpointed"];
// UNCONFIRMED defines a validator that is checkpointed on BTC but not confirmed.
CKPT_STATUS_UNCONFIRMED = 1 [(gogoproto.enumvalue_customname) = "Unconfirmed"];
// CONFIRMED defines a validator that is confirmed on BTC.
CKPT_STATUS_CONFIRMED = 2 [(gogoproto.enumvalue_customname) = "Confirmed"];
// ACCUMULATING defines a checkpoint that is awaiting for BLS signatures.
CKPT_STATUS_ACCUMULATING = 0 [(gogoproto.enumvalue_customname) = "Accumulating"];
// SIGNED defines a checkpoint that has accumulated sufficient BLS signatures.
CKPT_STATUS_SIGNED = 1 [(gogoproto.enumvalue_customname) = "Unconfirmed"];
// SUBMITTED defines a checkpoint that is included on BTC.
CKPT_STATUS_SUBMITTED = 2 [(gogoproto.enumvalue_customname) = "Submitted"];
// CONFIRMED defines a checkpoint that is k-deep on BTC.
CKPT_STATUS_CONFIRMED = 3 [(gogoproto.enumvalue_customname) = "Confirmed"];
// FINALIZED defines a checkpoint that is w-deep on BTC.
CKPT_STATUS_FINALIZED = 4 [(gogoproto.enumvalue_customname) = "Finalized"];
}

// BlsSig wraps the bls sig with meta data.
Expand Down
47 changes: 47 additions & 0 deletions x/checkpointing/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package checkpointing

import (
"github.com/babylonchain/babylon/x/checkpointing/types"
"time"

"github.com/babylonchain/babylon/x/checkpointing/keeper"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
abci "github.com/tendermint/tendermint/abci/types"
)

// BeginBlocker is called at the beginning of every block.
// Upon each BeginBlock, if reaching the second block after the epoch begins, then
// - extract the LastCommitHash from the block
// - create a raw checkpoint with the status of ACCUMULATING
// - start a BLS signer which creates a BLS sig transaction and distributes it to the network

func BeginBlocker(ctx sdk.Context, k keeper.Keeper, req abci.RequestBeginBlock) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

// get the height of the last block in this epoch
epochBoundary := k.GetEpochBoundary(ctx)
// if this block is the second block of an epoch
// TODO: it's not correct, we want the epoch boundary of the previous epoch
if uint64(ctx.BlockHeight())-2 == epochBoundary.Uint64() {
// note that this epochNum is obtained before the BeginBlocker of the epoching module is executed
// meaning that the epochNum has not been incremented upon a new epoch
epochNum := k.GetEpochNumber(ctx)
lch := ctx.BlockHeader().LastCommitHash
err := k.BuildRawCheckpoint(ctx, epochNum, lch)
if err != nil {
panic("failed to generate a raw checkpoint")
}

// emit BeginEpoch event
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeRawCheckpointGenerated,
sdk.NewAttribute(types.AttributeKeyEpochNumber, k.GetEpochNumber(ctx).String()),
),
})

// TODO: call BLS signer to send a BLS-sig transaction
}
}
15 changes: 7 additions & 8 deletions x/checkpointing/keeper/ckpt_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,20 @@ func (k Keeper) CheckpointsState(ctx sdk.Context) CheckpointsState {
store := ctx.KVStore(k.storeKey)
return CheckpointsState{
cdc: k.cdc,
checkpoints: prefix.NewStore(store, types.CheckpointsPrefix),
checkpoints: prefix.NewStore(store, types.CkptsObjectPrefix),
}
}

// CreateRawCkptWithMeta inserts the raw checkpoint with meta into the storage by its epoch number
// a new checkpoint is created with the status of UNCEHCKPOINTED
func (cs CheckpointsState) CreateRawCkptWithMeta(ckpt *types.RawCheckpoint) error {
// save concrete ckpt object
ckptWithMeta := types.NewCheckpointWithMeta(ckpt, types.Uncheckpointed)

if cs.checkpoints.Has(types.CkptsObjectKey(ckpt.EpochNum)) {
return types.ErrCkptAlreadyExist.Wrapf("a raw checkpoint already exists at epoch %v", ckpt.EpochNum)
func (cs CheckpointsState) CreateRawCkptWithMeta(ckptWithMeta *types.RawCheckpointWithMeta) error {
epoch := ckptWithMeta.Ckpt.EpochNum
if cs.checkpoints.Has(types.CkptsObjectKey(epoch)) {
return types.ErrCkptAlreadyExist.Wrapf("a raw checkpoint already exists at epoch %v", epoch)
}

cs.checkpoints.Set(types.CkptsObjectKey(ckpt.EpochNum), types.CkptWithMetaToBytes(cs.cdc, ckptWithMeta))
// save concrete ckpt object
cs.checkpoints.Set(types.CkptsObjectKey(epoch), types.CkptWithMetaToBytes(cs.cdc, ckptWithMeta))
return nil
}

Expand Down
20 changes: 16 additions & 4 deletions x/checkpointing/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,14 @@ func (k Keeper) AddBlsSig(ctx sdk.Context, sig *types.BlsSig) error {
}

// AddRawCheckpoint adds a raw checkpoint into the storage
// this API may not needed since checkpoints are generated internally
func (k Keeper) AddRawCheckpoint(ctx sdk.Context, ckpt *types.RawCheckpoint) error {
// NOTE: may remove this API
return k.CheckpointsState(ctx).CreateRawCkptWithMeta(ckpt)
func (k Keeper) AddRawCheckpoint(ctx sdk.Context, ckptWithMeta *types.RawCheckpointWithMeta) error {
return k.CheckpointsState(ctx).CreateRawCkptWithMeta(ckptWithMeta)
}

func (k Keeper) BuildRawCheckpoint(ctx sdk.Context, epochNum sdk.Uint, lch types.LastCommitHash) error {
ckptWithMeta := types.NewCheckpointWithMeta(types.NewCheckpoint(epochNum, lch), types.Accumulating)

return k.AddRawCheckpoint(ctx, ckptWithMeta)
}

// CheckpointEpoch verifies checkpoint from BTC and returns epoch number
Expand Down Expand Up @@ -105,3 +109,11 @@ func (k Keeper) UpdateCkptStatus(ctx sdk.Context, rawCkptBytes []byte, status ty
func (k Keeper) CreateRegistration(ctx sdk.Context, blsPubKey bls12381.PublicKey, valAddr types.ValidatorAddress) error {
return k.RegistrationState(ctx).CreateRegistration(blsPubKey, valAddr)
}

func (k Keeper) GetEpochBoundary(ctx sdk.Context) sdk.Uint {
return k.epochingKeeper.GetEpochBoundary(ctx)
}

func (k Keeper) GetEpochNumber(ctx sdk.Context) sdk.Uint {
return k.epochingKeeper.GetEpochNumber(ctx)
}
4 changes: 3 additions & 1 deletion x/checkpointing/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw
func (AppModule) ConsensusVersion() uint64 { return 2 }

// BeginBlock executes all ABCI BeginBlock logic respective to the capability module.
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
BeginBlocker(ctx, am.keeper, req)
}

// EndBlock executes all ABCI EndBlock logic respective to the capability module. It
// returns no validator updates.
Expand Down
39 changes: 0 additions & 39 deletions x/checkpointing/types/blssig_set.go

This file was deleted.

144 changes: 96 additions & 48 deletions x/checkpointing/types/checkpoint.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions x/checkpointing/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type StakingKeeper interface {
type EpochingKeeper interface {
GetEpochNumber(ctx sdk.Context) sdk.Uint
EnqueueMsg(ctx sdk.Context, msg epochingtypes.QueuedMessage)
GetEpochBoundary(ctx sdk.Context) sdk.Uint
}

// Event Hooks
Expand Down
Loading

0 comments on commit 66c0338

Please sign in to comment.