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: drand quicknet: allow scheduling drand quicknet upgrade before nv22 on 2k devnet #11632

Merged
merged 5 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
11 changes: 8 additions & 3 deletions build/drand.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes"
)

type DrandEnum int
type DrandEnum = dtypes.DrandEnum

func DrandConfigSchedule() dtypes.DrandSchedule {
out := dtypes.DrandSchedule{}
for start, config := range DrandSchedule {
out = append(out, dtypes.DrandPoint{Start: start, Config: DrandConfigs[config]})
for start, network := range DrandSchedule {
out = append(out, dtypes.DrandPoint{Start: start, Config: DrandConfigs[network]})
}

sort.Slice(out, func(i, j int) bool {
Expand All @@ -32,6 +32,7 @@ const (

var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
DrandMainnet: {
Network: DrandMainnet,
Servers: []string{
"https://api.drand.sh",
"https://api2.drand.sh",
Expand All @@ -47,6 +48,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
ChainInfoJSON: `{"public_key":"868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31","period":30,"genesis_time":1595431050,"hash":"8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce","groupHash":"176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a"}`,
},
DrandQuicknet: {
Network: DrandQuicknet,
Servers: []string{
"https://api.drand.sh",
"https://api2.drand.sh",
Expand All @@ -62,6 +64,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
ChainInfoJSON: `{"public_key":"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a","period":3,"genesis_time":1692803367,"hash":"52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971","groupHash":"f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e","schemeID":"bls-unchained-g1-rfc9380","metadata":{"beaconID":"quicknet"}}`,
},
DrandTestnet: {
Network: DrandTestnet,
Servers: []string{
"https://pl-eu.testnet.drand.sh",
"https://pl-us.testnet.drand.sh",
Expand All @@ -75,6 +78,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02","groupHash":"4dd408e5fdff9323c76a9b6f087ba8fdc5a6da907bd9217d9d10f2287d081957"}`,
},
DrandDevnet: {
Network: DrandDevnet,
Servers: []string{
"https://dev1.drand.sh",
"https://dev2.drand.sh",
Expand All @@ -86,6 +90,7 @@ var DrandConfigs = map[DrandEnum]dtypes.DrandConfig{
ChainInfoJSON: `{"public_key":"8cda589f88914aa728fd183f383980b35789ce81b274e5daee1f338b77d02566ef4d3fb0098af1f844f10f9c803c1827","period":25,"genesis_time":1595348225,"hash":"e73b7dc3c4f6a236378220c0dd6aa110eb16eed26c11259606e07ee122838d4f","groupHash":"567d4785122a5a3e75a9bc9911d7ea807dd85ff76b78dc4ff06b075712898607"}`,
},
DrandIncentinet: {
Network: DrandIncentinet,
ChainInfoJSON: `{"public_key":"8cad0c72c606ab27d36ee06de1d5b2db1faf92e447025ca37575ab3a8aac2eaae83192f846fc9e158bc738423753d000","period":30,"genesis_time":1595873820,"hash":"80c8b872c714f4c00fdd3daa465d5514049f457f01f85a4caf68cdcd394ba039","groupHash":"d9406aaed487f7af71851b4399448e311f2328923d454e971536c05398ce2d9b"}`,
},
}
24 changes: 23 additions & 1 deletion build/params_2k.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var NetworkBundle = "devnet"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = true

const GenesisNetworkVersion = network.Version21
var GenesisNetworkVersion = network.Version21

var UpgradeBreezeHeight = abi.ChainEpoch(-1)

Expand Down Expand Up @@ -96,6 +96,22 @@ func init() {
policy.SetMinVerifiedDealSize(MinVerifiedDealSize)
policy.SetPreCommitChallengeDelay(PreCommitChallengeDelay)

getGenesisNetworkVersion := func(ev string, def network.Version) network.Version {
hs, found := os.LookupEnv(ev)
if found {
h, err := strconv.Atoi(hs)
if err != nil {
log.Panicf("failed to parse %s env var", ev)
}

return network.Version(h)
}

return def
}

GenesisNetworkVersion = getGenesisNetworkVersion("LOTUS_GENESIS_NETWORK_VERSION", GenesisNetworkVersion)

getUpgradeHeight := func(ev string, def abi.ChainEpoch) abi.ChainEpoch {
hs, found := os.LookupEnv(ev)
if found {
Expand Down Expand Up @@ -136,6 +152,12 @@ func init() {
UpgradeWatermelonHeight = getUpgradeHeight("LOTUS_WATERMELON_HEIGHT", UpgradeWatermelonHeight)
UpgradeDragonHeight = getUpgradeHeight("LOTUS_DRAGON_HEIGHT", UpgradeDragonHeight)

UpgradePhoenixHeight = getUpgradeHeight("LOTUS_PHOENIX_HEIGHT", UpgradePhoenixHeight)
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
UpgradePhoenixHeight: DrandQuicknet,
}

BuildType |= Build2k

}
Expand Down
19 changes: 11 additions & 8 deletions chain/beacon/beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,17 @@ type RandomBeacon interface {
Entry(context.Context, uint64) <-chan Response
VerifyEntry(entry types.BeaconEntry, prevEntrySig []byte) error
MaxBeaconRoundForEpoch(network.Version, abi.ChainEpoch) uint64
IsChained() bool
}

func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockHeader, parentEpoch abi.ChainEpoch,
prevEntry types.BeaconEntry) error {
// Before nv22 we had "chained" beacons, and so required two entries at a fork
if nv < network.Version22 {

currBeacon := bSchedule.BeaconForEpoch(h.Height)
// When we have "chained" beacons, two entries at a fork are required.
if currBeacon.IsChained() {
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
currBeacon := bSchedule.BeaconForEpoch(h.Height)

if parentBeacon != currBeacon {
if len(h.BeaconEntries) != 2 {
return xerrors.Errorf("expected two beacon entries at beacon fork, got %d", len(h.BeaconEntries))
Expand Down Expand Up @@ -80,8 +83,8 @@ func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockH
return xerrors.Errorf("expected to have beacon entries in this block, but didn't find any")
}

if nv < network.Version22 && prevEntry.Round == 0 {
// We skip verifying the genesis entry before nv22, since that was "chained" randomness.
// We skip verifying the genesis entry when randomness is "chained".
if currBeacon.IsChained() && prevEntry.Round == 0 {
return nil
}

Expand Down Expand Up @@ -110,10 +113,10 @@ func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockH
}

func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.Version, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
// Before nv22 we had "chained" beacons, and so required two entries at a fork
if nv < network.Version22 {
// When we have "chained" beacons, two entries at a fork are required.
currBeacon := bSchedule.BeaconForEpoch(epoch)
if currBeacon.IsChained() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify this to:

		parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
		currBeacon := bSchedule.BeaconForEpoch(epoch)
		if parentBeacon != currBeacon && currBeacon.IsChained() {
// fork logic
}

Then we can also drop line 140 (and just use currBeacon everywhere).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
currBeacon := bSchedule.BeaconForEpoch(epoch)
if parentBeacon != currBeacon {
// Fork logic
round := currBeacon.MaxBeaconRoundForEpoch(nv, epoch)
Expand Down
8 changes: 7 additions & 1 deletion chain/beacon/drand/drand.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ var log = logging.Logger("drand")
//
// The root trust for the Drand chain is configured from build.DrandChain.
type DrandBeacon struct {
client dclient.Client
network dtypes.DrandEnum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we instead make this a simple boolean chained, and set that at config time? I think that will simplify this overall, and also avoid one-offs like db.network != build.DrandQuicknet.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

client dclient.Client

pubkey kyber.Point

Expand All @@ -52,6 +53,10 @@ type DrandBeacon struct {
localCache *lru.Cache[uint64, *types.BeaconEntry]
}

func (db *DrandBeacon) IsChained() bool {
return db.network != build.DrandQuicknet
}

// DrandHTTPClient interface overrides the user agent used by drand
type DrandHTTPClient interface {
SetUserAgent(string)
Expand Down Expand Up @@ -117,6 +122,7 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
}

db := &DrandBeacon{
network: config.Network,
client: client,
localCache: lc,
}
Expand Down
8 changes: 8 additions & 0 deletions chain/beacon/drand/drand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ func TestMaxBeaconRoundForEpoch(t *testing.T) {
todayTs := uint64(1652222222)
db, err := NewDrandBeacon(todayTs, build.BlockDelaySecs, nil, build.DrandConfigs[build.DrandTestnet])
assert.NoError(t, err)
assert.True(t, db.IsChained())
mbr15 := db.MaxBeaconRoundForEpoch(network.Version15, 100)
mbr16 := db.MaxBeaconRoundForEpoch(network.Version16, 100)
assert.Equal(t, mbr15+1, mbr16)
}

func TestQuicknetIsChained(t *testing.T) {
todayTs := uint64(1652222222)
db, err := NewDrandBeacon(todayTs, build.BlockDelaySecs, nil, build.DrandConfigs[build.DrandQuicknet])
assert.NoError(t, err)
assert.False(t, db.IsChained())
}
4 changes: 4 additions & 0 deletions chain/beacon/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type mockBeacon struct {
interval time.Duration
}

func (mb *mockBeacon) IsChained() bool {
return true
}

func NewMockBeacon(interval time.Duration) RandomBeacon {
mb := &mockBeacon{interval: interval}

Expand Down
3 changes: 3 additions & 0 deletions node/modules/dtypes/beacon.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package dtypes

import "github.com/filecoin-project/go-state-types/abi"

type DrandEnum int

type DrandSchedule []DrandPoint

type DrandPoint struct {
Expand All @@ -10,6 +12,7 @@ type DrandPoint struct {
}

type DrandConfig struct {
Network DrandEnum
Servers []string
Relays []string
ChainInfoJSON string
Expand Down