Skip to content

Commit

Permalink
Merge branch 'main' into evan/block-validity-rules
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-forbes committed Jun 26, 2023
2 parents f72be81 + 87812a9 commit 550e4f5
Show file tree
Hide file tree
Showing 22 changed files with 408 additions and 249 deletions.
2 changes: 1 addition & 1 deletion pkg/inclusion/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type path struct {
// calculateCommitmentPaths calculates all of the paths to subtree roots needed to
// create the commitment for a given blob.
func calculateCommitmentPaths(squareSize, start, blobShareLen, subtreeRootThreshold int) []path {
start = shares.NextShareIndex(start, blobShareLen, squareSize, subtreeRootThreshold)
start = shares.NextShareIndex(start, blobShareLen, subtreeRootThreshold)
startRow, endRow := start/squareSize, (start+blobShareLen-1)/squareSize
normalizedStartIndex := start % squareSize
normalizedEndIndex := (start + blobShareLen) - endRow*squareSize
Expand Down
56 changes: 18 additions & 38 deletions pkg/shares/blob_share_commitment_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ func FitsInSquare(cursor, squareSize, subtreeRootThreshold int, blobShareLens ..
firstBlobLen = blobShareLens[0]
}
// here we account for padding between the compact and sparse shares
cursor = NextShareIndex(cursor, firstBlobLen, squareSize, subtreeRootThreshold)
sharesUsed, _ := BlobSharesUsedNonInteractiveDefaults(cursor, squareSize, subtreeRootThreshold, blobShareLens...)
cursor = NextShareIndex(cursor, firstBlobLen, subtreeRootThreshold)
sharesUsed, _ := BlobSharesUsedNonInteractiveDefaults(cursor, subtreeRootThreshold, blobShareLens...)
return cursor+sharesUsed <= squareSize*squareSize, sharesUsed
}

// BlobSharesUsedNonInteractiveDefaults returns the number of shares used by a given set
// of blobs share lengths. It follows the blob share commitment rules and
// returns the share indexes for each blob.
func BlobSharesUsedNonInteractiveDefaults(cursor, squareSize, subtreeRootThreshold int, blobShareLens ...int) (sharesUsed int, indexes []uint32) {
func BlobSharesUsedNonInteractiveDefaults(cursor, subtreeRootThreshold int, blobShareLens ...int) (sharesUsed int, indexes []uint32) {
start := cursor
indexes = make([]uint32, len(blobShareLens))
for i, blobLen := range blobShareLens {
cursor = NextShareIndex(cursor, blobLen, squareSize, subtreeRootThreshold)
cursor = NextShareIndex(cursor, blobLen, subtreeRootThreshold)
indexes[i] = uint32(cursor)
cursor += blobLen
}
Expand All @@ -45,35 +45,25 @@ func BlobSharesUsedNonInteractiveDefaults(cursor, squareSize, subtreeRootThresho

// NextShareIndex determines the next index in a square that can be used. It
// follows the blob share commitment rules defined in ADR-013. Assumes that all
// args are non negative, and that squareSize is a power of two.
// args are non negative, that squareSize is a power of two and that the blob can
// fit in the square. The cursor is expected to be the index after the end of
// the previous blob.
//
// https://github.com/celestiaorg/celestia-specs/blob/master/src/rationale/message_block_layout.md#non-interactive-default-rules
func NextShareIndex(cursor, blobShareLen, squareSize, subtreeRootThreshold int) int {
// if we're starting at the beginning of the row, then return as there are
// no cases where we don't start at 0.
if isStartOfRow(cursor, squareSize) {
return cursor
}

// See https://github.com/celestiaorg/celestia-app/blob/main/specs/src/specs/data_square_layout.md
// for more information.
func NextShareIndex(cursor, blobShareLen, subtreeRootThreshold int) int {
// Calculate the subtreewidth. This is the width of the first mountain in the
// merkle mountain range that makes up the blob share commitment (given the
// subtreeRootThreshold and the BlobMinSquareSize).
treeWidth := SubTreeWidth(blobShareLen, subtreeRootThreshold)
startOfNextRow := getStartOfNextRow(cursor, squareSize)
cursor = roundUpBy(cursor, treeWidth)
switch {
// the entire blob fits in this row
case cursor+blobShareLen <= startOfNextRow:
return cursor
// only a portion of the blob fits in this row
case cursor+treeWidth <= startOfNextRow:
return cursor
// none of the blob fits on this row, so return the start of the next row
default:
return startOfNextRow
}
// We round up the cursor to the next multiple of this value i.e. if the cursor
// was at 13 and the tree width was 4, we return 16.
return roundUpByMultipleOf(cursor, treeWidth)
}

// roundUpBy rounds cursor up to the next multiple of v. If cursor is divisible
// roundUpByMultipleOf rounds cursor up to the next multiple of v. If cursor is divisible
// by v, then it returns cursor
func roundUpBy(cursor, v int) int {
func roundUpByMultipleOf(cursor, v int) int {
switch {
case cursor == 0:
return cursor
Expand Down Expand Up @@ -120,13 +110,3 @@ func min[T constraints.Integer](i, j T) T {
}
return j
}

// isStartOfRow returns true if cursor is at the start of a row
func isStartOfRow(cursor, squareSize int) bool {
return cursor == 0 || cursor%squareSize == 0
}

// getStartOfRow returns the index of the first share in the next row
func getStartOfNextRow(cursor, squareSize int) int {
return ((cursor / squareSize) + 1) * squareSize
}
42 changes: 21 additions & 21 deletions pkg/shares/blob_share_commitment_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,29 @@ import (

func TestBlobSharesUsedNonInteractiveDefaults(t *testing.T) {
type test struct {
cursor, squareSize, expected int
blobLens []int
indexes []uint32
cursor, expected int
blobLens []int
indexes []uint32
}
tests := []test{
{2, 4, 1, []int{1}, []uint32{2}},
{2, 2, 1, []int{1}, []uint32{2}},
{3, 4, 6, []int{3, 3}, []uint32{3, 6}},
{0, 8, 8, []int{8}, []uint32{0}},
{1, 8, 6, []int{3, 3}, []uint32{1, 4}},
{1, 8, 32, []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
{3, 8, 12, []int{5, 7}, []uint32{3, 8}},
{0, 8, 20, []int{5, 5, 5, 5}, []uint32{0, 5, 10, 15}},
{0, 8, 10, []int{10}, []uint32{0}},
{1, 8, 20, []int{10, 10}, []uint32{1, 11}},
{0, appconsts.DefaultSquareSizeUpperBound, 1000, []int{1000}, []uint32{0}},
{0, appconsts.DefaultSquareSizeUpperBound, appconsts.DefaultSquareSizeUpperBound + 1, []int{appconsts.DefaultSquareSizeUpperBound + 1}, []uint32{0}},
{1, 128, 385, []int{128, 128, 128}, []uint32{2, 130, 258}},
{1024, appconsts.DefaultSquareSizeUpperBound, 32, []int{32}, []uint32{1024}},
{2, 1, []int{1}, []uint32{2}},
{2, 1, []int{1}, []uint32{2}},
{3, 6, []int{3, 3}, []uint32{3, 6}},
{0, 8, []int{8}, []uint32{0}},
{1, 6, []int{3, 3}, []uint32{1, 4}},
{1, 32, []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
{3, 12, []int{5, 7}, []uint32{3, 8}},
{0, 20, []int{5, 5, 5, 5}, []uint32{0, 5, 10, 15}},
{0, 10, []int{10}, []uint32{0}},
{1, 20, []int{10, 10}, []uint32{1, 11}},
{0, 1000, []int{1000}, []uint32{0}},
{0, appconsts.DefaultSquareSizeUpperBound + 1, []int{appconsts.DefaultSquareSizeUpperBound + 1}, []uint32{0}},
{1, 385, []int{128, 128, 128}, []uint32{2, 130, 258}},
{1024, 32, []int{32}, []uint32{1024}},
}
for i, tt := range tests {
res, indexes := BlobSharesUsedNonInteractiveDefaults(tt.cursor, tt.squareSize, appconsts.DefaultSubtreeRootThreshold, tt.blobLens...)
test := fmt.Sprintf("test %d: cursor %d, squareSize %d", i, tt.cursor, tt.squareSize)
res, indexes := BlobSharesUsedNonInteractiveDefaults(tt.cursor, appconsts.DefaultSubtreeRootThreshold, tt.blobLens...)
test := fmt.Sprintf("test %d: cursor %d", i, tt.cursor)
assert.Equal(t, tt.expected, res, test)
assert.Equal(t, tt.indexes, indexes, test)
}
Expand Down Expand Up @@ -287,7 +287,7 @@ func TestNextShareIndex(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
res := NextShareIndex(tt.cursor, tt.blobLen, tt.squareSize, appconsts.DefaultSubtreeRootThreshold)
res := NextShareIndex(tt.cursor, tt.blobLen, appconsts.DefaultSubtreeRootThreshold)
assert.Equal(t, tt.expectedIndex, res)
})
}
Expand Down Expand Up @@ -350,7 +350,7 @@ func Test_roundUpBy(t *testing.T) {
tt.expectedIndex,
),
func(t *testing.T) {
res := roundUpBy(tt.cursor, tt.v)
res := roundUpByMultipleOf(tt.cursor, tt.v)
assert.Equal(t, tt.expectedIndex, res)
})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/square/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (b *Builder) Export() (Square, error) {
for i, element := range b.blobs {
// NextShareIndex returned where the next blob should start so as to comply with the share commitment rules
// We fill out the remaining
cursor = shares.NextShareIndex(cursor, element.numShares, ss, b.subtreeRootThreshold)
cursor = shares.NextShareIndex(cursor, element.numShares, b.subtreeRootThreshold)
if i == 0 {
nonReservedStart = cursor
}
Expand Down
10 changes: 7 additions & 3 deletions proto/celestia/mint/v1/mint.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ message Minter {
(gogoproto.nullable) = false
];

// GenesisTime is the timestamp of the genesis block.
google.protobuf.Timestamp genesis_time = 3 [ (gogoproto.stdtime) = true ];

// PreviousBlockTime is the timestamp of the previous block.
google.protobuf.Timestamp previous_block_time = 4
[ (gogoproto.stdtime) = true ];

// BondDenom is the denomination of the token that should be minted.
string bond_denom = 5;
}

// GenesisTime contains the timestamp of the genesis block.
message GenesisTime {
// GenesisTime is the timestamp of the genesis block.
google.protobuf.Timestamp genesis_time = 1
[ (gogoproto.stdtime) = true ];
}
15 changes: 9 additions & 6 deletions test/util/test_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ func (ao emptyAppOptions) Get(_ string) interface{} {
return nil
}

// SetupTestAppWithGenesisValSet initializes a new app with a validator set and genesis accounts
// that also act as delegators. For simplicity, each validator is bonded with a delegation
// of one consensus engine unit in the default token of the app from first genesis
// account. A Nop logger is set in app.
// SetupTestAppWithGenesisValSet initializes a new app with a validator set and
// genesis accounts that also act as delegators. For simplicity, each validator
// is bonded with a delegation of one consensus engine unit in the default token
// of the app from first genesis account. A no-op logger is set in app.
func SetupTestAppWithGenesisValSet(cparams *tmproto.ConsensusParams, genAccounts ...string) (*app.App, keyring.Keyring) {
// var cache sdk.MultiStorePersistentCache
// EmptyAppOptions is a stub implementing AppOptions
Expand Down Expand Up @@ -88,9 +88,12 @@ func SetupTestAppWithGenesisValSet(cparams *tmproto.ConsensusParams, genAccounts
Validator: &cparams.Validator,
}

genesisTime := time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC()

// init chain will set the validator set and initialize the genesis accounts
testApp.InitChain(
abci.RequestInitChain{
Time: genesisTime,
Validators: []abci.ValidatorUpdate{},
ConsensusParams: abciParams,
AppStateBytes: stateBytes,
Expand Down Expand Up @@ -173,8 +176,8 @@ func AddGenesisAccount(addr sdk.AccAddress, appState app.GenesisState, cdc codec
return appState, nil
}

// GenesisStateWithSingleValidator initializes GenesisState with a single validator and genesis accounts
// that also act as delegators.
// GenesisStateWithSingleValidator initializes GenesisState with a single
// validator and genesis accounts that also act as delegators.
func GenesisStateWithSingleValidator(testApp *app.App, genAccounts ...string) (app.GenesisState, *tmtypes.ValidatorSet, keyring.Keyring) {
privVal := mock.NewPV()
pubKey, err := privVal.GetPubKey()
Expand Down
4 changes: 4 additions & 0 deletions x/mint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ $ celestia-appd query mint inflation
0.080000000000000000
```

## Genesis State

The genesis state is defined in [./types/genesis.go](./types/genesis.go).

## Params

All params have been removed from this module because they should not be modifiable via governance.
Expand Down
21 changes: 7 additions & 14 deletions x/mint/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,26 @@ import (
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

maybeSetGenesisTime(ctx, k)
maybeUpdateMinter(ctx, k)
mintBlockProvision(ctx, k)
setPreviousBlockTime(ctx, k)
}

// maybeSetGenesisTime sets the genesis time if the current block height is 1.
func maybeSetGenesisTime(ctx sdk.Context, k keeper.Keeper) {
if ctx.BlockHeight() == 1 {
genesisTime := ctx.BlockTime()
minter := k.GetMinter(ctx)
minter.GenesisTime = &genesisTime
k.SetMinter(ctx, minter)
}
}

// maybeUpdateMinter updates the inflation rate and annual provisions if the
// inflation rate has changed.
// inflation rate has changed. The inflation rate is expected to change once per
// year at the genesis time anniversary until the TargetInflationRate is
// reached.
func maybeUpdateMinter(ctx sdk.Context, k keeper.Keeper) {
minter := k.GetMinter(ctx)
newInflationRate := minter.CalculateInflationRate(ctx)
genesisTime := k.GetGenesisTime(ctx).GenesisTime
newInflationRate := minter.CalculateInflationRate(ctx, *genesisTime)

isNonZeroAnnualProvisions := !minter.AnnualProvisions.IsZero()
if newInflationRate.Equal(minter.InflationRate) && isNonZeroAnnualProvisions {
// The minter's InflationRate and AnnualProvisions already reflect the
// values for this year. Exit early because we don't need to update
// them.
// them. AnnualProvisions must be updated if it is zero (expected at
// genesis).
return
}

Expand Down
Loading

0 comments on commit 550e4f5

Please sign in to comment.