Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a1abdab0f | ||
|
|
7344dd5eb3 | ||
|
|
5b5dd525f5 | ||
|
|
410bdc389e | ||
|
|
fbafe1c507 | ||
|
|
24a714d123 | ||
|
|
b243c405b4 | ||
|
|
cff785fa37 | ||
|
|
c0c4e6bf35 | ||
|
|
02929dd166 | ||
|
|
12b30c0069 | ||
|
|
b1228b51ef | ||
|
|
9d58fff806 | ||
|
|
d121760172 | ||
|
|
e8455567fd | ||
|
|
29fbfaf13d | ||
|
|
5f593b3ae1 | ||
|
|
ad8cfe1da2 | ||
|
|
64a9453db8 | ||
|
|
72c5a9a574 | ||
|
|
77b6b7ef10 | ||
|
|
d1b8af338e | ||
|
|
48a3076876 | ||
|
|
8bb6d423ff | ||
|
|
9387ffc593 | ||
|
|
3720e79806 | ||
|
|
7b473f60ae | ||
|
|
a6ae497c02 | ||
|
|
87801b5855 | ||
|
|
b6a77dfafc | ||
|
|
368278b19c | ||
|
|
21f8f642c9 | ||
|
|
3f00691f26 | ||
|
|
420f33017e | ||
|
|
6e22c08c1d | ||
|
|
84b07519c2 | ||
|
|
018c4e8a38 | ||
|
|
2d8dbf5bc1 | ||
|
|
d02b91e610 |
@@ -2,6 +2,8 @@
|
||||
|
||||
# UNRELEASED
|
||||
- chore: Auto remove local chain data when importing chain file or snapshot ([filecoin-project/lotus#11277](https://github.com/filecoin-project/lotus/pull/11277))
|
||||
- feat: metric: export Mpool message count ([filecoin-project/lotus#11361](https://github.com/filecoin-project/lotus/pull/11361))
|
||||
- feat: sealing: load SectorsSummary from sealing SectorStats instead of calling API each time ([filecoin-project/lotus#11353](https://github.com/filecoin-project/lotus/pull/11353))
|
||||
|
||||
## New features
|
||||
- feat: Added new tracing API (**HIGHLY EXPERIMENTAL**) supporting two RPC methods: `trace_block` and `trace_replayBlockTransactions` ([filecoin-project/lotus#11100](https://github.com/filecoin-project/lotus/pull/11100))
|
||||
@@ -9,6 +11,7 @@
|
||||
## Improvements
|
||||
- fix: Add time slicing to splitstore purging step during compaction to reduce lock congestion [filecoin-project/lotus#11269](https://github.com/filecoin-project/lotus/pull/11269)
|
||||
- feat: Added instructions on how to setup Prometheus/Grafana for monitoring a local Lotus node [filecoin-project/lotus#11276](https://github.com/filecoin-project/lotus/pull/11276)
|
||||
- fix: Exclude reverted events in `eth_getLogs` results [filecoin-project/lotus#11318](https://github.com/filecoin-project/lotus/pull/11318)
|
||||
|
||||
## New features
|
||||
- feat: Add move-partition command ([filecoin-project/lotus#11290](https://github.com/filecoin-project/lotus/pull/11290))
|
||||
|
||||
@@ -71,10 +71,10 @@ For other distributions you can find the required dependencies [here.](https://l
|
||||
|
||||
#### Go
|
||||
|
||||
To build Lotus, you need a working installation of [Go 1.19.12 or higher](https://golang.org/dl/):
|
||||
To build Lotus, you need a working installation of [Go 1.20.10 or higher](https://golang.org/dl/):
|
||||
|
||||
```bash
|
||||
wget -c https://golang.org/dl/go1.19.12.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
|
||||
wget -c https://golang.org/dl/go1.20.10.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
|
||||
```
|
||||
|
||||
**TIP:**
|
||||
|
||||
@@ -874,6 +874,11 @@ type FullNode interface {
|
||||
// Replays all transactions in a block returning the requested traces for each transaction
|
||||
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error) //perm:read
|
||||
|
||||
// go-ethereum "debug" trace endpoints
|
||||
EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error)
|
||||
EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
|
||||
// CreateBackup creates node backup onder the specified file name. The
|
||||
// method requires that the lotus daemon is running with the
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
|
||||
@@ -129,4 +129,7 @@ type Gateway interface {
|
||||
Web3ClientVersion(ctx context.Context) (string, error)
|
||||
EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error)
|
||||
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)
|
||||
EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error)
|
||||
EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ func CreateEthRPCAliases(as apitypes.Aliaser) {
|
||||
as.AliasMethod("trace_block", "Filecoin.EthTraceBlock")
|
||||
as.AliasMethod("trace_replayBlockTransactions", "Filecoin.EthTraceReplayBlockTransactions")
|
||||
|
||||
as.AliasMethod("debug_traceCall", "Filecoin.EthDebugTraceCall")
|
||||
as.AliasMethod("debug_traceBlockByHash", "Filecoin.EthDebugTraceBlockByHash")
|
||||
as.AliasMethod("debug_traceBlockByNumber", "Filecoin.EthDebugTraceBlockByNumber")
|
||||
|
||||
as.AliasMethod("net_version", "Filecoin.NetVersion")
|
||||
as.AliasMethod("net_listening", "Filecoin.NetListening")
|
||||
|
||||
|
||||
@@ -1500,12 +1500,57 @@ func (m *MockFullNode) EthTraceBlock(arg0 context.Context, arg1 string) ([]*etht
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EthDebugTraceCall mocks base method.
|
||||
func (m *MockFullNode) EthDebugTraceCall(ctx context.Context, arg0 ethtypes.EthTxArgs, arg1 ethtypes.EthBlockNumberOrHash, arg2 *ethtypes.TraceCallConfig) (interface{}, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EthDebugTraceCall", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(interface{})
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EthDebugTraceBlockByNumber mocks base method.
|
||||
func (m *MockFullNode) EthDebugTraceBlockByNumber(ctx context.Context, arg0 string, arg1 *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EthDebugTraceBlockByNumber", arg0, arg1)
|
||||
ret0, _ := ret[0].([]*ethtypes.TxTraceResult)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EthDebugTraceBlockByHash mocks base method.
|
||||
func (m *MockFullNode) EthDebugTraceBlockByHash(ctx context.Context, arg0 ethtypes.EthHash, arg1 *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EthDebugTraceBlockByHash", arg0, arg1)
|
||||
ret0, _ := ret[0].([]*ethtypes.TxTraceResult)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EthTraceBlock indicates an expected call of EthTraceBlock.
|
||||
func (mr *MockFullNodeMockRecorder) EthTraceBlock(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthTraceBlock", reflect.TypeOf((*MockFullNode)(nil).EthTraceBlock), arg0, arg1)
|
||||
}
|
||||
|
||||
// EthDebugTraceCall indicates an expected of EthDebugTraceCall
|
||||
func (mr *MockFullNodeMockRecorder) EthDebugTraceCall(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthDebugTraceCall", reflect.TypeOf((*MockFullNode)(nil).EthDebugTraceCall), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// EthDebugTraceBlockByHash indicates an expected of EthDebugTraceBlockByHash
|
||||
func (mr *MockFullNodeMockRecorder) EthDebugTraceBlockByHash(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthDebugTraceBlockByHash", reflect.TypeOf((*MockFullNode)(nil).EthDebugTraceBlockByHash), arg0, arg1)
|
||||
}
|
||||
|
||||
// EthDebugTraceBlockByNumber indicates an expected of EthDebugTraceBlockByHash
|
||||
func (mr *MockFullNodeMockRecorder) EthDebugTraceBlockByNumber(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthDebugTraceBlockByNumber", reflect.TypeOf((*MockFullNode)(nil).EthDebugTraceBlockByNumber), arg0, arg1)
|
||||
}
|
||||
|
||||
// EthTraceReplayBlockTransactions mocks base method.
|
||||
func (m *MockFullNode) EthTraceReplayBlockTransactions(arg0 context.Context, arg1 string, arg2 []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -183,3 +183,17 @@ func (b *idstore) Close() error {
|
||||
func (b *idstore) Flush(ctx context.Context) error {
|
||||
return b.bs.Flush(ctx)
|
||||
}
|
||||
|
||||
func (b *idstore) CollectGarbage(ctx context.Context, options ...BlockstoreGCOption) error {
|
||||
if bs, ok := b.bs.(BlockstoreGC); ok {
|
||||
return bs.CollectGarbage(ctx, options...)
|
||||
}
|
||||
return xerrors.Errorf("not supported")
|
||||
}
|
||||
|
||||
func (b *idstore) GCOnce(ctx context.Context, options ...BlockstoreGCOption) error {
|
||||
if bs, ok := b.bs.(BlockstoreGCOnce); ok {
|
||||
return bs.GCOnce(ctx, options...)
|
||||
}
|
||||
return xerrors.Errorf("not supported")
|
||||
}
|
||||
|
||||
Binary file not shown.
+14
-2
@@ -42,6 +42,12 @@ func init() {
|
||||
if err := loadManifests(NetworkBundle); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// The following code cid existed temporarily on the calibnet testnet, as a "buggy" storage miner actor implementation.
|
||||
// We include it in our builtin bundle, but intentionally omit from metadata.
|
||||
if NetworkBundle == "calibrationnet" {
|
||||
actors.AddActorMeta("storageminer", cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq"), actorstypes.Version12)
|
||||
}
|
||||
}
|
||||
|
||||
// UseNetworkBundle switches to a different network bundle, by name.
|
||||
@@ -183,6 +189,12 @@ func readEmbeddedBuiltinActorsMetadata(bundle string) ([]*BuiltinActorsMetadata,
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("error loading builtin actors bundle: %w", err)
|
||||
}
|
||||
|
||||
// The following manifest cid existed temporarily on the calibnet testnet
|
||||
// We include it in our builtin bundle, but intentionally omit from metadata
|
||||
if root == cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs") {
|
||||
continue
|
||||
}
|
||||
bundles = append(bundles, &BuiltinActorsMetadata{
|
||||
Network: name,
|
||||
Version: actorstypes.Version(version),
|
||||
@@ -232,7 +244,7 @@ func readBundleManifest(r io.Reader) (cid.Cid, map[string]cid.Cid, error) {
|
||||
}
|
||||
|
||||
// GetEmbeddedBuiltinActorsBundle returns the builtin-actors bundle for the given actors version.
|
||||
func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version) ([]byte, bool) {
|
||||
func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version, networkBundleName string) ([]byte, bool) {
|
||||
fi, err := embeddedBuiltinActorReleases.Open(fmt.Sprintf("actors/v%d.tar.zst", version))
|
||||
if err != nil {
|
||||
return nil, false
|
||||
@@ -243,7 +255,7 @@ func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version) ([]byte, bool)
|
||||
defer uncompressed.Close() //nolint
|
||||
|
||||
tarReader := tar.NewReader(uncompressed)
|
||||
targetFileName := fmt.Sprintf("builtin-actors-%s.car", NetworkBundle)
|
||||
targetFileName := fmt.Sprintf("builtin-actors-%s.car", networkBundleName)
|
||||
for {
|
||||
header, err := tarReader.Next()
|
||||
switch err {
|
||||
|
||||
+21
-21
@@ -97,8 +97,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "butterflynet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzaceb7s3k6zyuubqil7s2rwdcdyslqqx2fn2cj536yh3hexlyi4syyk6"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceabeegs5mhrxwqodyt7u2ulxr2jg6eh5g3545ganqzkncnxzserue"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacebp7anjdtg2sohyt6lromx4xs7nujtwdfcsffnptphaayabx7ysxs"),
|
||||
"cron": MustParseCid("bafk2bzacecu2y3awtemmglpkroiglulc2fj3gpdn6eazdqr6avcautiaighrg"),
|
||||
@@ -112,7 +112,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacedebvitdsztwebi44t5es4ls3p3hor252igzawr3s6uznmbvzh2ou"),
|
||||
"storagemarket": MustParseCid("bafk2bzaceb2tdeqtt2eqpzeb3gezuchb7g7uzbd52bgvcdt6bg3ckq7oisb74"),
|
||||
"storageminer": MustParseCid("bafk2bzaceaaztuglvw6pw5xohwfekbw47iyugbyftxrp6hwygsaiu6rebtcty"),
|
||||
"storageminer": MustParseCid("bafk2bzacea2jzzulmz6ktj6vndjheybz2io3vznnhsb32zberpaqeo7s7xa56"),
|
||||
"storagepower": MustParseCid("bafk2bzacedxvlj5xmhytdjrjqyonz37duvxb2ioyzk75c27yypkqalxuh3xh6"),
|
||||
"system": MustParseCid("bafk2bzacec3vwj2chzaram3iqupkbfiein5h2l5qiltlrngbju2vg5umelclm"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacedv2irkql7nil3w5v3ohqq3e54w62pxeoppjmaktzokolaaoh5ksu"),
|
||||
@@ -203,8 +203,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "calibrationnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacechwwxdqvggkdylm37zldjsra2ivkdzwp7fee56bzxbzs544wv6u6"),
|
||||
"cron": MustParseCid("bafk2bzacec4gdxxkqwxqqodsv6ug5dmdbqdfqwyqfek3yhxc2wweh5psxaeq6"),
|
||||
@@ -218,7 +218,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacedra77pcglf7vdca2itcaa4vd6xrxynxmgfgdjdxqxfwqyhtoxehy"),
|
||||
"storagemarket": MustParseCid("bafk2bzacea7g46y7xxu2zjq2h75x6mmx3utz2uxnlvnwi6tzpsvulna3bmiva"),
|
||||
"storageminer": MustParseCid("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq"),
|
||||
"storageminer": MustParseCid("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie"),
|
||||
"storagepower": MustParseCid("bafk2bzacedd3ka44k7d46ckbinjhv3diyuu2epgbyvhqqyjkc64qlrg3wlgzi"),
|
||||
"system": MustParseCid("bafk2bzacecioupndtcnyw6iq2hbrxag3aufvczlv5nobnfbkbywqzcyfaa376"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceavldupmf7bimeeacs67z5xdfdlfca6p7sn6bev3mt5ggepfqvhqo"),
|
||||
@@ -318,8 +318,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "caterpillarnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacedrimdbavexkdqldjwczbhlx4k5byshl363z62rrt6vkt7mbvnulu"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacechvmc3iy6qrsbb6xwjhjibqpznqnkajowjsdmrq42ie5hysqemqa"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacecereuhejfvodut5357cai4lmhsyr7uenhcxvmw6jpmhe6auuly32"),
|
||||
"cron": MustParseCid("bafk2bzacebo2whgy6jla4jsf5j4ovlqm2e4eepedlpw5wadas33yxmunis4b4"),
|
||||
@@ -333,7 +333,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceb2x5zgkrho373l3ippp6krs7brugssg6hj2tib22xmqjzdm2o25a"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced5j6drzmsebpxbf2dtptrc5tyidlbftdljqxavxqb57s2qpbvdek"),
|
||||
"storageminer": MustParseCid("bafk2bzacedozwxc3c6nqqajafs3hsjviyijhthysd5two5ptm5fcdbwh224ag"),
|
||||
"storageminer": MustParseCid("bafk2bzacec7al5izu3ynnb7wg6fxxck3hebtkvlgynufjwcio57jd3n4ke2ue"),
|
||||
"storagepower": MustParseCid("bafk2bzaceagp6ilkltsltwii66nz6a4zen4qtfk7rdkvdv3gzq7fbv4ivox3u"),
|
||||
"system": MustParseCid("bafk2bzacedye5j5uxox7knb6zlnhseaadztyav76mjbyk5qslhhbpiy5cdtt2"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacecduww5pirr7dvaijjijw4gf6ygf7vipgxh4scvv6vseo46gueb46"),
|
||||
@@ -424,8 +424,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "devnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacebk6yiirh4ennphzyka7b6g6jzn3lt4lr5ht7rjwulnrcthjihapo"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceau5i7eanhvss22z5ixmyrihilfniqn22tvkecjj56akz4xj7fvku"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacedki4apynvdxxuoigmqkgaktgy2erjftoxqxqaklnelgveyaqknfu"),
|
||||
"cron": MustParseCid("bafk2bzacebjpczf7qtcisy3zdp3sqoohxe75tgupmdo5dr26vh7orzrsjn3b2"),
|
||||
@@ -439,7 +439,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacebzso6xkjxdscbpncw7el2d4hap6lfkgwqzrbc76lzp33vkwk6obc"),
|
||||
"storagemarket": MustParseCid("bafk2bzacebzg74vyk3gzbhnz4zviwvxblyar574mtd6ayognmsvlkriejmunu"),
|
||||
"storageminer": MustParseCid("bafk2bzaceajgt523lr2sf6cacvzo3goyalljlkaoeehyhxlv57wevkljw2cps"),
|
||||
"storageminer": MustParseCid("bafk2bzaceckqrzomdnfb35byrhabrmmapxplj66cv3efw7u62qswjaqsuxah4"),
|
||||
"storagepower": MustParseCid("bafk2bzacebbtj2m2ajawfuzxqz5nmdep7xevjo2qfjqa5tx3vr5m6qojolya4"),
|
||||
"system": MustParseCid("bafk2bzacecnau5wddulbsvwn75tc3w75jrlvkybgrlxs4ngonqab6xq3eowvg"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacec37mddea65nvh4htsagtryfa3sq6i67utcupslyhzbhjhoy6hopa"),
|
||||
@@ -553,8 +553,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "mainnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacebxmnxdgt2usdrcrpotgodr75culawwv4eklaun4lu6vlxecql6h2"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacecooh5cjxkmraawn7wvmrx7k5hwdmbvqdteujr33mnaeclsazyb6a"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzaceboftg75mdiba7xbo2i3uvgtca4brhnr3u5ptihonixgpnrvhpxoa"),
|
||||
"cron": MustParseCid("bafk2bzacechxjkfe2cehx4s7skj3wzfpzf7zolds64khrrrs66bhazsemktls"),
|
||||
@@ -568,7 +568,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacealqnxn5lwzwexd6reav4dppypquklx2ujlnvaxiqk2tzstyvkp5u"),
|
||||
"storagemarket": MustParseCid("bafk2bzacedylkg5am446lcuih4voyzdn4yjeqfsxfzh5b6mcuhx4mok5ph5c4"),
|
||||
"storageminer": MustParseCid("bafk2bzacea56yi2khvvorofkf2t4rb5fbmltahrjtauszirdjz4jbunt55xsk"),
|
||||
"storageminer": MustParseCid("bafk2bzacedio7wfaqutc4w6gl2dwqkgpcatz2r223ms74zxiovbjrfxmzeiou"),
|
||||
"storagepower": MustParseCid("bafk2bzacecsij5tpfzjpfuckxvccv2p3bdqjklkrfyyoei6lx5dyj5j4fvjm6"),
|
||||
"system": MustParseCid("bafk2bzacebfqrja2hip7esf4eafxjmu6xcogoqu5xxtgdg7xa5szgvvdguchu"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacedudgflxc75c77c6zkmfyq4u2xuk7k6xw6dfdccarjrvxx453b77q"),
|
||||
@@ -659,8 +659,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "testing",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacebzcqzzlb5iwrledyuyy7pvob3xwzoxqsrvrbrnpaiejb52na5eza"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacec7artlmtdmfuhurd2i7dgturiveblruub5xh3yizjtp5qzye3dly"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
|
||||
"cron": MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
|
||||
@@ -674,7 +674,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
|
||||
"storageminer": MustParseCid("bafk2bzacecw6jvvfu62jkwsa4vzmn262cjrrxh6wza6nvjsyg5aeix7rzgmbe"),
|
||||
"storageminer": MustParseCid("bafk2bzaceclcbtu6edh73cn7ga7kzkmxcfnjt7jnxolkc5id6l6f7sztevm24"),
|
||||
"storagepower": MustParseCid("bafk2bzacedexrf5qplrrl5xzijfrthjdqwodfs5e6zj5kpztc7qnywbqdyiii"),
|
||||
"system": MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
|
||||
@@ -765,8 +765,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "testing-fake-proofs",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.1",
|
||||
ManifestCid: MustParseCid("bafy2bzacedtskkmrkkzairdi66syrmvfpydg63ro4dlmmqeta5krnur4hcp3a"),
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceand7owcb3omq7zjwir2q3lqapprl2eyiwpzv6oqs5bok4vzzqjbu"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
|
||||
"cron": MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
|
||||
@@ -780,7 +780,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
|
||||
"storageminer": MustParseCid("bafk2bzacea54x727xteh3tl46mitigy6cldqusqjxiwni65wrpofidh62k2ds"),
|
||||
"storageminer": MustParseCid("bafk2bzacebbusvtnyhi7mimbnx2tw2uyvrr3fbmncbf6frx6e4kvjvoqllu36"),
|
||||
"storagepower": MustParseCid("bafk2bzacecdwijcbbryinjtm27pdinqqkyzoskri24pwsvsadwcq2alkkjpnc"),
|
||||
"system": MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
|
||||
|
||||
@@ -67,6 +67,9 @@ var UpgradeThunderHeight = abi.ChainEpoch(-23)
|
||||
|
||||
var UpgradeWatermelonHeight = abi.ChainEpoch(200)
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -100
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
@@ -57,6 +57,9 @@ const UpgradeThunderHeight = -23
|
||||
|
||||
const UpgradeWatermelonHeight = 400
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -100
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
|
||||
@@ -82,6 +82,9 @@ const UpgradeThunderHeight = UpgradeLightningHeight + 3120
|
||||
// 2023-10-19T13:00:00Z
|
||||
const UpgradeWatermelonHeight = 1013134
|
||||
|
||||
// 2023-11-07T13:00:00Z
|
||||
const UpgradeWatermelonFixHeight = 1070494
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
|
||||
@@ -56,6 +56,9 @@ var UpgradeThunderHeight = abi.ChainEpoch(-23)
|
||||
|
||||
const UpgradeWatermelonHeight = 50
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -1
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
||||
@@ -95,8 +95,11 @@ const UpgradeLightningHeight = 2809800
|
||||
// 2023-05-18T13:00:00Z
|
||||
const UpgradeThunderHeight = UpgradeLightningHeight + 2880*21
|
||||
|
||||
// ???????
|
||||
var UpgradeWatermelonHeight = abi.ChainEpoch(9999999999)
|
||||
// 2023-11-29T13:30:00Z
|
||||
var UpgradeWatermelonHeight = abi.ChainEpoch(3431940)
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -1
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
|
||||
+24
-23
@@ -87,29 +87,30 @@ var (
|
||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeAssemblyHeight abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -8
|
||||
UpgradePersianHeight abi.ChainEpoch = -9
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
||||
UpgradeClausHeight abi.ChainEpoch = -11
|
||||
UpgradeTrustHeight abi.ChainEpoch = -12
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -13
|
||||
UpgradeTurboHeight abi.ChainEpoch = -14
|
||||
UpgradeHyperdriveHeight abi.ChainEpoch = -15
|
||||
UpgradeChocolateHeight abi.ChainEpoch = -16
|
||||
UpgradeOhSnapHeight abi.ChainEpoch = -17
|
||||
UpgradeSkyrHeight abi.ChainEpoch = -18
|
||||
UpgradeSharkHeight abi.ChainEpoch = -19
|
||||
UpgradeHyggeHeight abi.ChainEpoch = -20
|
||||
UpgradeLightningHeight abi.ChainEpoch = -21
|
||||
UpgradeThunderHeight abi.ChainEpoch = -22
|
||||
UpgradeWatermelonHeight abi.ChainEpoch = -23
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeAssemblyHeight abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -8
|
||||
UpgradePersianHeight abi.ChainEpoch = -9
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
||||
UpgradeClausHeight abi.ChainEpoch = -11
|
||||
UpgradeTrustHeight abi.ChainEpoch = -12
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -13
|
||||
UpgradeTurboHeight abi.ChainEpoch = -14
|
||||
UpgradeHyperdriveHeight abi.ChainEpoch = -15
|
||||
UpgradeChocolateHeight abi.ChainEpoch = -16
|
||||
UpgradeOhSnapHeight abi.ChainEpoch = -17
|
||||
UpgradeSkyrHeight abi.ChainEpoch = -18
|
||||
UpgradeSharkHeight abi.ChainEpoch = -19
|
||||
UpgradeHyggeHeight abi.ChainEpoch = -20
|
||||
UpgradeLightningHeight abi.ChainEpoch = -21
|
||||
UpgradeThunderHeight abi.ChainEpoch = -22
|
||||
UpgradeWatermelonHeight abi.ChainEpoch = -23
|
||||
UpgradeWatermelonFixHeight abi.ChainEpoch = -24
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
)
|
||||
|
||||
var InitActorAddr = builtin.InitActorAddr
|
||||
var SystemActorAddr = builtin.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin.CronActorAddr
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
smoothingtypes "github.com/filecoin-project/go-state-types/builtin/v8/util/smoothing"
|
||||
)
|
||||
|
||||
var InitActorAddr = builtin.InitActorAddr
|
||||
var SystemActorAddr = builtin.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin.CronActorAddr
|
||||
|
||||
@@ -72,7 +72,7 @@ func (s *state{{.v}}) AvailableBalance(bal abi.TokenAmount) (available abi.Token
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available{{if (ge .v 2)}}, err{{end}} = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state0) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state10) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmou
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state11) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmou
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state12) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmou
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -61,7 +61,7 @@ func (s *state2) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state3) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state4) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state5) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state6) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state7) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state8) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -62,7 +62,7 @@ func (s *state9) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmoun
|
||||
available = abi.NewTokenAmount(0)
|
||||
}
|
||||
}()
|
||||
// this panics if the miner doesnt have enough funds to cover their locked pledge
|
||||
// this panics if the miner doesn't have enough funds to cover their locked pledge
|
||||
available, err = s.GetAvailableBalance(bal)
|
||||
return available, err
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||
// Load returns an abstract copy of payment channel state, regardless of actor version
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
if name, av, ok := actors.GetActorMetaByCode(act.Code); ok {
|
||||
if name != manifest.PaychKey {
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
// Load returns an abstract copy of payment channel state, irregardless of actor version
|
||||
// Load returns an abstract copy of payment channel state, regardless of actor version
|
||||
func Load(store adt.Store, act *types.Actor) (State, error) {
|
||||
if name, av, ok := actors.GetActorMetaByCode(act.Code); ok {
|
||||
if name != manifest.PaychKey {
|
||||
|
||||
@@ -51,6 +51,12 @@ func RegisterManifest(av actorstypes.Version, manifestCid cid.Cid, entries map[s
|
||||
}
|
||||
}
|
||||
|
||||
func AddActorMeta(name string, codeId cid.Cid, av actorstypes.Version) {
|
||||
manifestMx.Lock()
|
||||
defer manifestMx.Unlock()
|
||||
actorMeta[codeId] = actorEntry{name: name, version: av}
|
||||
}
|
||||
|
||||
// GetManifest gets a loaded manifest.
|
||||
func GetManifest(av actorstypes.Version) (cid.Cid, bool) {
|
||||
manifestMx.RLock()
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
func SerializeParams(i cbg.CBORMarshaler) ([]byte, aerrors.ActorError) {
|
||||
buf := new(bytes.Buffer)
|
||||
if err := i.MarshalCBOR(buf); err != nil {
|
||||
// TODO: shouldnt this be a fatal error?
|
||||
// TODO: shouldn't this be a fatal error?
|
||||
return nil, aerrors.Absorb(err, exitcode.ErrSerialization, "failed to encode parameter")
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
func TestPrintGroupInfo(t *testing.T) {
|
||||
server := build.DrandConfigs[build.DrandDevnet].Servers[0]
|
||||
server := build.DrandConfigs[build.DrandTestnet].Servers[0]
|
||||
c, err := hclient.New(server, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
cg := c.(interface {
|
||||
@@ -31,7 +31,7 @@ func TestPrintGroupInfo(t *testing.T) {
|
||||
|
||||
func TestMaxBeaconRoundForEpoch(t *testing.T) {
|
||||
todayTs := uint64(1652222222)
|
||||
db, err := NewDrandBeacon(todayTs, build.BlockDelaySecs, nil, build.DrandConfigs[build.DrandDevnet])
|
||||
db, err := NewDrandBeacon(todayTs, build.BlockDelaySecs, nil, build.DrandConfigs[build.DrandTestnet])
|
||||
assert.NoError(t, err)
|
||||
mbr15 := db.MaxBeaconRoundForEpoch(network.Version15, 100)
|
||||
mbr16 := db.MaxBeaconRoundForEpoch(network.Version16, 100)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package filcns
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
@@ -19,7 +20,9 @@ import (
|
||||
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
nv18 "github.com/filecoin-project/go-state-types/builtin/v10/migration"
|
||||
init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
|
||||
nv19 "github.com/filecoin-project/go-state-types/builtin/v11/migration"
|
||||
system11 "github.com/filecoin-project/go-state-types/builtin/v11/system"
|
||||
nv21 "github.com/filecoin-project/go-state-types/builtin/v12/migration"
|
||||
nv17 "github.com/filecoin-project/go-state-types/builtin/v9/migration"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
@@ -268,11 +271,15 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
|
||||
Migration: UpgradeActorsV12,
|
||||
PreMigrations: []stmgr.PreMigration{{
|
||||
PreMigration: PreUpgradeActorsV12,
|
||||
StartWithin: 120,
|
||||
StartWithin: 180,
|
||||
DontStartWithin: 15,
|
||||
StopWithin: 10,
|
||||
}},
|
||||
Expensive: true,
|
||||
}, {
|
||||
Height: build.UpgradeWatermelonFixHeight,
|
||||
Network: network.Version21,
|
||||
Migration: upgradeActorsV12Fix,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1869,6 +1876,8 @@ func UpgradeActorsV12(ctx context.Context, sm *stmgr.StateManager, cache stmgr.M
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
var calibnetv12BuggyBundle = cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs")
|
||||
|
||||
func upgradeActorsV12Common(
|
||||
ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache,
|
||||
root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet,
|
||||
@@ -1894,13 +1903,50 @@ func upgradeActorsV12Common(
|
||||
)
|
||||
}
|
||||
|
||||
manifest, ok := actors.GetManifest(actorstypes.Version12)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade")
|
||||
// check whether or not this is a calibnet upgrade
|
||||
// we do this because calibnet upgraded to a "wrong" actors bundle, which was then corrected
|
||||
// we thus upgrade to calibrationnet-buggy in this upgrade
|
||||
actorsIn, err := state.LoadStateTree(adtStore, root)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
initActor, err := actorsIn.GetActor(builtin.InitActorAddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
|
||||
var initState init11.State
|
||||
if err := adtStore.Get(ctx, initActor.Head, &initState); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
|
||||
}
|
||||
|
||||
var manifestCid cid.Cid
|
||||
if initState.NetworkName == "calibrationnet" {
|
||||
embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, "calibrationnet-buggy")
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("didn't find buggy calibrationnet bundle")
|
||||
}
|
||||
|
||||
var err error
|
||||
manifestCid, err = bundle.LoadBundle(ctx, writeStore, bytes.NewReader(embedded))
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load buggy calibnet bundle: %w", err)
|
||||
}
|
||||
|
||||
if manifestCid != calibnetv12BuggyBundle {
|
||||
return cid.Undef, xerrors.Errorf("didn't find expected buggy calibnet bundle manifest: %s != %s", manifestCid, calibnetv12BuggyBundle)
|
||||
}
|
||||
} else {
|
||||
ok := false
|
||||
manifestCid, ok = actors.GetManifest(actorstypes.Version12)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade")
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the migration
|
||||
newHamtRoot, err := nv21.MigrateStateTree(ctx, adtStore, manifest, stateRoot.Actors, epoch, config,
|
||||
newHamtRoot, err := nv21.MigrateStateTree(ctx, adtStore, manifestCid, stateRoot.Actors, epoch, config,
|
||||
migrationLogger{}, cache)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("upgrading to actors v12: %w", err)
|
||||
@@ -1928,6 +1974,152 @@ func upgradeActorsV12Common(
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
|
||||
var calibnetv12BuggyMinerCID = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq")
|
||||
|
||||
func upgradeActorsV12Fix(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor,
|
||||
root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||
stateStore := sm.ChainStore().StateBlockstore()
|
||||
adtStore := store.ActorStore(ctx, stateStore)
|
||||
|
||||
// ensure that the manifest is loaded in the blockstore
|
||||
if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
|
||||
}
|
||||
|
||||
// Load input state tree
|
||||
actorsIn, err := state.LoadStateTree(adtStore, root)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
// load old manifest data
|
||||
systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
|
||||
var systemState system11.State
|
||||
if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
|
||||
}
|
||||
|
||||
var oldManifestData manifest.ManifestData
|
||||
if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err)
|
||||
}
|
||||
|
||||
newManifestCID, ok := actors.GetManifest(actorstypes.Version12)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade")
|
||||
}
|
||||
|
||||
// load new manifest
|
||||
var newManifest manifest.Manifest
|
||||
if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
if err := newManifest.Load(ctx, adtStore); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
// build the CID mapping
|
||||
codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries))
|
||||
for _, oldEntry := range oldManifestData.Entries {
|
||||
newCID, ok := newManifest.Get(oldEntry.Name)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name)
|
||||
}
|
||||
|
||||
// Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor
|
||||
codeMapping[oldEntry.Code] = newCID
|
||||
}
|
||||
|
||||
// Create empty actorsOut
|
||||
|
||||
actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version())
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err)
|
||||
}
|
||||
|
||||
// Perform the migration
|
||||
err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error {
|
||||
newCid, ok := codeMapping[actor.Code]
|
||||
if !ok {
|
||||
return xerrors.Errorf("didn't find mapping for %s", actor.Code)
|
||||
}
|
||||
|
||||
return actorsOut.SetActor(a, &types.ActorV5{
|
||||
Code: newCid,
|
||||
Head: actor.Head,
|
||||
Nonce: actor.Nonce,
|
||||
Balance: actor.Balance,
|
||||
Address: actor.Address,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err)
|
||||
}
|
||||
|
||||
systemState.BuiltinActors = newManifest.Data
|
||||
newSystemHead, err := adtStore.Put(ctx, &systemState)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err)
|
||||
}
|
||||
|
||||
systemActor.Head = newSystemHead
|
||||
if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err)
|
||||
}
|
||||
|
||||
// Sanity checking
|
||||
|
||||
err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error {
|
||||
outActor, err := actorsOut.GetActor(a)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get actor in outTree: %w", err)
|
||||
}
|
||||
|
||||
if inActor.Nonce != outActor.Nonce {
|
||||
return xerrors.Errorf("mismatched nonce for actor %s", a)
|
||||
}
|
||||
|
||||
if !inActor.Balance.Equals(outActor.Balance) {
|
||||
return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
|
||||
}
|
||||
|
||||
if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
|
||||
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
|
||||
}
|
||||
|
||||
if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
|
||||
return xerrors.Errorf("mismatched head for actor %s", a)
|
||||
}
|
||||
|
||||
// This is the hard-coded "buggy" miner actor Code ID
|
||||
if inActor.Code != calibnetv12BuggyMinerCID && inActor.Code != outActor.Code {
|
||||
return xerrors.Errorf("unexpected change in code for actor %s", a)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err)
|
||||
}
|
||||
|
||||
// Persist the result.
|
||||
newRoot, err := actorsOut.Flush(ctx)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
|
||||
}
|
||||
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
// Example upgrade function if upgrade requires only code changes
|
||||
//func UpgradeActorsV9(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, _ stmgr.ExecMonitor, root cid.Cid, _ abi.ChainEpoch, _ *types.TipSet) (cid.Cid, error) {
|
||||
// buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync())
|
||||
|
||||
@@ -180,7 +180,7 @@ func (e *heightEventsObserver) Revert(ctx context.Context, from, to *types.TipSe
|
||||
// Update the head first so we don't accidental skip reverting a concurrent call to ChainAt.
|
||||
e.updateHead(to)
|
||||
|
||||
// Call revert on all hights between the two tipsets, handling empty tipsets.
|
||||
// Call revert on all heights between the two tipsets, handling empty tipsets.
|
||||
for h := from.Height(); h > to.Height(); h-- {
|
||||
e.lk.Lock()
|
||||
triggers := e.tsHeights[h]
|
||||
|
||||
@@ -673,7 +673,7 @@ func TestCalled(t *testing.T) {
|
||||
}, 3, 20, matchAddrMethod(t0123, 5))
|
||||
require.NoError(t, err)
|
||||
|
||||
// create few blocks to make sure nothing get's randomly called
|
||||
// create few blocks to make sure nothing gets randomly called
|
||||
|
||||
fcs.advance(0, 4, 0, nil) // H=5
|
||||
require.Equal(t, false, applied)
|
||||
@@ -991,7 +991,7 @@ func TestCalledNull(t *testing.T) {
|
||||
}, 3, 20, matchAddrMethod(t0123, 5))
|
||||
require.NoError(t, err)
|
||||
|
||||
// create few blocks to make sure nothing get's randomly called
|
||||
// create few blocks to make sure nothing gets randomly called
|
||||
|
||||
fcs.advance(0, 4, 0, nil) // H=5
|
||||
require.Equal(t, false, applied)
|
||||
@@ -1050,7 +1050,7 @@ func TestRemoveTriggersOnMessage(t *testing.T) {
|
||||
}, 3, 20, matchAddrMethod(t0123, 5))
|
||||
require.NoError(t, err)
|
||||
|
||||
// create few blocks to make sure nothing get's randomly called
|
||||
// create few blocks to make sure nothing gets randomly called
|
||||
|
||||
fcs.advance(0, 4, 0, nil) // H=5
|
||||
require.Equal(t, false, applied)
|
||||
@@ -1155,7 +1155,7 @@ func TestStateChanged(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// create few blocks to make sure nothing get's randomly called
|
||||
// create few blocks to make sure nothing gets randomly called
|
||||
|
||||
fcs.advance(0, 4, 0, nil) // H=5
|
||||
require.Equal(t, false, applied)
|
||||
|
||||
@@ -388,7 +388,7 @@ func (m *EventFilterManager) Install(ctx context.Context, minHeight, maxHeight a
|
||||
|
||||
if m.EventIndex != nil && minHeight != -1 && minHeight < currentHeight {
|
||||
// Filter needs historic events
|
||||
if err := m.EventIndex.PrefillFilter(ctx, f); err != nil {
|
||||
if err := m.EventIndex.PrefillFilter(ctx, f, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,7 +481,7 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever
|
||||
}
|
||||
|
||||
// PrefillFilter fills a filter's collection of events from the historic index
|
||||
func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
|
||||
func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter, excludeReverted bool) error {
|
||||
clauses := []string{}
|
||||
values := []any{}
|
||||
joins := []string{}
|
||||
@@ -500,6 +500,11 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
|
||||
}
|
||||
}
|
||||
|
||||
if excludeReverted {
|
||||
clauses = append(clauses, "event.reverted=?")
|
||||
values = append(values, false)
|
||||
}
|
||||
|
||||
if len(f.addresses) > 0 {
|
||||
subclauses := []string{}
|
||||
for _, addr := range f.addresses {
|
||||
|
||||
@@ -272,7 +272,7 @@ func TestEventIndexPrefillFilter(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
tc := tc // appease lint
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if err := ei.PrefillFilter(context.Background(), tc.filter); err != nil {
|
||||
if err := ei.PrefillFilter(context.Background(), tc.filter, false); err != nil {
|
||||
require.NoError(t, err, "prefill filter events")
|
||||
}
|
||||
|
||||
@@ -281,3 +281,619 @@ func TestEventIndexPrefillFilter(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEventIndexPrefillFilterExcludeReverted(t *testing.T) {
|
||||
rng := pseudo.New(pseudo.NewSource(299792458))
|
||||
a1 := randomF4Addr(t, rng)
|
||||
a2 := randomF4Addr(t, rng)
|
||||
a3 := randomF4Addr(t, rng)
|
||||
|
||||
a1ID := abi.ActorID(1)
|
||||
a2ID := abi.ActorID(2)
|
||||
|
||||
addrMap := addressMap{}
|
||||
addrMap.add(a1ID, a1)
|
||||
addrMap.add(a2ID, a2)
|
||||
|
||||
ev1 := fakeEvent(
|
||||
a1ID,
|
||||
[]kv{
|
||||
{k: "type", v: []byte("approval")},
|
||||
{k: "signer", v: []byte("addr1")},
|
||||
},
|
||||
[]kv{
|
||||
{k: "amount", v: []byte("2988181")},
|
||||
},
|
||||
)
|
||||
ev2 := fakeEvent(
|
||||
a2ID,
|
||||
[]kv{
|
||||
{k: "type", v: []byte("approval")},
|
||||
{k: "signer", v: []byte("addr2")},
|
||||
},
|
||||
[]kv{
|
||||
{k: "amount", v: []byte("2988182")},
|
||||
},
|
||||
)
|
||||
|
||||
st := newStore()
|
||||
events := []*types.Event{ev1}
|
||||
revertedEvents := []*types.Event{ev2}
|
||||
em := executedMessage{
|
||||
msg: fakeMessage(randomF4Addr(t, rng), randomF4Addr(t, rng)),
|
||||
rct: fakeReceipt(t, rng, st, events),
|
||||
evs: events,
|
||||
}
|
||||
revertedEm := executedMessage{
|
||||
msg: fakeMessage(randomF4Addr(t, rng), randomF4Addr(t, rng)),
|
||||
rct: fakeReceipt(t, rng, st, revertedEvents),
|
||||
evs: revertedEvents,
|
||||
}
|
||||
|
||||
events14000 := buildTipSetEvents(t, rng, 14000, em)
|
||||
revertedEvents14000 := buildTipSetEvents(t, rng, 14000, revertedEm)
|
||||
cid14000, err := events14000.msgTs.Key().Cid()
|
||||
require.NoError(t, err, "tipset cid")
|
||||
reveredCID14000, err := revertedEvents14000.msgTs.Key().Cid()
|
||||
require.NoError(t, err, "tipset cid")
|
||||
|
||||
noCollectedEvents := []*CollectedEvent{}
|
||||
oneCollectedEvent := []*CollectedEvent{
|
||||
{
|
||||
Entries: ev1.Entries,
|
||||
EmitterAddr: a1,
|
||||
EventIdx: 0,
|
||||
Reverted: false,
|
||||
Height: 14000,
|
||||
TipSetKey: events14000.msgTs.Key(),
|
||||
MsgIdx: 0,
|
||||
MsgCid: em.msg.Cid(),
|
||||
},
|
||||
}
|
||||
twoCollectedEvent := []*CollectedEvent{
|
||||
{
|
||||
Entries: ev1.Entries,
|
||||
EmitterAddr: a1,
|
||||
EventIdx: 0,
|
||||
Reverted: false,
|
||||
Height: 14000,
|
||||
TipSetKey: events14000.msgTs.Key(),
|
||||
MsgIdx: 0,
|
||||
MsgCid: em.msg.Cid(),
|
||||
},
|
||||
{
|
||||
Entries: ev2.Entries,
|
||||
EmitterAddr: a2,
|
||||
EventIdx: 0,
|
||||
Reverted: true,
|
||||
Height: 14000,
|
||||
TipSetKey: revertedEvents14000.msgTs.Key(),
|
||||
MsgIdx: 0,
|
||||
MsgCid: revertedEm.msg.Cid(),
|
||||
},
|
||||
}
|
||||
oneCollectedRevertedEvent := []*CollectedEvent{
|
||||
{
|
||||
Entries: ev2.Entries,
|
||||
EmitterAddr: a2,
|
||||
EventIdx: 0,
|
||||
Reverted: true,
|
||||
Height: 14000,
|
||||
TipSetKey: revertedEvents14000.msgTs.Key(),
|
||||
MsgIdx: 0,
|
||||
MsgCid: revertedEm.msg.Cid(),
|
||||
},
|
||||
}
|
||||
|
||||
workDir, err := os.MkdirTemp("", "lotusevents")
|
||||
require.NoError(t, err, "create temporary work directory")
|
||||
|
||||
defer func() {
|
||||
_ = os.RemoveAll(workDir)
|
||||
}()
|
||||
t.Logf("using work dir %q", workDir)
|
||||
|
||||
dbPath := filepath.Join(workDir, "actorevents.db")
|
||||
|
||||
ei, err := NewEventIndex(context.Background(), dbPath, nil)
|
||||
require.NoError(t, err, "create event index")
|
||||
if err := ei.CollectEvents(context.Background(), revertedEvents14000, false, addrMap.ResolveAddress); err != nil {
|
||||
require.NoError(t, err, "collect reverted events")
|
||||
}
|
||||
if err := ei.CollectEvents(context.Background(), revertedEvents14000, true, addrMap.ResolveAddress); err != nil {
|
||||
require.NoError(t, err, "revert reverted events")
|
||||
}
|
||||
if err := ei.CollectEvents(context.Background(), events14000, false, addrMap.ResolveAddress); err != nil {
|
||||
require.NoError(t, err, "collect events")
|
||||
}
|
||||
|
||||
inclusiveTestCases := []struct {
|
||||
name string
|
||||
filter *EventFilter
|
||||
te *TipSetEvents
|
||||
want []*CollectedEvent
|
||||
}{
|
||||
{
|
||||
name: "nomatch tipset min height",
|
||||
filter: &EventFilter{
|
||||
minHeight: 14001,
|
||||
maxHeight: -1,
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch tipset max height",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: 13999,
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match tipset min height",
|
||||
filter: &EventFilter{
|
||||
minHeight: 14000,
|
||||
maxHeight: -1,
|
||||
},
|
||||
te: events14000,
|
||||
want: twoCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match tipset cid",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
tipsetCid: cid14000,
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match tipset cid",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
tipsetCid: reveredCID14000,
|
||||
},
|
||||
te: revertedEvents14000,
|
||||
want: oneCollectedRevertedEvent,
|
||||
},
|
||||
{
|
||||
name: "nomatch address",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a3},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match address 2",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a2},
|
||||
},
|
||||
te: revertedEvents14000,
|
||||
want: oneCollectedRevertedEvent,
|
||||
},
|
||||
{
|
||||
name: "match address 1",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a1},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match one entry",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: twoCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match one entry with alternate values",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("cancel"),
|
||||
[]byte("propose"),
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: twoCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry by missing value",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("cancel"),
|
||||
[]byte("propose"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry by missing key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"method": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match one entry with multiple keys",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match one entry with multiple keys",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: revertedEvents14000,
|
||||
want: oneCollectedRevertedEvent,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one mismatching key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"approver": {
|
||||
[]byte("addr1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one mismatching value",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr3"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one unindexed key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"amount": {
|
||||
[]byte("2988181"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one unindexed key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"amount": {
|
||||
[]byte("2988182"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
}
|
||||
|
||||
exclusiveTestCases := []struct {
|
||||
name string
|
||||
filter *EventFilter
|
||||
te *TipSetEvents
|
||||
want []*CollectedEvent
|
||||
}{
|
||||
{
|
||||
name: "nomatch tipset min height",
|
||||
filter: &EventFilter{
|
||||
minHeight: 14001,
|
||||
maxHeight: -1,
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch tipset max height",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: 13999,
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match tipset min height",
|
||||
filter: &EventFilter{
|
||||
minHeight: 14000,
|
||||
maxHeight: -1,
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match tipset cid",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
tipsetCid: cid14000,
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match tipset cid but reverted",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
tipsetCid: reveredCID14000,
|
||||
},
|
||||
te: revertedEvents14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch address",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a3},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch address 2 but reverted",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a2},
|
||||
},
|
||||
te: revertedEvents14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match address",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
addresses: []address.Address{a1},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match one entry",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "match one entry with alternate values",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("cancel"),
|
||||
[]byte("propose"),
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry by missing value",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("cancel"),
|
||||
[]byte("propose"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry by missing key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"method": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "match one entry with multiple keys",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: oneCollectedEvent,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one mismatching key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"approver": {
|
||||
[]byte("addr1"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with matching reverted value",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr2"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one mismatching value",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"type": {
|
||||
[]byte("approval"),
|
||||
},
|
||||
"signer": {
|
||||
[]byte("addr3"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
{
|
||||
name: "nomatch one entry with one unindexed key",
|
||||
filter: &EventFilter{
|
||||
minHeight: -1,
|
||||
maxHeight: -1,
|
||||
keys: map[string][][]byte{
|
||||
"amount": {
|
||||
[]byte("2988181"),
|
||||
},
|
||||
},
|
||||
},
|
||||
te: events14000,
|
||||
want: noCollectedEvents,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range inclusiveTestCases {
|
||||
tc := tc // appease lint
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if err := ei.PrefillFilter(context.Background(), tc.filter, false); err != nil {
|
||||
require.NoError(t, err, "prefill filter events")
|
||||
}
|
||||
|
||||
coll := tc.filter.TakeCollectedEvents(context.Background())
|
||||
require.ElementsMatch(t, coll, tc.want, tc.name)
|
||||
})
|
||||
}
|
||||
|
||||
for _, tc := range exclusiveTestCases {
|
||||
tc := tc // appease lint
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if err := ei.PrefillFilter(context.Background(), tc.filter, true); err != nil {
|
||||
require.NoError(t, err, "prefill filter events")
|
||||
}
|
||||
|
||||
coll := tc.filter.TakeCollectedEvents(context.Background())
|
||||
require.ElementsMatch(t, coll, tc.want, tc.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ func (c *client) processResponse(req *Request, res *Response, tipsets []*types.T
|
||||
// If we didn't request the headers they should have been provided
|
||||
// by the caller.
|
||||
if len(tipsets) < len(res.Chain) {
|
||||
return nil, xerrors.Errorf("not enought tipsets provided for message response validation, needed %d, have %d", len(res.Chain), len(tipsets))
|
||||
return nil, xerrors.Errorf("not enough tipsets provided for message response validation, needed %d, have %d", len(res.Chain), len(tipsets))
|
||||
}
|
||||
chain := make([]*BSTipSet, 0, resLength)
|
||||
for i, resChain := range res.Chain {
|
||||
|
||||
@@ -131,7 +131,7 @@ func NewMsgIndex(lctx context.Context, basePath string, cs ChainStore) (MsgIndex
|
||||
|
||||
db, err := sql.Open("sqlite3", dbPath)
|
||||
if err != nil {
|
||||
// TODO [nice to have]: automaticaly delete corrupt databases
|
||||
// TODO [nice to have]: automatically delete corrupt databases
|
||||
// but for now we can just error and let the operator delete.
|
||||
return nil, xerrors.Errorf("error opening msgindex database: %w", err)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||
"github.com/minio/blake2b-simd"
|
||||
"github.com/raulk/clock"
|
||||
"go.opencensus.io/stats"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
ffi "github.com/filecoin-project/filecoin-ffi"
|
||||
@@ -1021,6 +1022,9 @@ func (mp *MessagePool) addLocked(ctx context.Context, m *types.SignedMessage, st
|
||||
}
|
||||
})
|
||||
|
||||
// Record the current size of the Mpool
|
||||
stats.Record(ctx, metrics.MpoolMessageCount.M(int64(mp.currentSize)))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1213,6 +1217,9 @@ func (mp *MessagePool) remove(ctx context.Context, from address.Address, nonce u
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Record the current size of the Mpool
|
||||
stats.Record(ctx, metrics.MpoolMessageCount.M(int64(mp.currentSize)))
|
||||
}
|
||||
|
||||
func (mp *MessagePool) Pending(ctx context.Context) ([]*types.SignedMessage, *types.TipSet) {
|
||||
|
||||
@@ -570,7 +570,7 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
|
||||
}
|
||||
|
||||
// no need to record anything here, there are no duplicates in the actors HAMT
|
||||
// iself.
|
||||
// itself.
|
||||
if _, ok := seen[addr]; ok {
|
||||
return nil
|
||||
}
|
||||
@@ -588,7 +588,7 @@ func (st *StateTree) ForEach(f func(address.Address, *types.Actor) error) error
|
||||
}
|
||||
|
||||
// no need to record anything here, there are no duplicates in the actors HAMT
|
||||
// iself.
|
||||
// itself.
|
||||
if _, ok := seen[addr]; ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
+12
-9
@@ -178,16 +178,18 @@ func (sm *StateManager) HandleStateForks(ctx context.Context, root cid.Cid, heig
|
||||
retCid := root
|
||||
u := sm.stateMigrations[height]
|
||||
if u != nil && u.upgrade != nil {
|
||||
migCid, ok, err := u.migrationResultCache.Get(ctx, root)
|
||||
if err == nil {
|
||||
if ok {
|
||||
log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
|
||||
return migCid, nil
|
||||
if height != build.UpgradeWatermelonFixHeight {
|
||||
migCid, ok, err := u.migrationResultCache.Get(ctx, root)
|
||||
if err == nil {
|
||||
if ok {
|
||||
log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
|
||||
return migCid, nil
|
||||
}
|
||||
} else if !errors.Is(err, datastore.ErrNotFound) {
|
||||
log.Errorw("failed to lookup previous migration result", "err", err)
|
||||
} else {
|
||||
log.Debug("no cached migration found, migrating from scratch")
|
||||
}
|
||||
} else if !errors.Is(err, datastore.ErrNotFound) {
|
||||
log.Errorw("failed to lookup previous migration result", "err", err)
|
||||
} else {
|
||||
log.Debug("no cached migration found, migrating from scratch")
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
@@ -195,6 +197,7 @@ func (sm *StateManager) HandleStateForks(ctx context.Context, root cid.Cid, heig
|
||||
// Yes, we clone the cache, even for the final upgrade epoch. Why? Reverts. We may
|
||||
// have to migrate multiple times.
|
||||
tmpCache := u.cache.Clone()
|
||||
var err error
|
||||
retCid, err = u.upgrade(ctx, sm, tmpCache, cb, root, height, ts)
|
||||
if err != nil {
|
||||
log.Errorw("FAILED migration", "height", height, "from", root, "error", err)
|
||||
|
||||
@@ -212,13 +212,8 @@ func (cs *ChainStore) MessagesForTipset(ctx context.Context, ts *types.TipSet) (
|
||||
|
||||
var out []types.ChainMsg
|
||||
for _, bm := range bmsgs {
|
||||
for _, blsm := range bm.BlsMessages {
|
||||
out = append(out, blsm)
|
||||
}
|
||||
|
||||
for _, secm := range bm.SecpkMessages {
|
||||
out = append(out, secm)
|
||||
}
|
||||
out = append(out, bm.BlsMessages...)
|
||||
out = append(out, bm.SecpkMessages...)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
|
||||
@@ -167,7 +167,7 @@ func (t walkSchedTaskType) String() string {
|
||||
case dagTask:
|
||||
return "dag"
|
||||
}
|
||||
panic(fmt.Sprintf("unknow task %d", t))
|
||||
panic(fmt.Sprintf("unknown task %d", t))
|
||||
}
|
||||
|
||||
type walkTask struct {
|
||||
@@ -656,9 +656,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
|
||||
}
|
||||
|
||||
if b.Height > 0 {
|
||||
for _, p := range b.Parents {
|
||||
blocksToWalk = append(blocksToWalk, p)
|
||||
}
|
||||
blocksToWalk = append(blocksToWalk, b.Parents...)
|
||||
} else {
|
||||
// include the genesis block
|
||||
cids = append(cids, b.Parents...)
|
||||
|
||||
@@ -516,7 +516,7 @@ func (v *IndexerMessageValidator) Validate(ctx context.Context, pid peer.ID, msg
|
||||
return pubsub.ValidationReject
|
||||
}
|
||||
if len(idxrMsg.ExtraData) == 0 {
|
||||
log.Debugw("ignoring messsage missing miner id", "peer", originPeer)
|
||||
log.Debugw("ignoring message missing miner id", "peer", originPeer)
|
||||
return pubsub.ValidationIgnore
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ func (v *IndexerMessageValidator) Validate(ctx context.Context, pid peer.ID, msg
|
||||
// Check that the miner ID maps to the peer that sent the message.
|
||||
err = v.authenticateMessage(ctx, minerAddr, originPeer)
|
||||
if err != nil {
|
||||
log.Warnw("cannot authenticate messsage", "err", err, "peer", originPeer, "minerID", minerAddr)
|
||||
log.Warnw("cannot authenticate message", "err", err, "peer", originPeer, "minerID", minerAddr)
|
||||
stats.Record(ctx, metrics.IndexerMessageValidationFailure.M(1))
|
||||
return pubsub.ValidationReject
|
||||
}
|
||||
|
||||
+3
-3
@@ -844,7 +844,7 @@ loop:
|
||||
return nil, xerrors.Errorf("failed to load next local tipset: %w", err)
|
||||
}
|
||||
if base.IsChildOf(knownParent) {
|
||||
// common case: receiving a block thats potentially part of the same tipset as our best block
|
||||
// common case: receiving a block that's potentially part of the same tipset as our best block
|
||||
return blockSet, nil
|
||||
}
|
||||
|
||||
@@ -1094,8 +1094,8 @@ func (syncer *Syncer) fetchMessages(ctx context.Context, headers []*types.TipSet
|
||||
requestErr = multierror.Append(requestErr, err)
|
||||
} else {
|
||||
isGood := true
|
||||
for index, ts := range headers[nextI:lastI] {
|
||||
cm := result[index]
|
||||
for index, cm := range result {
|
||||
ts := headers[nextI+index]
|
||||
if err := checkMsgMeta(ts, cm.Bls, cm.Secpk, cm.BlsIncludes, cm.SecpkIncludes); err != nil {
|
||||
log.Errorf("fetched messages not as expected: %s", err)
|
||||
isGood = false
|
||||
|
||||
@@ -102,6 +102,10 @@ func (e EthBigInt) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(e.String())
|
||||
}
|
||||
|
||||
func (e EthBigInt) ToInt() big.Int {
|
||||
return (big.Int)(e)
|
||||
}
|
||||
|
||||
func (e *EthBigInt) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
if err := json.Unmarshal(b, &s); err != nil {
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package ethtypes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
|
||||
logger "github.com/ipfs/go-log/v2"
|
||||
)
|
||||
|
||||
// TraceConfig holds extra parameters to trace functions.
|
||||
type TraceConfig struct {
|
||||
*logger.Config
|
||||
Tracer *string
|
||||
Timeout *string
|
||||
Reexec *uint64
|
||||
// Config specific to given tracer. Note struct logger
|
||||
// config are historically embedded in main object.
|
||||
TracerConfig json.RawMessage
|
||||
}
|
||||
|
||||
// TraceCallConfig is the config for traceCall API. It holds one more
|
||||
// field to override the state for tracing.
|
||||
type TraceCallConfig struct {
|
||||
TraceConfig
|
||||
StateOverrides *StateOverride
|
||||
BlockOverrides *BlockOverrides
|
||||
}
|
||||
|
||||
// OverrideAccount indicates the overriding fields of account during the execution
|
||||
// of a message call.
|
||||
// Note, state and stateDiff can't be specified at the same time. If state is
|
||||
// set, message execution will only use the data in the given state. Otherwise
|
||||
// if statDiff is set, all diff will be applied first and then execute the call
|
||||
// message.
|
||||
type OverrideAccount struct {
|
||||
Nonce *EthUint64 `json:"nonce"`
|
||||
Code *EthBytes `json:"code"`
|
||||
Balance **EthBigInt `json:"balance"`
|
||||
State *map[EthHash]EthHash `json:"state"`
|
||||
StateDiff *map[EthHash]EthHash `json:"stateDiff"`
|
||||
}
|
||||
|
||||
// StateOverride is the collection of overridden accounts.
|
||||
type StateOverride map[EthHash]OverrideAccount
|
||||
|
||||
// BlockOverrides is a set of header fields to override.
|
||||
type BlockOverrides struct {
|
||||
Number *EthBigInt
|
||||
Difficulty *EthBigInt
|
||||
Time *EthUint64
|
||||
GasLimit *EthUint64
|
||||
Coinbase *EthAddress
|
||||
Random *EthHash
|
||||
BaseFee *EthUint64
|
||||
}
|
||||
|
||||
// Apply overrides the given header fields into the given block context.
|
||||
func (diff *BlockOverrides) Apply(blockCtx *BlockContext) {
|
||||
if diff == nil {
|
||||
return
|
||||
}
|
||||
if diff.Number != nil {
|
||||
blockCtx.BlockNumber = diff.Number.Int
|
||||
}
|
||||
if diff.Difficulty != nil {
|
||||
blockCtx.Difficulty = diff.Difficulty.Int
|
||||
}
|
||||
if diff.Time != nil {
|
||||
blockCtx.Time = uint64(*diff.Time)
|
||||
}
|
||||
if diff.GasLimit != nil {
|
||||
blockCtx.GasLimit = uint64(*diff.GasLimit)
|
||||
}
|
||||
if diff.Coinbase != nil {
|
||||
blockCtx.Coinbase = *diff.Coinbase
|
||||
}
|
||||
if diff.Random != nil {
|
||||
blockCtx.Random = diff.Random
|
||||
}
|
||||
if diff.BaseFee != nil {
|
||||
blockCtx.BaseFee = new(big.Int).SetUint64((uint64)(*diff.BaseFee))
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// CanTransferFunc is the signature of a transfer guard function
|
||||
CanTransferFunc func(StateDB, EthAddress, *big.Int) bool
|
||||
// TransferFunc is the signature of a transfer function
|
||||
TransferFunc func(StateDB, EthAddress, EthAddress, *big.Int)
|
||||
// GetHashFunc returns the n'th block hash in the blockchain
|
||||
// and is used by the BLOCKHASH EVM op code.
|
||||
GetHashFunc func(uint64) EthAddress
|
||||
)
|
||||
|
||||
// BlockContext provides the EVM with auxiliary information. Once provided
|
||||
// it shouldn't be modified.
|
||||
type BlockContext struct {
|
||||
// CanTransfer returns whether the account contains
|
||||
// sufficient ether to transfer the value
|
||||
CanTransfer CanTransferFunc
|
||||
// Transfer transfers ether from one account to the other
|
||||
Transfer TransferFunc
|
||||
// GetHash returns the hash corresponding to n
|
||||
GetHash GetHashFunc
|
||||
|
||||
// Block information
|
||||
Coinbase EthAddress // Provides information for COINBASE
|
||||
GasLimit uint64 // Provides information for GASLIMIT
|
||||
BlockNumber *big.Int // Provides information for NUMBER
|
||||
Time uint64 // Provides information for TIME
|
||||
Difficulty *big.Int // Provides information for DIFFICULTY
|
||||
BaseFee *big.Int // Provides information for BASEFEE
|
||||
Random *EthHash // Provides information for PREVRANDAO
|
||||
}
|
||||
|
||||
// TxTraceResult is the result of a single transaction trace.
|
||||
type TxTraceResult struct {
|
||||
Result interface{} `json:"result,omitempty"` // Trace results produced by the tracer
|
||||
Error string `json:"error,omitempty"` // Trace failure produced by the tracer
|
||||
}
|
||||
@@ -140,7 +140,7 @@ func (t *messageReceiptV0) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
return fmt.Errorf("int64 negative overflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
@@ -186,7 +186,7 @@ func (t *messageReceiptV0) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
return fmt.Errorf("int64 negative overflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
@@ -278,7 +278,7 @@ func (t *messageReceiptV1) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
return fmt.Errorf("int64 negative overflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
@@ -324,7 +324,7 @@ func (t *messageReceiptV1) UnmarshalCBOR(r io.Reader) (err error) {
|
||||
case cbg.MajNegativeInt:
|
||||
extraI = int64(extra)
|
||||
if extraI < 0 {
|
||||
return fmt.Errorf("int64 negative oveflow")
|
||||
return fmt.Errorf("int64 negative overflow")
|
||||
}
|
||||
extraI = -1 - extraI
|
||||
default:
|
||||
|
||||
@@ -92,6 +92,15 @@ func (x *FvmExtern) VerifyConsensusFault(ctx context.Context, a, b, extra []byte
|
||||
log.Info("invalid consensus fault: submitted blocks are the same")
|
||||
return ret, totalGas
|
||||
}
|
||||
|
||||
// workaround chain halt
|
||||
if build.IsNearUpgrade(blockA.Height, build.UpgradeWatermelonFixHeight) {
|
||||
return ret, totalGas
|
||||
}
|
||||
if build.IsNearUpgrade(blockB.Height, build.UpgradeWatermelonFixHeight) {
|
||||
return ret, totalGas
|
||||
}
|
||||
|
||||
// (1) check conditions necessary to any consensus fault
|
||||
|
||||
// were blocks mined by same miner?
|
||||
|
||||
+23
-2
@@ -1920,8 +1920,29 @@ var StateSysActorCIDsCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for name, cid := range actorsCids {
|
||||
_, _ = fmt.Fprintf(tw, "%v\t%v\n", name, cid)
|
||||
|
||||
var actorsCidTuples []struct {
|
||||
actorName string
|
||||
actorCid cid.Cid
|
||||
}
|
||||
|
||||
for name, actorCid := range actorsCids {
|
||||
keyVal := struct {
|
||||
actorName string
|
||||
actorCid cid.Cid
|
||||
}{
|
||||
actorName: name,
|
||||
actorCid: actorCid,
|
||||
}
|
||||
actorsCidTuples = append(actorsCidTuples, keyVal)
|
||||
}
|
||||
|
||||
sort.Slice(actorsCidTuples, func(i, j int) bool {
|
||||
return actorsCidTuples[i].actorName < actorsCidTuples[j].actorName
|
||||
})
|
||||
|
||||
for _, keyVal := range actorsCidTuples {
|
||||
_, _ = fmt.Fprintf(tw, "%v\t%v\n", keyVal.actorName, keyVal.actorCid)
|
||||
}
|
||||
return tw.Flush()
|
||||
},
|
||||
|
||||
@@ -143,7 +143,7 @@ var runCmd = &cli.Command{
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "rate-limit-timeout",
|
||||
Usage: "the maximum time to wait for the rate limter before returning an error to clients",
|
||||
Usage: "the maximum time to wait for the rate limiter before returning an error to clients",
|
||||
Value: gateway.DefaultRateLimitTimeout,
|
||||
},
|
||||
&cli.Int64Flag{
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/builtin"
|
||||
v10 "github.com/filecoin-project/go-state-types/builtin/v10"
|
||||
v11 "github.com/filecoin-project/go-state-types/builtin/v11"
|
||||
v12 "github.com/filecoin-project/go-state-types/builtin/v12"
|
||||
v8 "github.com/filecoin-project/go-state-types/builtin/v8"
|
||||
v9 "github.com/filecoin-project/go-state-types/builtin/v9"
|
||||
|
||||
@@ -149,6 +150,13 @@ var invariantsCmd = &cli.Command{
|
||||
if err != nil {
|
||||
return xerrors.Errorf("checking state invariants: %w", err)
|
||||
}
|
||||
case actorstypes.Version12:
|
||||
messages, err = v12.CheckStateInvariants(actorTree, abi.ChainEpoch(epoch), actorCodeCids)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("checking state invariants: %w", err)
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf("unsupported actor version: %v", av)
|
||||
}
|
||||
|
||||
fmt.Println("completed, took ", time.Since(startTime))
|
||||
|
||||
+14
-22
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
|
||||
badgerbs "github.com/filecoin-project/lotus/blockstore/badger"
|
||||
"github.com/filecoin-project/lotus/blockstore"
|
||||
"github.com/filecoin-project/lotus/chain/consensus/filcns"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
@@ -144,13 +144,6 @@ var stateTreePruneCmd = &cli.Command{
|
||||
}
|
||||
}()
|
||||
|
||||
// After migrating to native blockstores, this has been made
|
||||
// database-specific.
|
||||
badgbs, ok := bs.(*badgerbs.Blockstore)
|
||||
if !ok {
|
||||
return fmt.Errorf("only badger blockstores are supported")
|
||||
}
|
||||
|
||||
mds, err := lkrepo.Datastore(context.Background(), "/metadata")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -160,8 +153,12 @@ var stateTreePruneCmd = &cli.Command{
|
||||
const DiscardRatio = 0.2
|
||||
if cctx.Bool("only-ds-gc") {
|
||||
fmt.Println("running datastore gc....")
|
||||
gbs, ok := bs.(blockstore.BlockstoreGCOnce)
|
||||
if !ok {
|
||||
return xerrors.Errorf("blockstore %T does not support GC", bs)
|
||||
}
|
||||
for i := 0; i < cctx.Int("gc-count"); i++ {
|
||||
if err := badgbs.DB().RunValueLogGC(DiscardRatio); err != nil {
|
||||
if err := gbs.GCOnce(ctx, blockstore.WithThreshold(DiscardRatio)); err != nil {
|
||||
return xerrors.Errorf("datastore GC failed: %w", err)
|
||||
}
|
||||
}
|
||||
@@ -208,13 +205,6 @@ var stateTreePruneCmd = &cli.Command{
|
||||
return nil
|
||||
}
|
||||
|
||||
b := badgbs.DB().NewWriteBatch()
|
||||
defer b.Cancel()
|
||||
|
||||
markForRemoval := func(c cid.Cid) error {
|
||||
return b.Delete(badgbs.StorageKey(nil, c))
|
||||
}
|
||||
|
||||
keys, err := bs.AllKeysChan(context.Background())
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to query blockstore: %w", err)
|
||||
@@ -225,12 +215,12 @@ var stateTreePruneCmd = &cli.Command{
|
||||
var deleteCount int
|
||||
var goodHits int
|
||||
for k := range keys {
|
||||
if goodSet.HasRaw(k.Bytes()) {
|
||||
if goodSet.Has(k) {
|
||||
goodHits++
|
||||
continue
|
||||
}
|
||||
|
||||
if err := markForRemoval(k); err != nil {
|
||||
if err := bs.DeleteBlock(ctx, k); err != nil {
|
||||
return fmt.Errorf("failed to remove cid %s: %w", k, err)
|
||||
}
|
||||
|
||||
@@ -243,13 +233,15 @@ var stateTreePruneCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
|
||||
if err := b.Flush(); err != nil {
|
||||
return xerrors.Errorf("failed to flush final batch delete: %w", err)
|
||||
fmt.Println("running datastore gc....")
|
||||
gbs, ok := bs.(blockstore.BlockstoreGCOnce)
|
||||
if !ok {
|
||||
fmt.Println("gc not supported...")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("running datastore gc....")
|
||||
for i := 0; i < cctx.Int("gc-count"); i++ {
|
||||
if err := badgbs.DB().RunValueLogGC(DiscardRatio); err != nil {
|
||||
if err := gbs.GCOnce(ctx, blockstore.WithThreshold(DiscardRatio)); err != nil {
|
||||
return xerrors.Errorf("datastore GC failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -348,6 +349,18 @@ var runCmd = &cli.Command{
|
||||
// Connect to storage-miner
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
// Create a new context with cancel function
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// Listen for interrupt signals
|
||||
go func() {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
<-c
|
||||
cancel()
|
||||
}()
|
||||
|
||||
var nodeApi api.StorageMiner
|
||||
var closer func()
|
||||
for {
|
||||
@@ -359,14 +372,13 @@ var runCmd = &cli.Command{
|
||||
}
|
||||
}
|
||||
fmt.Printf("\r\x1b[0KConnecting to miner API... (%s)", err)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return xerrors.New("Interrupted by user")
|
||||
case <-time.After(time.Second):
|
||||
}
|
||||
}
|
||||
|
||||
defer closer()
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
// Register all metric views
|
||||
if err := view.Register(
|
||||
metrics.DefaultViews...,
|
||||
|
||||
@@ -104,9 +104,9 @@ domain separation tag.
|
||||
### Winning PoSt proof
|
||||
|
||||
Draw randomness for current epoch with `WinningPoSt` domain separation tag.
|
||||
Get list of sectors challanged in this epoch for this miner, based on the randomness drawn.
|
||||
Get list of sectors challenged in this epoch for this miner, based on the randomness drawn.
|
||||
|
||||
`V`: Use filecoin proofs system to verify that miner prooved access to sealed versions of these sectors.
|
||||
`V`: Use filecoin proofs system to verify that miner proved access to sealed versions of these sectors.
|
||||
|
||||
## `(*StateManager).TipSetState()`
|
||||
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
**Note for whoever is owning the release:** please capture notes as comments in this issue for anything you noticed that could be improved for future releases. There is a *Post Release* step below for incorporating changes back into the [RELEASE_ISSUE_TEMPLATE](https://github.com/filecoin-project/lotus/blob/master/documentation/misc/RELEASE_ISSUE_TEMPLATE.md), and this is easier done by collecting notes from along the way rather than just thinking about it at the end.
|
||||
|
||||
First steps:
|
||||
- [ ] FFI: Fork a new branch (`release/lotus-vX.Y.Z`) from the filecoin-ffi `master` branch
|
||||
- [ ] FFI: Tag the head of `release/lotus-vX.Y.Z` as `vX.Y.Z-pre1`
|
||||
- [ ] Set shell variables vX.Y.Z `export X=1 && export Y=24 && export Z=3`
|
||||
- [ ] FFI: Fork a new branch (`release/lotus-vX.Y.Z`) from the filecoin-ffi `master` branch: `git checkout master && git checkout -b release/lotus-v$X.$Y.$Z`
|
||||
- [ ] FFI: Tag the head of `release/lotus-vX.Y.Z` as `vX.Y.Z-pre1`: `git tag -a v$X.$Y.$Z-pre1 -m"release"`
|
||||
- [ ] Open and land a PR in lotus `master` that updates the FFI dependency to `vX.Y.Z-pre1` as cut in the previous step
|
||||
- [ ] Fork a new branch (`release/vX.Y.Z`) from `master` and make any further release related changes to this branch. If any "non-trivial" changes get added to the release, uncheck all the checkboxes and return to this stage.
|
||||
- [ ] Bump the version in `build/version.go` in the `master` branch to `vX.Y.(Z+1)-dev` (bump from feature release) or `vX.(Y+1).0-dev` (bump from mandatory release). Run make gen and make docsgen-cli before committing changes
|
||||
- [ ] Bump the version in `build/version.go` in the `master` branch to `vX.Y.(Z+1)-dev` (bump from feature release) or `vX.(Y+1).0-dev` (bump from mandatory release).
|
||||
- [ ] Run `make gen && make docsgen-cli` before committing changes
|
||||
|
||||
**Prepping an RC**:
|
||||
|
||||
@@ -26,6 +28,7 @@ First steps:
|
||||
- [ ] run `make gen && make docsgen-cli`
|
||||
- [ ] Generate changelog using the script at scripts/mkreleaselog
|
||||
- [ ] Add contents of generated text to lotus/CHANGELOG.md in addition to other details
|
||||
- [ ] Commit using PR
|
||||
- [ ] tag commit with `vX.Y.Z-rcN`
|
||||
- [ ] cut a pre-release [here](https://github.com/filecoin-project/lotus/releases/new?prerelease=true)
|
||||
|
||||
|
||||
@@ -146,6 +146,9 @@ type TargetAPI interface {
|
||||
Web3ClientVersion(ctx context.Context) (string, error)
|
||||
EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error)
|
||||
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)
|
||||
EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error)
|
||||
EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
}
|
||||
|
||||
var _ TargetAPI = *new(api.FullNode) // gateway depends on latest
|
||||
|
||||
@@ -606,6 +606,42 @@ func (gw *Node) EthTraceReplayBlockTransactions(ctx context.Context, blkNum stri
|
||||
return gw.target.EthTraceReplayBlockTransactions(ctx, blkNum, traceTypes)
|
||||
}
|
||||
|
||||
func (gw *Node) EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error) {
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := gw.checkEthBlockParam(ctx, blockNrOrHash, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gw.target.EthDebugTraceCall(ctx, args, blockNrOrHash, config)
|
||||
}
|
||||
|
||||
func (gw *Node) EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := gw.checkBlkHash(ctx, hash); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gw.target.EthDebugTraceBlockByHash(ctx, hash, config)
|
||||
}
|
||||
|
||||
func (gw *Node) EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := gw.checkBlkParam(ctx, number, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gw.target.EthDebugTraceBlockByNumber(ctx, number, config)
|
||||
}
|
||||
|
||||
var EthMaxFiltersPerConn = 16 // todo make this configurable
|
||||
|
||||
func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID, error)) (ethtypes.EthFilterID, error) {
|
||||
|
||||
@@ -81,12 +81,16 @@ func TestValueTransferValidSignature(t *testing.T) {
|
||||
receipt, err := waitForEthTxReceipt(ctx, client, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
require.EqualValues(t, ethAddr, receipt.From)
|
||||
require.EqualValues(t, ethAddr2, *receipt.To)
|
||||
require.EqualValues(t, hash, receipt.TransactionHash)
|
||||
|
||||
// Success.
|
||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||
|
||||
// Validate that we sent the expected transaction.
|
||||
ethTx, err := client.EthGetTransactionByHash(ctx, &hash)
|
||||
require.Nil(t, err)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, ethAddr, ethTx.From)
|
||||
require.EqualValues(t, ethAddr2, *ethTx.To)
|
||||
require.EqualValues(t, tx.ChainID, ethTx.ChainID)
|
||||
@@ -269,6 +273,17 @@ func TestContractInvocation(t *testing.T) {
|
||||
|
||||
// Success.
|
||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||
|
||||
// Validate that we correctly computed the gas outputs.
|
||||
mCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, mCid)
|
||||
|
||||
invokResult, err := client.StateReplay(ctx, types.EmptyTSK, *mCid)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, invokResult.GasCost.GasUsed, big.NewInt(int64(receipt.GasUsed)))
|
||||
effectiveGasPrice := big.Div(invokResult.GasCost.TotalCost, invokResult.GasCost.GasUsed)
|
||||
require.EqualValues(t, effectiveGasPrice, big.Int(receipt.EffectiveGasPrice))
|
||||
}
|
||||
|
||||
func TestGetBlockByNumber(t *testing.T) {
|
||||
|
||||
@@ -106,6 +106,7 @@ var (
|
||||
MpoolAddTsDuration = stats.Float64("mpool/addts_ms", "Duration of addTs in mpool", stats.UnitMilliseconds)
|
||||
MpoolAddDuration = stats.Float64("mpool/add_ms", "Duration of Add in mpool", stats.UnitMilliseconds)
|
||||
MpoolPushDuration = stats.Float64("mpool/push_ms", "Duration of Push in mpool", stats.UnitMilliseconds)
|
||||
MpoolMessageCount = stats.Int64("mpool/message_count", "Number of messages in the mpool", stats.UnitDimensionless)
|
||||
BlockPublished = stats.Int64("block/published", "Counter for total locally published blocks", stats.UnitDimensionless)
|
||||
BlockReceived = stats.Int64("block/received", "Counter for total received blocks", stats.UnitDimensionless)
|
||||
BlockValidationFailure = stats.Int64("block/failure", "Counter for block validation failures", stats.UnitDimensionless)
|
||||
@@ -307,6 +308,10 @@ var (
|
||||
Measure: MpoolPushDuration,
|
||||
Aggregation: defaultMillisecondsDistribution,
|
||||
}
|
||||
MpoolMessageCountView = &view.View{
|
||||
Measure: MpoolMessageCount,
|
||||
Aggregation: view.LastValue(),
|
||||
}
|
||||
PeerCountView = &view.View{
|
||||
Measure: PeerCount,
|
||||
Aggregation: view.LastValue(),
|
||||
@@ -761,6 +766,7 @@ var ChainNodeViews = append([]*view.View{
|
||||
MpoolAddTsDurationView,
|
||||
MpoolAddDurationView,
|
||||
MpoolPushDurationView,
|
||||
MpoolMessageCountView,
|
||||
PubsubPublishMessageView,
|
||||
PubsubDeliverMessageView,
|
||||
PubsubRejectMessageView,
|
||||
|
||||
+1
-1
@@ -325,7 +325,7 @@ minerLoop:
|
||||
"block-time", btime, "time", build.Clock.Now(), "difference", build.Clock.Since(btime))
|
||||
}
|
||||
|
||||
if os.Getenv("LOTUS_MINER_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" {
|
||||
if os.Getenv("LOTUS_MINER_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" && !build.IsNearUpgrade(base.TipSet.Height(), build.UpgradeWatermelonFixHeight) {
|
||||
witness, fault, err := m.sf.MinedBlock(ctx, b.Header, base.TipSet.Height()+base.NullRounds)
|
||||
if err != nil {
|
||||
log.Errorf("<!!> SLASH FILTER ERRORED: %s", err)
|
||||
|
||||
@@ -90,6 +90,7 @@ const (
|
||||
// health checks
|
||||
CheckFDLimit
|
||||
CheckFvmConcurrency
|
||||
CheckUDPBufferSize
|
||||
LegacyMarketsEOL
|
||||
|
||||
// libp2p
|
||||
@@ -169,6 +170,7 @@ func defaults() []Option {
|
||||
|
||||
Override(CheckFDLimit, modules.CheckFdLimit(build.DefaultFDLimit)),
|
||||
Override(CheckFvmConcurrency, modules.CheckFvmConcurrency()),
|
||||
Override(CheckUDPBufferSize, modules.CheckUDPBufferSize(2048*1024)),
|
||||
|
||||
Override(new(system.MemoryConstraints), modules.MemoryConstraints),
|
||||
Override(InitMemoryWatchdog, modules.MemoryWatchdog),
|
||||
|
||||
@@ -69,7 +69,7 @@ func LoadBundles(ctx context.Context, bs blockstore.Blockstore, versions ...acto
|
||||
)
|
||||
if path, ok := build.BundleOverrides[av]; ok {
|
||||
root, err = LoadBundleFromFile(ctx, bs, path)
|
||||
} else if embedded, ok := build.GetEmbeddedBuiltinActorsBundle(av); ok {
|
||||
} else if embedded, ok := build.GetEmbeddedBuiltinActorsBundle(av, build.NetworkBundle); ok {
|
||||
root, err = LoadBundle(ctx, bs, bytes.NewReader(embedded))
|
||||
} else {
|
||||
err = xerrors.Errorf("bundle for actors version v%d not found", av)
|
||||
|
||||
@@ -186,5 +186,17 @@ func (e *EthModuleDummy) EthTraceReplayBlockTransactions(ctx context.Context, bl
|
||||
return nil, ErrModuleDisabled
|
||||
}
|
||||
|
||||
func (e *EthModuleDummy) EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
return nil, ErrModuleDisabled
|
||||
}
|
||||
|
||||
func (e *EthModuleDummy) EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
return nil, ErrModuleDisabled
|
||||
}
|
||||
|
||||
func (e *EthModuleDummy) EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error) {
|
||||
return nil, ErrModuleDisabled
|
||||
}
|
||||
|
||||
var _ EthModuleAPI = &EthModuleDummy{}
|
||||
var _ EthEventAPI = &EthModuleDummy{}
|
||||
|
||||
+27
-9
@@ -73,6 +73,9 @@ type EthModuleAPI interface {
|
||||
Web3ClientVersion(ctx context.Context) (string, error)
|
||||
EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error)
|
||||
EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error)
|
||||
EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error)
|
||||
EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error)
|
||||
}
|
||||
|
||||
type EthEventAPI interface {
|
||||
@@ -397,26 +400,31 @@ func (a *EthModule) EthGetTransactionReceiptLimited(ctx context.Context, txHash
|
||||
}
|
||||
|
||||
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, c, limit, true)
|
||||
if err != nil || msgLookup == nil {
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to lookup Eth Txn %s as %s: %w", txHash, c, err)
|
||||
}
|
||||
if msgLookup == nil {
|
||||
// This is the best we can do. In theory, we could have just not indexed this
|
||||
// transaction, but there's no way to check that here.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.Chain, a.StateAPI)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, xerrors.Errorf("failed to convert %s into an Eth Txn: %w", txHash, err)
|
||||
}
|
||||
|
||||
var events []types.Event
|
||||
if rct := msgLookup.Receipt; rct.EventsRoot != nil {
|
||||
events, err = a.ChainAPI.ChainGetEvents(ctx, *rct.EventsRoot)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, xerrors.Errorf("failed get events for %s", txHash)
|
||||
}
|
||||
}
|
||||
|
||||
receipt, err := newEthTxReceipt(ctx, tx, msgLookup, events, a.Chain, a.StateAPI)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
return nil, xerrors.Errorf("failed to convert %s into an Eth Receipt: %w", txHash, err)
|
||||
}
|
||||
|
||||
return &receipt, nil
|
||||
@@ -728,10 +736,11 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
|
||||
}
|
||||
|
||||
rewards, totalGasUsed := calculateRewardsAndGasUsed(rewardPercentiles, txGasRewards)
|
||||
maxGas := build.BlockGasLimit * int64(len(ts.Blocks()))
|
||||
|
||||
// arrays should be reversed at the end
|
||||
baseFeeArray = append(baseFeeArray, ethtypes.EthBigInt(basefee))
|
||||
gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(build.BlockGasLimit))
|
||||
gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(maxGas))
|
||||
rewardsArray = append(rewardsArray, rewards)
|
||||
oldestBlkHeight = uint64(ts.Height())
|
||||
blocksIncluded++
|
||||
@@ -942,10 +951,7 @@ func (a *EthModule) EthTraceReplayBlockTransactions(ctx context.Context, blkNum
|
||||
return nil, xerrors.Errorf("failed to decode payload: %w", err)
|
||||
}
|
||||
} else {
|
||||
output, err = handleFilecoinMethodOutput(ir.ExecutionTrace.MsgRct.ExitCode, ir.ExecutionTrace.MsgRct.ReturnCodec, ir.ExecutionTrace.MsgRct.Return)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("could not convert output: %w", err)
|
||||
}
|
||||
output = encodeFilecoinReturnAsABI(ir.ExecutionTrace.MsgRct.ExitCode, ir.ExecutionTrace.MsgRct.ReturnCodec, ir.ExecutionTrace.MsgRct.Return)
|
||||
}
|
||||
|
||||
t := ethtypes.EthTraceReplayBlockTransaction{
|
||||
@@ -966,6 +972,18 @@ func (a *EthModule) EthTraceReplayBlockTransactions(ctx context.Context, blkNum
|
||||
return allTraces, nil
|
||||
}
|
||||
|
||||
func (a *EthModule) EthDebugTraceCall(ctx context.Context, args ethtypes.EthTxArgs, blockNrOrHash ethtypes.EthBlockNumberOrHash, config *ethtypes.TraceCallConfig) (interface{}, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (a *EthModule) EthDebugTraceBlockByNumber(ctx context.Context, number string, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (a *EthModule) EthDebugTraceBlockByHash(ctx context.Context, hash ethtypes.EthHash, config *ethtypes.TraceConfig) ([]*ethtypes.TxTraceResult, error) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (res *api.InvocResult, err error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package full
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
@@ -162,3 +163,17 @@ func TestRewardPercentiles(t *testing.T) {
|
||||
require.Equal(t, ans, rewards)
|
||||
}
|
||||
}
|
||||
|
||||
func TestABIEncoding(t *testing.T) {
|
||||
// Generated from https://abi.hashex.org/
|
||||
const expected = "000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000510000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000001b1111111111111111111020200301000000044444444444444444010000000000"
|
||||
const data = "111111111111111111102020030100000004444444444444444401"
|
||||
|
||||
expectedBytes, err := hex.DecodeString(expected)
|
||||
require.NoError(t, err)
|
||||
|
||||
dataBytes, err := hex.DecodeString(data)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, expectedBytes, encodeAsABIHelper(22, 81, dataBytes))
|
||||
}
|
||||
|
||||
+2
-106
@@ -3,18 +3,13 @@ package full
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/multiformats/go-multicodec"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/evm"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -124,14 +119,8 @@ func buildTraces(ctx context.Context, traces *[]*ethtypes.EthTrace, parent *etht
|
||||
} else {
|
||||
// we are going to assume a native method, but we may change it in one of the edge cases below
|
||||
// TODO: only do this if we know it's a native method (optimization)
|
||||
trace.Action.Input, err = handleFilecoinMethodInput(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("buildTraces: %w", err)
|
||||
}
|
||||
trace.Result.Output, err = handleFilecoinMethodOutput(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("buildTraces: %w", err)
|
||||
}
|
||||
trace.Action.Input = encodeFilecoinParamsAsABI(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params)
|
||||
trace.Result.Output = encodeFilecoinReturnAsABI(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return)
|
||||
}
|
||||
|
||||
// TODO: is it OK to check this here or is this only specific to certain edge case (evm to evm)?
|
||||
@@ -258,96 +247,3 @@ func buildTraces(ctx context.Context, traces *[]*ethtypes.EthTrace, parent *etht
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func writePadded(w io.Writer, data any, size int) error {
|
||||
tmp := &bytes.Buffer{}
|
||||
|
||||
// first write data to tmp buffer to get the size
|
||||
err := binary.Write(tmp, binary.BigEndian, data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("writePadded: failed writing tmp data to buffer: %w", err)
|
||||
}
|
||||
|
||||
if tmp.Len() > size {
|
||||
return fmt.Errorf("writePadded: data is larger than size")
|
||||
}
|
||||
|
||||
// write tailing zeros to pad up to size
|
||||
cnt := size - tmp.Len()
|
||||
for i := 0; i < cnt; i++ {
|
||||
err = binary.Write(w, binary.BigEndian, uint8(0))
|
||||
if err != nil {
|
||||
return fmt.Errorf("writePadded: failed writing tailing zeros to buffer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// finally write the actual value
|
||||
err = binary.Write(w, binary.BigEndian, tmp.Bytes())
|
||||
if err != nil {
|
||||
return fmt.Errorf("writePadded: failed writing data to buffer: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleFilecoinMethodInput(method abi.MethodNum, codec uint64, params []byte) ([]byte, error) {
|
||||
NATIVE_METHOD_SELECTOR := []byte{0x86, 0x8e, 0x10, 0xc4}
|
||||
EVM_WORD_SIZE := 32
|
||||
|
||||
staticArgs := []uint64{
|
||||
uint64(method),
|
||||
codec,
|
||||
uint64(EVM_WORD_SIZE) * 3,
|
||||
uint64(len(params)),
|
||||
}
|
||||
totalWords := len(staticArgs) + (len(params) / EVM_WORD_SIZE)
|
||||
if len(params)%EVM_WORD_SIZE != 0 {
|
||||
totalWords++
|
||||
}
|
||||
len := 4 + totalWords*EVM_WORD_SIZE
|
||||
|
||||
w := &bytes.Buffer{}
|
||||
err := binary.Write(w, binary.BigEndian, NATIVE_METHOD_SELECTOR)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodInput: failed writing method selector: %w", err)
|
||||
}
|
||||
|
||||
for _, arg := range staticArgs {
|
||||
err := writePadded(w, arg, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodInput: %w", err)
|
||||
}
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodInput: failed writing params: %w", err)
|
||||
}
|
||||
remain := len - w.Len()
|
||||
for i := 0; i < remain; i++ {
|
||||
err = binary.Write(w, binary.BigEndian, uint8(0))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodInput: failed writing tailing zeros: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
func handleFilecoinMethodOutput(exitCode exitcode.ExitCode, codec uint64, data []byte) ([]byte, error) {
|
||||
w := &bytes.Buffer{}
|
||||
|
||||
values := []interface{}{uint32(exitCode), codec, uint32(w.Len()), uint32(len(data))}
|
||||
for _, v := range values {
|
||||
err := writePadded(w, v, 32)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodOutput: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err := binary.Write(w, binary.BigEndian, data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("handleFilecoinMethodOutput: failed writing data: %w", err)
|
||||
}
|
||||
|
||||
return w.Bytes(), nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package full
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
@@ -627,7 +629,13 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", lookup.TipSet, err)
|
||||
}
|
||||
|
||||
baseFee := ts.Blocks()[0].ParentBaseFee
|
||||
// The tx is located in the parent tipset
|
||||
parentTs, err := cs.LoadTipSet(ctx, ts.Parents())
|
||||
if err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", ts.Parents(), err)
|
||||
}
|
||||
|
||||
baseFee := parentTs.Blocks()[0].ParentBaseFee
|
||||
gasOutputs := vm.ComputeGasOutputs(lookup.Receipt.GasUsed, int64(tx.Gas), baseFee, big.Int(tx.MaxFeePerGas), big.Int(tx.MaxPriorityFeePerGas), true)
|
||||
totalSpent := big.Sum(gasOutputs.BaseFeeBurn, gasOutputs.MinerTip, gasOutputs.OverEstimationBurn)
|
||||
|
||||
@@ -688,3 +696,45 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
|
||||
return receipt, nil
|
||||
}
|
||||
|
||||
func encodeFilecoinParamsAsABI(method abi.MethodNum, codec uint64, params []byte) []byte {
|
||||
buf := []byte{0x86, 0x8e, 0x10, 0xc4} // Native method selector.
|
||||
return append(buf, encodeAsABIHelper(uint64(method), codec, params)...)
|
||||
}
|
||||
|
||||
func encodeFilecoinReturnAsABI(exitCode exitcode.ExitCode, codec uint64, data []byte) []byte {
|
||||
return encodeAsABIHelper(uint64(exitCode), codec, data)
|
||||
}
|
||||
|
||||
// Format 2 numbers followed by an arbitrary byte array as solidity ABI. Both our native
|
||||
// inputs/outputs follow the same pattern, so we can reuse this code.
|
||||
func encodeAsABIHelper(param1 uint64, param2 uint64, data []byte) []byte {
|
||||
const EVM_WORD_SIZE = 32
|
||||
|
||||
// The first two params are "static" numbers. Then, we record the offset of the "data" arg,
|
||||
// then, at that offset, we record the length of the data.
|
||||
//
|
||||
// In practice, this means we have 4 256-bit words back to back where the third arg (the
|
||||
// offset) is _always_ '32*3'.
|
||||
staticArgs := []uint64{param1, param2, EVM_WORD_SIZE * 3, uint64(len(data))}
|
||||
// We always pad out to the next EVM "word" (32 bytes).
|
||||
totalWords := len(staticArgs) + (len(data) / EVM_WORD_SIZE)
|
||||
if len(data)%EVM_WORD_SIZE != 0 {
|
||||
totalWords++
|
||||
}
|
||||
len := totalWords * EVM_WORD_SIZE
|
||||
buf := make([]byte, len)
|
||||
offset := 0
|
||||
// Below, we use copy instead of "appending" to preserve all the zero padding.
|
||||
for _, arg := range staticArgs {
|
||||
// Write each "arg" into the last 8 bytes of each 32 byte word.
|
||||
offset += EVM_WORD_SIZE
|
||||
start := offset - 8
|
||||
binary.BigEndian.PutUint64(buf[start:offset], arg)
|
||||
}
|
||||
|
||||
// Finally, we copy in the data.
|
||||
copy(buf[offset:], data)
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) erro
|
||||
return xerrors.Errorf("loading parent block: %w", err)
|
||||
}
|
||||
|
||||
if a.SlashFilter != nil && os.Getenv("LOTUS_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" {
|
||||
if a.SlashFilter != nil && os.Getenv("LOTUS_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" && !build.IsNearUpgrade(blk.Header.Height, build.UpgradeWatermelonFixHeight) {
|
||||
witness, fault, err := a.SlashFilter.MinedBlock(ctx, blk.Header, parent.Height)
|
||||
if err != nil {
|
||||
log.Errorf("<!!> SLASH FILTER ERRORED: %s", err)
|
||||
|
||||
+2
-12
@@ -336,19 +336,9 @@ func (sm *StorageMinerAPI) SectorsListInStates(ctx context.Context, states []api
|
||||
return sns, nil
|
||||
}
|
||||
|
||||
// Use SectorsSummary from stats (prometheus) for faster result
|
||||
func (sm *StorageMinerAPI) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) {
|
||||
sectors, err := sm.Miner.ListSectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := make(map[api.SectorState]int)
|
||||
for i := range sectors {
|
||||
state := api.SectorState(sectors[i].State)
|
||||
out[state]++
|
||||
}
|
||||
|
||||
return out, nil
|
||||
return sm.Miner.SectorsSummary(ctx), nil
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) StorageLocal(ctx context.Context) (map[storiface.ID]string, error) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
||||
"github.com/filecoin-project/lotus/journal/alerting"
|
||||
"github.com/filecoin-project/lotus/lib/ulimit"
|
||||
@@ -35,6 +37,69 @@ func CheckFdLimit(min uint64) func(al *alerting.Alerting) {
|
||||
}
|
||||
}
|
||||
|
||||
func CheckUDPBufferSize(wanted int) func(al *alerting.Alerting) {
|
||||
return func(al *alerting.Alerting) {
|
||||
conn, err := net.Dial("udp", "localhost:0")
|
||||
if err != nil {
|
||||
alert := al.AddAlertType("process", "udp-buffer-size")
|
||||
al.Raise(alert, map[string]string{
|
||||
"message": "Failed to create UDP connection",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err := conn.Close(); err != nil {
|
||||
log.Warnf("Failed to close connection: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
udpConn, ok := conn.(*net.UDPConn)
|
||||
if !ok {
|
||||
alert := al.AddAlertType("process", "udp-buffer-size")
|
||||
al.Raise(alert, map[string]string{
|
||||
"message": "Failed to cast connection to UDPConn",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
file, err := udpConn.File()
|
||||
if err != nil {
|
||||
alert := al.AddAlertType("process", "udp-buffer-size")
|
||||
al.Raise(alert, map[string]string{
|
||||
"message": "Failed to get file descriptor from UDPConn",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err := file.Close(); err != nil {
|
||||
log.Warnf("Failed to close file: %s", err)
|
||||
}
|
||||
}()
|
||||
|
||||
size, err := syscall.GetsockoptInt(int(file.Fd()), syscall.SOL_SOCKET, syscall.SO_RCVBUF)
|
||||
if err != nil {
|
||||
alert := al.AddAlertType("process", "udp-buffer-size")
|
||||
al.Raise(alert, map[string]string{
|
||||
"message": "Failed to get UDP buffer size",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if size < wanted {
|
||||
alert := al.AddAlertType("process", "udp-buffer-size")
|
||||
al.Raise(alert, map[string]interface{}{
|
||||
"message": "UDP buffer size is low",
|
||||
"current_size": size,
|
||||
"wanted_size": wanted,
|
||||
"help": "See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func LegacyMarketsEOL(al *alerting.Alerting) {
|
||||
// Add alert if lotus-miner legacy markets subsystem is still in use
|
||||
alert := al.AddAlertType("system", "EOL")
|
||||
|
||||
+1
-1
@@ -482,7 +482,7 @@ func (ca *channelAccessor) listVouchers(ctx context.Context, ch address.Address)
|
||||
// the data store over the chain state
|
||||
func (ca *channelAccessor) laneState(ctx context.Context, state lpaych.State, ch address.Address) (map[uint64]lpaych.LaneState, error) {
|
||||
// TODO: we probably want to call UpdateChannelState with all vouchers to be fully correct
|
||||
// (but technically dont't need to)
|
||||
// (but technically don't need to)
|
||||
|
||||
laneCount, err := state.LaneCount()
|
||||
if err != nil {
|
||||
|
||||
@@ -304,6 +304,20 @@ func (m *Sealing) TerminateSector(ctx context.Context, sid abi.SectorNumber) err
|
||||
return m.sectors.Send(uint64(sid), SectorTerminate{})
|
||||
}
|
||||
|
||||
func (m *Sealing) SectorsSummary(ctx context.Context) map[api.SectorState]int {
|
||||
m.stats.lk.Lock()
|
||||
defer m.stats.lk.Unlock()
|
||||
|
||||
out := make(map[api.SectorState]int)
|
||||
|
||||
for st, count := range m.stats.byState {
|
||||
state := api.SectorState(st)
|
||||
out[state] = int(count)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Sealing) TerminateFlush(ctx context.Context) (*cid.Cid, error) {
|
||||
return m.terminator.Flush(ctx)
|
||||
}
|
||||
|
||||
@@ -928,7 +928,7 @@ func (sb *Sealer) SealPreCommit2(ctx context.Context, sector storiface.SectorRef
|
||||
return storiface.SectorCids{}, xerrors.Errorf("generate synth proofs: %w", err)
|
||||
}
|
||||
|
||||
if err = ffi.ClearLayerData(ssize, paths.Cache); err != nil {
|
||||
if err = ffi.ClearCache(uint64(ssize), paths.Cache); err != nil {
|
||||
log.Warn("failed to GenerateSynthProofs(): ", err)
|
||||
log.Warnf("num:%d tkt:%v, sealedCID:%v, unsealedCID:%v", sector.ID.Number, ticket, sealedCID, unsealedCID)
|
||||
return storiface.SectorCids{
|
||||
|
||||
Reference in New Issue
Block a user