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:ec: integrate F3 dynamic manifest #12185

Merged
merged 1 commit into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions build/params_2k.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,5 @@ const Eip155ChainId = 31415926
var WhitelistedBlock = cid.Undef

const f3Enabled = true
const ManifestServerID = "12D3KooWHcNBkqXEBrsjoveQvj6zDF3vK5S9tAfqyYaQF1LGSJwG"
const F3BootstrapEpoch abi.ChainEpoch = 100
1 change: 1 addition & 0 deletions build/params_butterfly.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ const Eip155ChainId = 3141592
var WhitelistedBlock = cid.Undef

const f3Enabled = true
const ManifestServerID = "12D3KooWJr9jy4ngtJNR7JC1xgLFra3DjEtyxskRYWvBK9TC3Yn6"
const F3BootstrapEpoch abi.ChainEpoch = 200
1 change: 1 addition & 0 deletions build/params_calibnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,5 @@ const Eip155ChainId = 314159
var WhitelistedBlock = cid.Undef

const f3Enabled = true
const ManifestServerID = "12D3KooWS9vD9uwm8u2uPyJV32QBAhKAmPYwmziAgr3Xzk2FU1Mr"
const F3BootstrapEpoch abi.ChainEpoch = UpgradeWaffleHeight + 100
1 change: 1 addition & 0 deletions build/params_interop.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,5 @@ const Eip155ChainId = 3141592
var WhitelistedBlock = cid.Undef

const f3Enabled = true
const ManifestServerID = "12D3KooWQJ2rdVnG4okDUB6yHQhAjNutGNemcM7XzqC9Eo4z9Jce"
const F3BootstrapEpoch abi.ChainEpoch = 1000
1 change: 1 addition & 0 deletions build/params_mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,5 @@ const Eip155ChainId = 314
var WhitelistedBlock = MustParseCid("bafy2bzaceapyg2uyzk7vueh3xccxkuwbz3nxewjyguoxvhx77malc2lzn2ybi")

const f3Enabled = false
const ManifestServerID = "12D3KooWENMwUF9YxvQxar7uBWJtZkA6amvK4xWmKXfSiHUo2Qq7"
const F3BootstrapEpoch abi.ChainEpoch = -1
15 changes: 7 additions & 8 deletions chain/lf3/ec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"golang.org/x/xerrors"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-f3"
"github.com/filecoin-project/go-f3/ec"
"github.com/filecoin-project/go-f3/gpbft"
"github.com/filecoin-project/go-state-types/abi"

Expand All @@ -23,7 +23,6 @@ import (
type ecWrapper struct {
ChainStore *store.ChainStore
StateManager *stmgr.StateManager
Manifest f3.Manifest
}

type f3TipSet types.TipSet
Expand Down Expand Up @@ -57,7 +56,7 @@ func (ts *f3TipSet) Timestamp() time.Time {
return time.Unix(int64(ts.cast().Blocks()[0].Timestamp), 0)
}

func wrapTS(ts *types.TipSet) f3.TipSet {
func wrapTS(ts *types.TipSet) ec.TipSet {
if ts == nil {
return nil
}
Expand All @@ -66,15 +65,15 @@ func wrapTS(ts *types.TipSet) f3.TipSet {

// GetTipsetByEpoch should return a tipset before the one requested if the requested
// tipset does not exist due to null epochs
func (ec *ecWrapper) GetTipsetByEpoch(ctx context.Context, epoch int64) (f3.TipSet, error) {
func (ec *ecWrapper) GetTipsetByEpoch(ctx context.Context, epoch int64) (ec.TipSet, error) {
ts, err := ec.ChainStore.GetTipsetByHeight(ctx, abi.ChainEpoch(epoch), nil, true)
if err != nil {
return nil, xerrors.Errorf("getting tipset by height: %w", err)
}
return wrapTS(ts), nil
}

func (ec *ecWrapper) GetTipset(ctx context.Context, tsk gpbft.TipSetKey) (f3.TipSet, error) {
func (ec *ecWrapper) GetTipset(ctx context.Context, tsk gpbft.TipSetKey) (ec.TipSet, error) {
tskLotus, err := types.TipSetKeyFromBytes(tsk)
if err != nil {
return nil, xerrors.Errorf("decoding tsk: %w", err)
Expand All @@ -88,16 +87,16 @@ func (ec *ecWrapper) GetTipset(ctx context.Context, tsk gpbft.TipSetKey) (f3.Tip
return wrapTS(ts), nil
}

func (ec *ecWrapper) GetHead(_ context.Context) (f3.TipSet, error) {
func (ec *ecWrapper) GetHead(_ context.Context) (ec.TipSet, error) {
return wrapTS(ec.ChainStore.GetHeaviestTipSet()), nil
}

func (ec *ecWrapper) GetParent(ctx context.Context, tsF3 f3.TipSet) (f3.TipSet, error) {
func (ec *ecWrapper) GetParent(ctx context.Context, tsF3 ec.TipSet) (ec.TipSet, error) {
var ts *types.TipSet
if tsW, ok := tsF3.(*f3TipSet); ok {
ts = tsW.cast()
} else {
// There are only two implementations of F3.TipSet: f3TipSet, and one in fake EC
// There are only two implementations of ec.TipSet: f3TipSet, and one in fake EC
// backend.
//
// TODO: Revisit the type check here and remove as needed once testing
Expand Down
35 changes: 18 additions & 17 deletions chain/lf3/f3.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ package lf3
import (
"context"
"errors"
"time"

"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"go.uber.org/fx"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-f3"
"github.com/filecoin-project/go-f3/blssig"
"github.com/filecoin-project/go-f3/certs"
"github.com/filecoin-project/go-f3/gpbft"
"github.com/filecoin-project/go-f3/manifest"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
Expand All @@ -35,39 +36,39 @@ type F3 struct {
type F3Params struct {
fx.In

NetworkName dtypes.NetworkName
PubSub *pubsub.PubSub
Host host.Host
ChainStore *store.ChainStore
StateManager *stmgr.StateManager
Datastore dtypes.MetadataDS
Wallet api.Wallet
NetworkName dtypes.NetworkName
ManifestProvider manifest.ManifestProvider
PubSub *pubsub.PubSub
Host host.Host
ChainStore *store.ChainStore
StateManager *stmgr.StateManager
Datastore dtypes.MetadataDS
Wallet api.Wallet
}

var log = logging.Logger("f3")

func New(mctx helpers.MetricsCtx, lc fx.Lifecycle, params F3Params) (*F3, error) {
manifest := f3.LocalnetManifest()
manifest.NetworkName = gpbft.NetworkName(params.NetworkName)
manifest.ECDelay = 2 * time.Duration(build.BlockDelaySecs) * time.Second
manifest.ECPeriod = manifest.ECDelay
manifest.BootstrapEpoch = int64(build.F3BootstrapEpoch)
manifest.ECFinality = int64(build.Finality)

ds := namespace.Wrap(params.Datastore, datastore.NewKey("/f3"))
ec := &ecWrapper{
ChainStore: params.ChainStore,
StateManager: params.StateManager,
Manifest: manifest,
}
verif := blssig.VerifierWithKeyOnG1()

module, err := f3.New(mctx, manifest, ds,
params.Host, params.PubSub, verif, ec, log, nil)
senderID, err := peer.Decode(build.ManifestServerID)
if err != nil {
return nil, xerrors.Errorf("decoding F3 manifest server identity: %w", err)
}

module, err := f3.New(mctx, params.ManifestProvider, ds,
params.Host, senderID, params.PubSub, verif, ec, log, nil)

if err != nil {
return nil, xerrors.Errorf("creating F3: %w", err)
}
params.ManifestProvider.SetManifestChangeCallback(f3.ManifestChangeCallback(module))

fff := &F3{
inner: module,
Expand Down
39 changes: 39 additions & 0 deletions chain/lf3/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package lf3

import (
"time"

pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/peer"

"github.com/filecoin-project/go-f3/gpbft"
"github.com/filecoin-project/go-f3/manifest"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)

func NewManifestProvider(nn dtypes.NetworkName, cs *store.ChainStore, sm *stmgr.StateManager, ps *pubsub.PubSub) manifest.ManifestProvider {
m := manifest.LocalDevnetManifest()
m.NetworkName = gpbft.NetworkName(nn)
m.ECDelay = 2 * time.Duration(build.BlockDelaySecs) * time.Second
m.ECPeriod = m.ECDelay
m.BootstrapEpoch = int64(build.F3BootstrapEpoch)
m.ECFinality = int64(build.Finality)
m.CommiteeLookback = 5

ec := &ecWrapper{
ChainStore: cs,
StateManager: sm,
}

switch manifestServerID, err := peer.Decode(build.ManifestServerID); {
case err != nil:
log.Warnw("Cannot decode F3 manifest sever identity; falling back on static manifest provider", "err", err)
return manifest.NewStaticManifestProvider(m)
default:
return manifest.NewDynamicManifestProvider(m, ps, ec, manifestServerID)
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ require (
github.com/filecoin-project/go-commp-utils v0.1.3
github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082a837
github.com/filecoin-project/go-crypto v0.0.1
github.com/filecoin-project/go-f3 v0.0.2
github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4
github.com/filecoin-project/go-fil-commcid v0.1.0
github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0
github.com/filecoin-project/go-jsonrpc v0.3.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,8 @@ github.com/filecoin-project/go-commp-utils/nonffi v0.0.0-20220905160352-62059082
github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
github.com/filecoin-project/go-crypto v0.0.1 h1:AcvpSGGCgjaY8y1az6AMfKQWreF/pWO2JJGLl6gCq6o=
github.com/filecoin-project/go-crypto v0.0.1/go.mod h1:+viYnvGtUTgJRdy6oaeF4MTFKAfatX071MPDPBL11EQ=
github.com/filecoin-project/go-f3 v0.0.2 h1:bzw/GndxntJnUYA+WCaXwHE2qwGRwrFVo9umz3unTUs=
github.com/filecoin-project/go-f3 v0.0.2/go.mod h1:Wry0mNa8z767TBHb7N0cVb+9j00KsHbD2pzsC3li4R8=
github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4 h1:eQW2fyKyMuiweuySEb/zMIc3WLSAnIOY8lpqCVQM7pU=
github.com/filecoin-project/go-f3 v0.0.3-0.20240702063402-d48771055cf4/go.mod h1:Wry0mNa8z767TBHb7N0cVb+9j00KsHbD2pzsC3li4R8=
github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8=
github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ=
Expand Down
7 changes: 6 additions & 1 deletion node/builder_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"go.uber.org/fx"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-f3/manifest"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain"
Expand Down Expand Up @@ -151,7 +153,10 @@ var ChainNode = Options(
Override(HandleIncomingBlocksKey, modules.HandleIncomingBlocks),
),

If(build.IsF3Enabled(), Override(new(*lf3.F3), lf3.New)),
If(build.IsF3Enabled(),
Override(new(manifest.ManifestProvider), lf3.NewManifestProvider),
Override(new(*lf3.F3), lf3.New),
),
)

func ConfigFullNode(c interface{}) Option {
Expand Down
31 changes: 30 additions & 1 deletion node/modules/lp2p/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package lp2p
import (
"context"
"encoding/json"
"fmt"
"net"
"time"

Expand All @@ -17,6 +18,7 @@ import (
"golang.org/x/xerrors"

"github.com/filecoin-project/go-f3/gpbft"
"github.com/filecoin-project/go-f3/manifest"

"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/metrics"
Expand Down Expand Up @@ -46,6 +48,12 @@ const (
GraylistScoreThreshold = -2500
AcceptPXScoreThreshold = 1000
OpportunisticGraftScoreThreshold = 3.5

// Determines the max. number of configuration changes
// that are allowed for the dynamic manifest.
// If the manifest changes more than this number, the F3
// message topic will be filtered
MaxDynamicManifestChangesAllowed = 1000
)

func ScoreKeeper() *dtypes.ScoreKeeper {
Expand Down Expand Up @@ -382,7 +390,28 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) {
}

if build.IsF3Enabled() {
allowTopics = append(allowTopics, gpbft.NetworkName(in.Nn).PubSubTopic())
f3TopicName := manifest.PubSubTopicFromNetworkName(gpbft.NetworkName(in.Nn))
allowTopics = append(allowTopics, f3TopicName)

// allow dynamic manifest topic and the new topic names after a reconfiguration.
// Note: This is pretty ugly, but I tried to use a regex subscription filter
// as the commented code below, but unfortunately it overwrites previous filters. A simple fix would
// be to allow combining several topic filters, but for now this works.
//
// pattern := fmt.Sprintf(`^\/f3\/%s\/0\.0\.1\/?[0-9]*$`, in.Nn)
// rx, err := regexp.Compile(pattern)
// if err != nil {
// return nil, xerrors.Errorf("failed to compile manifest topic regex: %w", err)
// }
// options = append(options,
// pubsub.WithSubscriptionFilter(
// pubsub.WrapLimitSubscriptionFilter(
// pubsub.NewRegexpSubscriptionFilter(rx),
// 100)))
allowTopics = append(allowTopics, manifest.ManifestPubSubTopicName)
for i := 0; i < MaxDynamicManifestChangesAllowed; i++ {
allowTopics = append(allowTopics, f3TopicName+"/"+fmt.Sprintf("%d", i))
}
}

allowTopics = append(allowTopics, drandTopics...)
Expand Down