From 0f4c6275a7fdbc7a0f98976e8d62121be0569159 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 16 Sep 2024 16:44:42 +0400 Subject: [PATCH 01/61] fix conflicts with chain indexer --- api/api_full.go | 3 + api/mocks/mock_full.go | 15 + api/proxy_gen.go | 13 + build/openrpc/full.json | 543 ++++++++++++-------- build/openrpc/gateway.json | 200 +++---- build/openrpc/miner.json | 176 +++---- build/openrpc/worker.json | 74 +-- chain/index/api.go | 167 ++++++ chain/index/ddls.go | 8 +- chain/index/gc.go | 3 + chain/index/helpers.go | 21 - chain/index/indexer.go | 29 +- chain/index/interface.go | 2 + chain/index/reconcile.go | 10 +- chain/types/index.go | 11 + documentation/en/api-v1-unstable-methods.md | 26 + itests/eth_filter_test.go | 11 + node/builder_chain.go | 3 + node/impl/full.go | 1 + node/impl/full/chain_index.go | 48 ++ node/modules/chainindex.go | 34 +- 21 files changed, 917 insertions(+), 481 deletions(-) create mode 100644 chain/index/api.go create mode 100644 chain/types/index.go create mode 100644 node/impl/full/chain_index.go diff --git a/api/api_full.go b/api/api_full.go index 271aa2dd43b..f786f3b167e 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -63,6 +63,9 @@ type FullNode interface { Common Net + // MethodGroup: ChainIndexer + ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) //perm:read + // MethodGroup: Chain // The Chain method group contains methods for interacting with the // blockchain, but that do not require any form of state computation. diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 7e26fdc03d0..6b315d618df 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -510,6 +510,21 @@ func (mr *MockFullNodeMockRecorder) ChainTipSetWeight(arg0, arg1 interface{}) *g return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainTipSetWeight", reflect.TypeOf((*MockFullNode)(nil).ChainTipSetWeight), arg0, arg1) } +// ChainValidateIndex mocks base method. +func (m *MockFullNode) ChainValidateIndex(arg0 context.Context, arg1 abi.ChainEpoch, arg2 bool) (*types.IndexValidation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainValidateIndex", arg0, arg1, arg2) + ret0, _ := ret[0].(*types.IndexValidation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainValidateIndex indicates an expected call of ChainValidateIndex. +func (mr *MockFullNodeMockRecorder) ChainValidateIndex(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainValidateIndex", reflect.TypeOf((*MockFullNode)(nil).ChainValidateIndex), arg0, arg1, arg2) +} + // Closing mocks base method. func (m *MockFullNode) Closing(arg0 context.Context) (<-chan struct{}, error) { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 744d50e9e77..2c1b585c424 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -169,6 +169,8 @@ type FullNodeMethods struct { ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` + ChainValidateIndex func(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) `perm:"read"` + CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `perm:"read"` @@ -1630,6 +1632,17 @@ func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) return *new(types.BigInt), ErrNotSupported } +func (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) { + if s.Internal.ChainValidateIndex == nil { + return nil, ErrNotSupported + } + return s.Internal.ChainValidateIndex(p0, p1, p2) +} + +func (s *FullNodeStub) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) { + return nil, ErrNotSupported +} + func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { if s.Internal.CreateBackup == nil { return ErrNotSupported diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 862211eb411..8236985c928 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -37,7 +37,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1325" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1327" } }, { @@ -60,7 +60,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1336" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1338" } }, { @@ -103,7 +103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1347" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1349" } }, { @@ -214,7 +214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1369" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1371" } }, { @@ -454,7 +454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1380" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1382" } }, { @@ -685,7 +685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1391" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1393" } }, { @@ -784,7 +784,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1402" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1404" } }, { @@ -816,7 +816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1413" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1415" } }, { @@ -922,7 +922,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1424" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1426" } }, { @@ -1019,7 +1019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1435" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1437" } }, { @@ -1078,7 +1078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1446" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1448" } }, { @@ -1171,7 +1171,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1457" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1459" } }, { @@ -1255,7 +1255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1468" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1470" } }, { @@ -1355,7 +1355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1479" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1481" } }, { @@ -1411,7 +1411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1490" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1492" } }, { @@ -1484,7 +1484,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1501" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1503" } }, { @@ -1557,7 +1557,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1512" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1514" } }, { @@ -1604,7 +1604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1523" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1525" } }, { @@ -1636,7 +1636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1534" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1536" } }, { @@ -1691,7 +1691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1545" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1547" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1567" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1569" } }, { @@ -1780,7 +1780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1578" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1580" } }, { @@ -1827,7 +1827,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1589" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1591" } }, { @@ -1874,7 +1874,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1600" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1602" } }, { @@ -1954,7 +1954,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1611" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1613" } }, { @@ -2006,7 +2006,98 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1622" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1624" + } + }, + { + "name": "Filecoin.ChainValidateIndex", + "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", + "summary": "There are not yet any comments for this method.", + "paramStructure": "by-position", + "params": [ + { + "name": "p1", + "description": "abi.ChainEpoch", + "summary": "", + "schema": { + "title": "number", + "description": "Number is a number", + "examples": [ + 10101 + ], + "type": [ + "number" + ] + }, + "required": true, + "deprecated": false + }, + { + "name": "p2", + "description": "bool", + "summary": "", + "schema": { + "examples": [ + true + ], + "type": [ + "boolean" + ] + }, + "required": true, + "deprecated": false + } + ], + "result": { + "name": "*types.IndexValidation", + "description": "*types.IndexValidation", + "summary": "", + "schema": { + "examples": [ + { + "TipsetKey": "string value", + "Height": 42, + "TotalMessages": 42, + "TotalEvents": 42, + "EventsReverted": true, + "Backfilled": true + } + ], + "additionalProperties": false, + "properties": { + "Backfilled": { + "type": "boolean" + }, + "EventsReverted": { + "type": "boolean" + }, + "Height": { + "title": "number", + "type": "number" + }, + "TipsetKey": { + "type": "string" + }, + "TotalEvents": { + "title": "number", + "type": "number" + }, + "TotalMessages": { + "title": "number", + "type": "number" + } + }, + "type": [ + "object" + ] + }, + "required": true, + "deprecated": false + }, + "deprecated": false, + "externalDocs": { + "description": "Github remote link", + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1635" } }, { @@ -2045,7 +2136,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1633" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1646" } }, { @@ -2092,7 +2183,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1644" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1657" } }, { @@ -2147,7 +2238,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1655" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1668" } }, { @@ -2176,7 +2267,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1666" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1679" } }, { @@ -2313,7 +2404,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1677" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1690" } }, { @@ -2342,7 +2433,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1688" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1701" } }, { @@ -2396,7 +2487,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1699" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1712" } }, { @@ -2487,7 +2578,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1710" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1723" } }, { @@ -2515,7 +2606,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1721" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1734" } }, { @@ -2605,7 +2696,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1732" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1745" } }, { @@ -2861,7 +2952,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1743" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1756" } }, { @@ -3106,7 +3197,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1754" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1767" } }, { @@ -3162,7 +3253,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1765" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1778" } }, { @@ -3209,7 +3300,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1776" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1789" } }, { @@ -3307,7 +3398,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1787" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1800" } }, { @@ -3373,7 +3464,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1798" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1811" } }, { @@ -3439,7 +3530,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1809" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1822" } }, { @@ -3548,7 +3639,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1820" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1833" } }, { @@ -3606,7 +3697,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1831" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1844" } }, { @@ -3728,7 +3819,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1842" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1855" } }, { @@ -3937,7 +4028,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1853" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1866" } }, { @@ -4137,7 +4228,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1864" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1877" } }, { @@ -4329,7 +4420,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1875" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1888" } }, { @@ -4538,7 +4629,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1886" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1899" } }, { @@ -4629,7 +4720,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1897" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1910" } }, { @@ -4687,7 +4778,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1908" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1921" } }, { @@ -4945,7 +5036,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1919" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1932" } }, { @@ -5220,7 +5311,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1930" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1943" } }, { @@ -5248,7 +5339,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1941" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1954" } }, { @@ -5286,7 +5377,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1952" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1965" } }, { @@ -5394,7 +5485,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1963" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1976" } }, { @@ -5432,7 +5523,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1974" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1987" } }, { @@ -5461,7 +5552,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1985" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1998" } }, { @@ -5524,7 +5615,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1996" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2009" } }, { @@ -5587,7 +5678,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2007" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2020" } }, { @@ -5650,7 +5741,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2018" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2031" } }, { @@ -5695,7 +5786,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2029" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2042" } }, { @@ -5817,7 +5908,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2040" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2053" } }, { @@ -5993,7 +6084,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2051" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2064" } }, { @@ -6148,7 +6239,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2062" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2075" } }, { @@ -6270,7 +6361,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2073" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2086" } }, { @@ -6324,7 +6415,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2084" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2097" } }, { @@ -6378,7 +6469,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2095" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2108" } }, { @@ -6567,7 +6658,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2106" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2119" } }, { @@ -6650,7 +6741,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2117" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2130" } }, { @@ -6733,7 +6824,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2128" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2141" } }, { @@ -6904,7 +6995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2139" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2152" } }, { @@ -6980,7 +7071,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2150" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2163" } }, { @@ -7043,7 +7134,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2161" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2174" } }, { @@ -7186,7 +7277,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2172" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2185" } }, { @@ -7313,7 +7404,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2183" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2196" } }, { @@ -7415,7 +7506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2194" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2207" } }, { @@ -7638,7 +7729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2205" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2218" } }, { @@ -7821,7 +7912,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2216" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2229" } }, { @@ -7901,7 +7992,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2227" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2240" } }, { @@ -7946,7 +8037,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2238" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2251" } }, { @@ -8002,7 +8093,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2249" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2262" } }, { @@ -8082,7 +8173,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2260" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2273" } }, { @@ -8162,7 +8253,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2271" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2284" } }, { @@ -8647,7 +8738,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2282" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2295" } }, { @@ -8841,7 +8932,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2293" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2306" } }, { @@ -8996,7 +9087,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2304" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2317" } }, { @@ -9245,7 +9336,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2315" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2328" } }, { @@ -9400,7 +9491,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2326" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2339" } }, { @@ -9577,7 +9668,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2337" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2350" } }, { @@ -9675,7 +9766,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2348" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2361" } }, { @@ -9840,7 +9931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2359" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2372" } }, { @@ -9879,7 +9970,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2370" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2383" } }, { @@ -9944,7 +10035,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2381" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2394" } }, { @@ -9990,7 +10081,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2392" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2405" } }, { @@ -10140,7 +10231,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2403" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2416" } }, { @@ -10277,7 +10368,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2414" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2427" } }, { @@ -10508,7 +10599,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2425" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2438" } }, { @@ -10645,7 +10736,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2436" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2449" } }, { @@ -10810,7 +10901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2447" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2460" } }, { @@ -10887,7 +10978,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2458" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2471" } }, { @@ -11082,7 +11173,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2480" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2493" } }, { @@ -11261,7 +11352,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2491" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2504" } }, { @@ -11423,7 +11514,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2502" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2515" } }, { @@ -11571,7 +11662,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2513" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2526" } }, { @@ -11799,7 +11890,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2524" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2537" } }, { @@ -11947,7 +12038,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2535" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2548" } }, { @@ -12159,7 +12250,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2546" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2559" } }, { @@ -12365,7 +12456,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2557" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2570" } }, { @@ -12433,7 +12524,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2568" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2581" } }, { @@ -12550,7 +12641,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2579" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2592" } }, { @@ -12641,7 +12732,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2590" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2603" } }, { @@ -12727,7 +12818,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2601" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2614" } }, { @@ -12922,7 +13013,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2612" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2625" } }, { @@ -13084,7 +13175,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2623" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2636" } }, { @@ -13280,7 +13371,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2634" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2647" } }, { @@ -13460,7 +13551,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2645" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2658" } }, { @@ -13623,7 +13714,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2656" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2669" } }, { @@ -13650,7 +13741,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2667" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2680" } }, { @@ -13677,7 +13768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2678" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2691" } }, { @@ -13776,7 +13867,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2689" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2702" } }, { @@ -13822,7 +13913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2700" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2713" } }, { @@ -13922,7 +14013,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2711" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2724" } }, { @@ -14038,7 +14129,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2722" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2735" } }, { @@ -14086,7 +14177,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2733" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2746" } }, { @@ -14178,7 +14269,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2744" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2757" } }, { @@ -14293,7 +14384,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2755" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2768" } }, { @@ -14341,7 +14432,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2766" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2779" } }, { @@ -14378,7 +14469,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2777" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2790" } }, { @@ -14650,7 +14741,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2788" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2801" } }, { @@ -14698,7 +14789,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2799" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2812" } }, { @@ -14756,7 +14847,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2810" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2823" } }, { @@ -14961,7 +15052,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2821" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2834" } }, { @@ -15164,7 +15255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2832" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2845" } }, { @@ -15333,7 +15424,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2843" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2856" } }, { @@ -15537,7 +15628,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2854" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2867" } }, { @@ -15704,7 +15795,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2865" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2878" } }, { @@ -15911,7 +16002,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2876" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2889" } }, { @@ -15979,7 +16070,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2887" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2900" } }, { @@ -16031,7 +16122,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2898" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2911" } }, { @@ -16080,7 +16171,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2909" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2922" } }, { @@ -16171,7 +16262,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2920" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2933" } }, { @@ -16677,7 +16768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2931" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2944" } }, { @@ -16783,7 +16874,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2942" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2955" } }, { @@ -16835,7 +16926,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2953" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2966" } }, { @@ -17387,7 +17478,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2964" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2977" } }, { @@ -17501,7 +17592,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2975" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2988" } }, { @@ -17598,7 +17689,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2986" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2999" } }, { @@ -17698,7 +17789,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2997" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3010" } }, { @@ -17786,7 +17877,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3008" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3021" } }, { @@ -17886,7 +17977,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3019" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3032" } }, { @@ -17973,7 +18064,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3030" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3043" } }, { @@ -18064,7 +18155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3041" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3054" } }, { @@ -18189,7 +18280,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3052" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3065" } }, { @@ -18298,7 +18389,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3063" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3076" } }, { @@ -18368,7 +18459,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3074" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3087" } }, { @@ -18471,7 +18562,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3085" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3098" } }, { @@ -18532,7 +18623,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3096" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3109" } }, { @@ -18662,7 +18753,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3107" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3120" } }, { @@ -18769,7 +18860,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3118" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3131" } }, { @@ -18983,7 +19074,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3129" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3142" } }, { @@ -19060,7 +19151,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3140" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3153" } }, { @@ -19137,7 +19228,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3151" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3164" } }, { @@ -19246,7 +19337,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3162" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3175" } }, { @@ -19355,7 +19446,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3173" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3186" } }, { @@ -19416,7 +19507,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3184" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3197" } }, { @@ -19526,7 +19617,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3195" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3208" } }, { @@ -19587,7 +19678,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3206" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3219" } }, { @@ -19655,7 +19746,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3217" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3230" } }, { @@ -19723,7 +19814,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3228" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3241" } }, { @@ -19804,7 +19895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3239" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3252" } }, { @@ -19958,7 +20049,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3250" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3263" } }, { @@ -20030,7 +20121,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3261" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3274" } }, { @@ -20194,7 +20285,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3272" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3285" } }, { @@ -20359,7 +20450,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3283" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3296" } }, { @@ -20429,7 +20520,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3294" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3307" } }, { @@ -20497,7 +20588,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3305" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3318" } }, { @@ -20590,7 +20681,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3316" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3329" } }, { @@ -20661,7 +20752,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3327" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3340" } }, { @@ -20862,7 +20953,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3338" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3351" } }, { @@ -20994,7 +21085,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3349" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3362" } }, { @@ -21131,7 +21222,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3360" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3373" } }, { @@ -21242,7 +21333,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3371" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3384" } }, { @@ -21374,7 +21465,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3382" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3395" } }, { @@ -21505,7 +21596,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3393" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3406" } }, { @@ -21576,7 +21667,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3404" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3417" } }, { @@ -21660,7 +21751,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3415" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3428" } }, { @@ -21746,7 +21837,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3426" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3439" } }, { @@ -21929,7 +22020,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3437" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3450" } }, { @@ -21956,7 +22047,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3448" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3461" } }, { @@ -22009,7 +22100,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3459" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3472" } }, { @@ -22097,7 +22188,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3470" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3483" } }, { @@ -22548,7 +22639,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3481" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3494" } }, { @@ -22715,7 +22806,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3492" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3505" } }, { @@ -22813,7 +22904,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3503" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3516" } }, { @@ -22986,7 +23077,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3514" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3527" } }, { @@ -23084,7 +23175,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3525" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3538" } }, { @@ -23235,7 +23326,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3536" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3549" } }, { @@ -23320,7 +23411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3547" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3560" } }, { @@ -23388,7 +23479,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3558" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3571" } }, { @@ -23440,7 +23531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3569" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3582" } }, { @@ -23508,7 +23599,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3580" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3593" } }, { @@ -23669,7 +23760,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3591" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3604" } }, { @@ -23716,7 +23807,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3613" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3626" } }, { @@ -23763,7 +23854,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3624" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3637" } }, { @@ -23806,7 +23897,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3646" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3659" } }, { @@ -23902,7 +23993,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3657" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3670" } }, { @@ -24168,7 +24259,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3668" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3681" } }, { @@ -24191,7 +24282,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3679" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3692" } }, { @@ -24234,7 +24325,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3690" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3703" } }, { @@ -24285,7 +24376,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3701" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3714" } }, { @@ -24330,7 +24421,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3712" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3725" } }, { @@ -24358,7 +24449,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3723" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3736" } }, { @@ -24398,7 +24489,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3734" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3747" } }, { @@ -24457,7 +24548,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3745" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3758" } }, { @@ -24501,7 +24592,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3756" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3769" } }, { @@ -24560,7 +24651,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3767" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3780" } }, { @@ -24597,7 +24688,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3778" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3791" } }, { @@ -24641,7 +24732,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3789" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3802" } }, { @@ -24681,7 +24772,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3800" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3813" } }, { @@ -24756,7 +24847,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3811" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3824" } }, { @@ -24964,7 +25055,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3822" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3835" } }, { @@ -25008,7 +25099,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3833" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3846" } }, { @@ -25098,7 +25189,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3844" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3857" } }, { @@ -25125,7 +25216,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3855" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3868" } } ] diff --git a/build/openrpc/gateway.json b/build/openrpc/gateway.json index f173a6125f0..c34175cd2d3 100644 --- a/build/openrpc/gateway.json +++ b/build/openrpc/gateway.json @@ -242,7 +242,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3866" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3879" } }, { @@ -473,7 +473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3877" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3890" } }, { @@ -572,7 +572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3888" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3901" } }, { @@ -604,7 +604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3899" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3912" } }, { @@ -710,7 +710,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3910" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3923" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3921" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3934" } }, { @@ -887,7 +887,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3932" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3945" } }, { @@ -987,7 +987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3943" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3956" } }, { @@ -1043,7 +1043,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3954" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3967" } }, { @@ -1116,7 +1116,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3965" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3978" } }, { @@ -1189,7 +1189,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3976" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3989" } }, { @@ -1236,7 +1236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3987" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4000" } }, { @@ -1268,7 +1268,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3998" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4011" } }, { @@ -1305,7 +1305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4020" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4033" } }, { @@ -1352,7 +1352,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4031" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4044" } }, { @@ -1392,7 +1392,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4042" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4055" } }, { @@ -1439,7 +1439,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4053" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4066" } }, { @@ -1494,7 +1494,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4064" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4077" } }, { @@ -1523,7 +1523,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4075" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4088" } }, { @@ -1660,7 +1660,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4086" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4099" } }, { @@ -1689,7 +1689,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4097" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4110" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4108" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4121" } }, { @@ -1834,7 +1834,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4119" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4132" } }, { @@ -1862,7 +1862,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4130" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4143" } }, { @@ -1952,7 +1952,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4141" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4154" } }, { @@ -2208,7 +2208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4152" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4165" } }, { @@ -2453,7 +2453,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4163" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4176" } }, { @@ -2509,7 +2509,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4174" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4187" } }, { @@ -2556,7 +2556,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4185" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4198" } }, { @@ -2654,7 +2654,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4196" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4209" } }, { @@ -2720,7 +2720,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4207" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4220" } }, { @@ -2786,7 +2786,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4218" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4231" } }, { @@ -2895,7 +2895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4229" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4242" } }, { @@ -2953,7 +2953,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4240" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4253" } }, { @@ -3075,7 +3075,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4251" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4264" } }, { @@ -3267,7 +3267,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4262" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4275" } }, { @@ -3476,7 +3476,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4273" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4286" } }, { @@ -3567,7 +3567,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4284" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4297" } }, { @@ -3625,7 +3625,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4295" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4308" } }, { @@ -3883,7 +3883,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4306" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4319" } }, { @@ -4158,7 +4158,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4317" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4330" } }, { @@ -4186,7 +4186,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4328" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4341" } }, { @@ -4224,7 +4224,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4339" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4352" } }, { @@ -4332,7 +4332,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4350" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4363" } }, { @@ -4370,7 +4370,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4361" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4374" } }, { @@ -4399,7 +4399,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4372" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4385" } }, { @@ -4462,7 +4462,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4383" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4396" } }, { @@ -4525,7 +4525,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4394" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4407" } }, { @@ -4570,7 +4570,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4405" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4418" } }, { @@ -4692,7 +4692,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4416" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4429" } }, { @@ -4868,7 +4868,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4427" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4440" } }, { @@ -5023,7 +5023,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4438" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4451" } }, { @@ -5145,7 +5145,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4449" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4462" } }, { @@ -5199,7 +5199,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4460" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4473" } }, { @@ -5253,7 +5253,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4471" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4484" } }, { @@ -5316,7 +5316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4482" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4495" } }, { @@ -5418,7 +5418,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4493" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4506" } }, { @@ -5641,7 +5641,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4504" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4517" } }, { @@ -5824,7 +5824,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4515" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4528" } }, { @@ -6018,7 +6018,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4526" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4539" } }, { @@ -6064,7 +6064,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4537" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4550" } }, { @@ -6214,7 +6214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4548" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4561" } }, { @@ -6351,7 +6351,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4559" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4572" } }, { @@ -6419,7 +6419,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4570" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4583" } }, { @@ -6536,7 +6536,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4581" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4594" } }, { @@ -6627,7 +6627,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4592" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4605" } }, { @@ -6713,7 +6713,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4603" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4616" } }, { @@ -6740,7 +6740,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4614" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4627" } }, { @@ -6767,7 +6767,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4625" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4638" } }, { @@ -6835,7 +6835,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4636" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4649" } }, { @@ -7341,7 +7341,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4647" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4660" } }, { @@ -7438,7 +7438,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4658" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4671" } }, { @@ -7538,7 +7538,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4669" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4682" } }, { @@ -7638,7 +7638,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4680" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4693" } }, { @@ -7763,7 +7763,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4691" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4704" } }, { @@ -7872,7 +7872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4702" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4715" } }, { @@ -7975,7 +7975,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4713" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4726" } }, { @@ -8105,7 +8105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4724" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4737" } }, { @@ -8212,7 +8212,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4735" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4748" } }, { @@ -8273,7 +8273,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4746" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4759" } }, { @@ -8341,7 +8341,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4757" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4770" } }, { @@ -8422,7 +8422,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4768" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4781" } }, { @@ -8586,7 +8586,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4779" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4792" } }, { @@ -8679,7 +8679,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4790" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4803" } }, { @@ -8880,7 +8880,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4801" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4814" } }, { @@ -8991,7 +8991,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4812" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4825" } }, { @@ -9122,7 +9122,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4823" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4836" } }, { @@ -9208,7 +9208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4834" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4847" } }, { @@ -9235,7 +9235,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4845" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4858" } }, { @@ -9288,7 +9288,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4856" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4869" } }, { @@ -9376,7 +9376,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4867" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4880" } }, { @@ -9827,7 +9827,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4878" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4891" } }, { @@ -9994,7 +9994,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4889" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4902" } }, { @@ -10167,7 +10167,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4900" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4913" } }, { @@ -10235,7 +10235,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4911" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4924" } }, { @@ -10303,7 +10303,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4922" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4935" } }, { @@ -10464,7 +10464,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4933" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4946" } }, { @@ -10509,7 +10509,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4955" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4968" } }, { @@ -10554,7 +10554,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4966" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4979" } }, { @@ -10581,7 +10581,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4977" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4990" } } ] diff --git a/build/openrpc/miner.json b/build/openrpc/miner.json index b8c37f2293d..1dc9213b549 100644 --- a/build/openrpc/miner.json +++ b/build/openrpc/miner.json @@ -30,7 +30,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5263" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5276" } }, { @@ -109,7 +109,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5274" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5287" } }, { @@ -155,7 +155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5285" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5298" } }, { @@ -203,7 +203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5296" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5309" } }, { @@ -251,7 +251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5307" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5320" } }, { @@ -354,7 +354,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5318" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5331" } }, { @@ -428,7 +428,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5329" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5342" } }, { @@ -591,7 +591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5340" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5353" } }, { @@ -742,7 +742,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5351" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5364" } }, { @@ -781,7 +781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5362" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5375" } }, { @@ -913,7 +913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5373" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5386" } }, { @@ -945,7 +945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5384" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5397" } }, { @@ -986,7 +986,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5395" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5408" } }, { @@ -1054,7 +1054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5406" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5419" } }, { @@ -1185,7 +1185,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5417" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5430" } }, { @@ -1316,7 +1316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5428" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5441" } }, { @@ -1416,7 +1416,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5439" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5452" } }, { @@ -1516,7 +1516,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5450" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5463" } }, { @@ -1616,7 +1616,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5461" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5474" } }, { @@ -1716,7 +1716,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5472" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5485" } }, { @@ -1816,7 +1816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5483" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5496" } }, { @@ -1916,7 +1916,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5494" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5507" } }, { @@ -2040,7 +2040,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5505" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5518" } }, { @@ -2164,7 +2164,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5516" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5529" } }, { @@ -2279,7 +2279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5527" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5540" } }, { @@ -2379,7 +2379,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5538" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5551" } }, { @@ -2512,7 +2512,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5549" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5562" } }, { @@ -2636,7 +2636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5560" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5573" } }, { @@ -2760,7 +2760,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5571" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5584" } }, { @@ -2884,7 +2884,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5582" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5595" } }, { @@ -3017,7 +3017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5593" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5606" } }, { @@ -3117,7 +3117,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5604" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5617" } }, { @@ -3157,7 +3157,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5615" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5628" } }, { @@ -3229,7 +3229,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5626" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5639" } }, { @@ -3279,7 +3279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5637" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5650" } }, { @@ -3323,7 +3323,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5648" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5661" } }, { @@ -3364,7 +3364,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5659" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5672" } }, { @@ -3608,7 +3608,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5670" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5683" } }, { @@ -3682,7 +3682,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5681" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5694" } }, { @@ -3732,7 +3732,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5692" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5705" } }, { @@ -3761,7 +3761,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5703" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5716" } }, { @@ -3790,7 +3790,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5714" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5727" } }, { @@ -3846,7 +3846,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5725" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5738" } }, { @@ -3869,7 +3869,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5736" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5749" } }, { @@ -3929,7 +3929,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5747" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5760" } }, { @@ -3968,7 +3968,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5758" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5771" } }, { @@ -4008,7 +4008,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5769" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5782" } }, { @@ -4081,7 +4081,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5780" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5793" } }, { @@ -4145,7 +4145,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5791" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5804" } }, { @@ -4208,7 +4208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5802" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5815" } }, { @@ -4258,7 +4258,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5813" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5826" } }, { @@ -4817,7 +4817,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5824" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5837" } }, { @@ -4858,7 +4858,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5835" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5848" } }, { @@ -4899,7 +4899,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5846" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5859" } }, { @@ -4940,7 +4940,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5857" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5870" } }, { @@ -4981,7 +4981,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5868" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5881" } }, { @@ -5022,7 +5022,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5879" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5892" } }, { @@ -5053,7 +5053,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5890" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5903" } }, { @@ -5103,7 +5103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5901" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5914" } }, { @@ -5144,7 +5144,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5912" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5925" } }, { @@ -5183,7 +5183,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5923" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5936" } }, { @@ -5247,7 +5247,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5934" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5947" } }, { @@ -5305,7 +5305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5945" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5958" } }, { @@ -5752,7 +5752,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5956" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5969" } }, { @@ -5788,7 +5788,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5967" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5980" } }, { @@ -5931,7 +5931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5978" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5991" } }, { @@ -5987,7 +5987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5989" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6002" } }, { @@ -6026,7 +6026,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6000" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6013" } }, { @@ -6203,7 +6203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6011" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6024" } }, { @@ -6255,7 +6255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6022" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6035" } }, { @@ -6447,7 +6447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6033" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6046" } }, { @@ -6547,7 +6547,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6044" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6057" } }, { @@ -6601,7 +6601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6055" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6068" } }, { @@ -6640,7 +6640,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6066" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6079" } }, { @@ -6725,7 +6725,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6077" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6090" } }, { @@ -6919,7 +6919,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6088" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6101" } }, { @@ -7017,7 +7017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6099" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6112" } }, { @@ -7149,7 +7149,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6110" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6123" } }, { @@ -7203,7 +7203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6121" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6134" } }, { @@ -7237,7 +7237,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6132" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6145" } }, { @@ -7324,7 +7324,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6143" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6156" } }, { @@ -7378,7 +7378,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6154" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6167" } }, { @@ -7478,7 +7478,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6165" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6178" } }, { @@ -7555,7 +7555,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6176" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6189" } }, { @@ -7646,7 +7646,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6187" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6200" } }, { @@ -7685,7 +7685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6198" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6211" } }, { @@ -7801,7 +7801,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6209" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6222" } }, { @@ -9901,7 +9901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6220" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6233" } } ] diff --git a/build/openrpc/worker.json b/build/openrpc/worker.json index a4da54792ec..8871b9306da 100644 --- a/build/openrpc/worker.json +++ b/build/openrpc/worker.json @@ -161,7 +161,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6308" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6321" } }, { @@ -252,7 +252,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6319" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6332" } }, { @@ -420,7 +420,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6330" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6343" } }, { @@ -447,7 +447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6341" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6354" } }, { @@ -597,7 +597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6352" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6365" } }, { @@ -700,7 +700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6363" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6376" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6374" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6387" } }, { @@ -925,7 +925,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6385" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6398" } }, { @@ -1135,7 +1135,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6396" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6409" } }, { @@ -1306,7 +1306,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6407" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6420" } }, { @@ -3350,7 +3350,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6418" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6431" } }, { @@ -3470,7 +3470,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6429" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6442" } }, { @@ -3531,7 +3531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6440" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6453" } }, { @@ -3569,7 +3569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6451" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6464" } }, { @@ -3729,7 +3729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6462" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6475" } }, { @@ -3913,7 +3913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6473" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6486" } }, { @@ -4054,7 +4054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6484" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6497" } }, { @@ -4107,7 +4107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6495" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6508" } }, { @@ -4250,7 +4250,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6506" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6519" } }, { @@ -4474,7 +4474,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6517" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6530" } }, { @@ -4601,7 +4601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6528" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6541" } }, { @@ -4768,7 +4768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6539" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6552" } }, { @@ -4895,7 +4895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6550" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6563" } }, { @@ -4933,7 +4933,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6561" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6574" } }, { @@ -4972,7 +4972,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6572" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6585" } }, { @@ -4995,7 +4995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6583" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6596" } }, { @@ -5034,7 +5034,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6594" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6607" } }, { @@ -5057,7 +5057,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6605" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6618" } }, { @@ -5096,7 +5096,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6616" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6629" } }, { @@ -5130,7 +5130,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6627" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6640" } }, { @@ -5184,7 +5184,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6638" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6651" } }, { @@ -5223,7 +5223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6649" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6662" } }, { @@ -5262,7 +5262,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6660" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6673" } }, { @@ -5297,7 +5297,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6671" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6684" } }, { @@ -5477,7 +5477,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6682" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6695" } }, { @@ -5506,7 +5506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6693" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6706" } }, { @@ -5529,7 +5529,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6704" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6717" } } ] diff --git a/chain/index/api.go b/chain/index/api.go new file mode 100644 index 00000000000..3674aa3046f --- /dev/null +++ b/chain/index/api.go @@ -0,0 +1,167 @@ +package index + +import ( + "context" + "database/sql" + + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/chain/types" +) + +func (si *SqliteIndexer) sanityCheckBackfillEpoch(ctx context.Context, epoch abi.ChainEpoch) error { + // should be less than the max non reverted height in the Index + var maxNonRevertedHeight sql.NullInt64 + err := si.stmts.getMaxNonRevertedHeightStmt.QueryRowContext(ctx).Scan(&maxNonRevertedHeight) + if err != nil { + return xerrors.Errorf("failed to get max non reverted height: %w", err) + } + if !maxNonRevertedHeight.Valid { + return nil + } + if epoch >= abi.ChainEpoch(maxNonRevertedHeight.Int64) { + return xerrors.Errorf("failed to validate index at epoch %d; can only validate at or before epoch %d for safety", epoch, maxNonRevertedHeight.Int64-1) + } + + return nil +} + +func (si *SqliteIndexer) validateNullRound(ctx context.Context, epoch abi.ChainEpoch) (*types.IndexValidation, error) { + // make sure we do not have ANY non-reverted tipset at this epoch + var isNullRound bool + err := si.stmts.hasNullRoundAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&isNullRound) + if err != nil { + return nil, xerrors.Errorf("failed to check if null round exists at height %d: %w", epoch, err) + } + if !isNullRound { + return nil, xerrors.Errorf("index corruption: height %d should be a null round but is not", epoch) + } + + return nil, nil +} + +func (si *SqliteIndexer) getTipsetCountsAtHeight(ctx context.Context, height abi.ChainEpoch) (revertedCount, nonRevertedCount int, err error) { + err = si.stmts.countTipsetsAtHeightStmt.QueryRowContext(ctx, height).Scan(&revertedCount, &nonRevertedCount) + if err != nil { + if err == sql.ErrNoRows { + // No tipsets found at this height + return 0, 0, nil + } + return 0, 0, xerrors.Errorf("failed to query tipset counts: %w", err) + } + + return revertedCount, nonRevertedCount, nil +} + +func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) { + if !si.started { + return nil, xerrors.Errorf("ChainValidateIndex can only be called after the indexer has been started") + } + si.writerLk.Lock() + defer si.writerLk.Unlock() + + if err := si.sanityCheckBackfillEpoch(ctx, epoch); err != nil { + return nil, err + } + + var isIndexEmpty bool + err := si.stmts.isIndexEmptyStmt.QueryRowContext(ctx).Scan(&isIndexEmpty) + if err != nil { + return nil, xerrors.Errorf("failed to check if index is empty: %w", err) + } + + // fetch the tipset at the given epoch on the canonical chain + expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, nil, true) + if err != nil { + return nil, xerrors.Errorf("failed to get tipset by height: %w", err) + } + expectedTsKeyCid, err := expectedTs.Key().Cid() + if err != nil { + return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) + } + + // Canonical chain has a null round at the epoch -> return if index is empty otherwise validate + if expectedTs.Height() != epoch { // Canonical chain has a null round at the epoch + if isIndexEmpty { + return nil, nil + } + return si.validateNullRound(ctx, epoch) + } + + // if the index is empty -> short-circuit and simply backfill if applicable + if isIndexEmpty { + return si.backfillMissingTipset(ctx, expectedTs, backfill) + } + + revertedCount, nonRevertedCount, err := si.getTipsetCountsAtHeight(ctx, epoch) + if err != nil { + if err == sql.ErrNoRows { + return si.backfillMissingTipset(ctx, expectedTs, backfill) + } + return nil, xerrors.Errorf("failed to get tipset counts at height: %w", err) + } + if revertedCount == 0 && nonRevertedCount == 0 { + return si.backfillMissingTipset(ctx, expectedTs, backfill) + } + + if revertedCount > 0 && nonRevertedCount == 0 { + return nil, xerrors.Errorf("index corruption: height %d only has reverted tipsets", epoch) + } + + if nonRevertedCount > 1 { + return nil, xerrors.Errorf("index corruption: height %d has multiple non-reverted tipsets", epoch) + } + + // fetch the non-reverted tipset at this epoch + var indexedTsKeyCidBytes []byte + err = si.stmts.getNonRevertedTipsetAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&indexedTsKeyCidBytes) + if err != nil { + return nil, xerrors.Errorf("failed to get non-reverted tipset at height: %w", err) + } + indexedTsKeyCid, err := cid.Cast(indexedTsKeyCidBytes) + if err != nil { + return nil, xerrors.Errorf("failed to cast tipset key cid: %w", err) + } + + if indexedTsKeyCid != expectedTsKeyCid { + return nil, xerrors.Errorf("index corruption: non-reverted tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) + } + + return &types.IndexValidation{ + TipsetKey: expectedTs.Key().String(), + Height: uint64(expectedTs.Height()), + // TODO Other fields + }, nil +} + +func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.TipSet, backfill bool) (*types.IndexValidation, error) { + if !backfill { + return nil, xerrors.Errorf("missing tipset at height %d in the chain index, set backfill to true to backfill", ts.Height()) + } + // backfill the tipset in the Index + parentTs, err := si.cs.GetTipSetFromKey(ctx, ts.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to get parent tipset: %w", err) + } + + err = withTx(ctx, si.db, func(tx *sql.Tx) error { + if err := si.indexTipsetWithParentEvents(ctx, tx, parentTs, ts); err != nil { + return xerrors.Errorf("error indexing tipset: %w", err) + } + + return nil + }) + + if err != nil { + return nil, xerrors.Errorf("error applying tipset: %w", err) + } + + return &types.IndexValidation{ + TipsetKey: ts.Key().String(), + Height: uint64(ts.Height()), + Backfilled: true, + }, nil +} diff --git a/chain/index/ddls.go b/chain/index/ddls.go index c7002fde6b5..8a1927430e0 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -70,13 +70,17 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.removeEthHashesOlderThanStmt: "DELETE FROM eth_tx_hash WHERE inserted_at < datetime('now', ?)", &ps.updateTipsetsToRevertedFromHeightStmt: "UPDATE tipset_message SET reverted = 1 WHERE height >= ?", &ps.updateEventsToRevertedFromHeightStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE height >= ?)", - &ps.isTipsetMessageNonEmptyStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message LIMIT 1)", + &ps.isIndexEmptyStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message LIMIT 1)", &ps.getMinNonRevertedHeightStmt: "SELECT MIN(height) FROM tipset_message WHERE reverted = 0", &ps.hasNonRevertedTipsetStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", &ps.updateEventsToRevertedStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", &ps.updateEventsToNonRevertedStmt: "UPDATE event SET reverted = 0 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", &ps.getMsgIdForMsgCidAndTipsetStmt: "SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND message_cid = ? AND reverted = 0", - &ps.insertEventStmt: "INSERT INTO event (message_id, event_index, emitter_addr, reverted) VALUES (?, ?, ?, ?)", + &ps.insertEventStmt: "INSERT INTO event (message_id, event_index, emitter_addr, reverted) VALUES (?, ?, ?, ?) ON CONFLICT (message_id, event_index) DO UPDATE SET reverted = 0", &ps.insertEventEntryStmt: "INSERT INTO event_entry (event_id, indexed, flags, key, codec, value) VALUES (?, ?, ?, ?, ?, ?)", + &ps.getMaxNonRevertedHeightStmt: "SELECT MAX(height) FROM tipset_message WHERE reverted = 0", + &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", + &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0", + &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", } } diff --git a/chain/index/gc.go b/chain/index/gc.go index 168b59507e9..e30d4700aaf 100644 --- a/chain/index/gc.go +++ b/chain/index/gc.go @@ -42,6 +42,9 @@ func (si *SqliteIndexer) gcLoop() { } func (si *SqliteIndexer) gc(ctx context.Context) { + si.writerLk.Lock() + defer si.writerLk.Unlock() + if si.gcRetentionEpochs <= 0 { log.Info("gc retention epochs is not set, skipping gc") return diff --git a/chain/index/helpers.go b/chain/index/helpers.go index 682020e3d82..6c5294a5ba7 100644 --- a/chain/index/helpers.go +++ b/chain/index/helpers.go @@ -8,7 +8,6 @@ import ( ipld "github.com/ipfs/go-ipld-format" "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" ) @@ -80,26 +79,6 @@ func PopulateFromSnapshot(ctx context.Context, path string, cs ChainStore) error return nil } -func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, indexer Indexer) { - for ctx.Err() == nil { - select { - case <-ctx.Done(): - return - case u := <-ch: - if u.Type != api.MpoolAdd { - continue - } - if u.Message == nil { - continue - } - err := indexer.IndexSignedMessage(ctx, u.Message) - if err != nil { - log.Errorw("failed to index signed Mpool message", "error", err) - } - } - } -} - func toTipsetKeyCidBytes(ts *types.TipSet) ([]byte, error) { tsKeyCid, err := ts.Key().Cid() if err != nil { diff --git a/chain/index/indexer.go b/chain/index/indexer.go index d341cd19757..18dc71a0192 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -35,7 +35,7 @@ type preparedStatements struct { removeEthHashesOlderThanStmt *sql.Stmt updateTipsetsToRevertedFromHeightStmt *sql.Stmt updateEventsToRevertedFromHeightStmt *sql.Stmt - isTipsetMessageNonEmptyStmt *sql.Stmt + isIndexEmptyStmt *sql.Stmt getMinNonRevertedHeightStmt *sql.Stmt hasNonRevertedTipsetStmt *sql.Stmt updateEventsToRevertedStmt *sql.Stmt @@ -43,6 +43,11 @@ type preparedStatements struct { getMsgIdForMsgCidAndTipsetStmt *sql.Stmt insertEventStmt *sql.Stmt insertEventEntryStmt *sql.Stmt + + getMaxNonRevertedHeightStmt *sql.Stmt + hasNullRoundAtHeightStmt *sql.Stmt + getNonRevertedTipsetAtHeightStmt *sql.Stmt + countTipsetsAtHeightStmt *sql.Stmt } type SqliteIndexer struct { @@ -66,8 +71,13 @@ type SqliteIndexer struct { updateSubs map[uint64]*updateSub subIdCounter uint64 + started bool + closeLk sync.RWMutex closed bool + + // ensures writes are serialized so backfilling does not race with index updates + writerLk sync.Mutex } func NewSqliteIndexer(path string, cs ChainStore, gcRetentionEpochs int64, reconcileEmptyIndex bool, @@ -115,6 +125,9 @@ func NewSqliteIndexer(path string, cs ChainStore, gcRetentionEpochs int64, recon func (si *SqliteIndexer) Start() error { si.wg.Add(1) go si.gcLoop() + + si.started = true + return nil } @@ -220,6 +233,9 @@ func (si *SqliteIndexer) Apply(ctx context.Context, from, to *types.TipSet) erro } si.closeLk.RUnlock() + si.writerLk.Lock() + defer si.writerLk.Unlock() + // We're moving the chain ahead from the `from` tipset to the `to` tipset // Height(to) > Height(from) err := withTx(ctx, si.db, func(tx *sql.Tx) error { @@ -337,6 +353,9 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err } si.closeLk.RUnlock() + si.writerLk.Lock() + defer si.writerLk.Unlock() + // We're reverting the chain from the tipset at `from` to the tipset at `to`. // Height(to) < Height(from) @@ -353,12 +372,18 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err } err = withTx(ctx, si.db, func(tx *sql.Tx) error { + // revert the `from` tipset if _, err := tx.Stmt(si.stmts.updateTipsetToRevertedStmt).ExecContext(ctx, revertTsKeyCid); err != nil { return xerrors.Errorf("failed to mark tipset %s as reverted: %w", revertTsKeyCid, err) } + // index the `to` tipset -> it is idempotent + if err := si.indexTipset(ctx, tx, to); err != nil { + return xerrors.Errorf("failed to index tipset: %w", err) + } + // events are indexed against the message inclusion tipset, not the message execution tipset. - // So we need to revert the events for the message inclusion tipset. + // So we need to revert the events for the message inclusion tipset i.e. `to` tipset. if _, err := tx.Stmt(si.stmts.updateEventsToRevertedStmt).ExecContext(ctx, eventTsKeyCid); err != nil { return xerrors.Errorf("failed to revert events for tipset %s: %w", eventTsKeyCid, err) } diff --git a/chain/index/interface.go b/chain/index/interface.go index 67b43f3be4f..1dd84e7f5d1 100644 --- a/chain/index/interface.go +++ b/chain/index/interface.go @@ -67,6 +67,8 @@ type Indexer interface { GetEventsForFilter(ctx context.Context, f *EventFilter, excludeReverted bool) ([]*CollectedEvent, error) + ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) + Close() error } diff --git a/chain/index/reconcile.go b/chain/index/reconcile.go index 2a36a93db58..c2fdb0e8f33 100644 --- a/chain/index/reconcile.go +++ b/chain/index/reconcile.go @@ -27,6 +27,9 @@ import ( // This function is crucial for maintaining index integrity, especially after chain reorgs. // It ensures that the index accurately reflects the current state of the blockchain. func (si *SqliteIndexer) ReconcileWithChain(ctx context.Context, head *types.TipSet) error { + si.writerLk.Lock() + defer si.writerLk.Unlock() + if !si.cs.IsStoringEvents() { log.Warn("chain indexer is not storing events during reconciliation; please ensure this is intentional") } @@ -43,13 +46,12 @@ func (si *SqliteIndexer) ReconcileWithChain(ctx context.Context, head *types.Tip } return withTx(ctx, si.db, func(tx *sql.Tx) error { - var hasTipset bool - err := tx.StmtContext(ctx, si.stmts.isTipsetMessageNonEmptyStmt).QueryRowContext(ctx).Scan(&hasTipset) + var isIndexEmpty bool + err := tx.StmtContext(ctx, si.stmts.isIndexEmptyStmt).QueryRowContext(ctx).Scan(&isIndexEmpty) if err != nil { - return xerrors.Errorf("failed to check if tipset message is empty: %w", err) + return xerrors.Errorf("failed to check if index is empty: %w", err) } - isIndexEmpty := !hasTipset if isIndexEmpty && !si.reconcileEmptyIndex { log.Info("chain index is empty and reconcileEmptyIndex is disabled; skipping reconciliation") return nil diff --git a/chain/types/index.go b/chain/types/index.go new file mode 100644 index 00000000000..a43e2a9019d --- /dev/null +++ b/chain/types/index.go @@ -0,0 +1,11 @@ +package types + +type IndexValidation struct { + TipsetKey string + Height uint64 + + TotalMessages uint64 + TotalEvents uint64 + EventsReverted bool + Backfilled bool +} diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index da322b4882d..8594aa34658 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -37,6 +37,7 @@ * [ChainSetHead](#ChainSetHead) * [ChainStatObj](#ChainStatObj) * [ChainTipSetWeight](#ChainTipSetWeight) + * [ChainValidateIndex](#ChainValidateIndex) * [Create](#Create) * [CreateBackup](#CreateBackup) * [Eth](#Eth) @@ -1233,6 +1234,31 @@ Inputs: Response: `"0"` +### ChainValidateIndex +There are not yet any comments for this method. + +Perms: read + +Inputs: +```json +[ + 10101, + true +] +``` + +Response: +```json +{ + "TipsetKey": "string value", + "Height": 42, + "TotalMessages": 42, + "TotalEvents": 42, + "EventsReverted": true, + "Backfilled": true +} +``` + ## Create diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 16991069c9c..ba86ab57c8e 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -524,6 +524,17 @@ func TestEthGetLogsBasic(t *testing.T) { } AssertEthLogs(t, rctLogs, expected, received) + + iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(0), false) + require.NoError(err) + require.NotNil(iv) + + fmt.Printf("index validation: %v\n", iv) + + iv, err = client.ChainValidateIndex(ctx, abi.ChainEpoch(22), false) + require.NoError(err) + require.NotNil(iv) + fmt.Printf("index validation: %v\n", iv) } func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { diff --git a/node/builder_chain.go b/node/builder_chain.go index 0f0c7102e6b..aa8a80c1c2f 100644 --- a/node/builder_chain.go +++ b/node/builder_chain.go @@ -287,6 +287,9 @@ func ConfigFullNode(c interface{}) Option { If(cfg.ChainIndexer.EnableIndexer, Override(InitChainIndexerKey, modules.InitChainIndexer), ), + If(cfg.ChainIndexer.EnableIndexer, + Override(new(full.ChainIndexerAPI), modules.ChainIndexHandler(cfg.ChainIndexer)), + ), ), ) } diff --git a/node/impl/full.go b/node/impl/full.go index 6ed0bf3eb11..24240e3df2c 100644 --- a/node/impl/full.go +++ b/node/impl/full.go @@ -36,6 +36,7 @@ type FullNodeAPI struct { full.EthAPI full.ActorEventsAPI full.F3API + full.ChainIndexAPI DS dtypes.MetadataDS NetworkName dtypes.NetworkName diff --git a/node/impl/full/chain_index.go b/node/impl/full/chain_index.go new file mode 100644 index 00000000000..7276d594c61 --- /dev/null +++ b/node/impl/full/chain_index.go @@ -0,0 +1,48 @@ +package full + +import ( + "context" + "errors" + + "go.uber.org/fx" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/index" + "github.com/filecoin-project/lotus/chain/types" +) + +type ChainIndexerAPI interface { + ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) +} + +var ( + _ ChainIndexerAPI = *new(api.FullNode) +) + +type ChainIndexAPI struct { + fx.In + ChainIndexerAPI +} + +type ChainIndexHandler struct { + indexer index.Indexer +} + +func (ch *ChainIndexHandler) ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) { + if ch.indexer == nil { + return nil, errors.New("chain indexer is not initialized") + } + return ch.indexer.ChainValidateIndex(ctx, epoch, backfill) +} + +var _ ChainIndexerAPI = (*ChainIndexHandler)(nil) + +func NewChainIndexHandler( + indexer index.Indexer, +) *ChainIndexHandler { + return &ChainIndexHandler{ + indexer: indexer, + } +} diff --git a/node/modules/chainindex.go b/node/modules/chainindex.go index e0a44ed1fe4..c4c0e606880 100644 --- a/node/modules/chainindex.go +++ b/node/modules/chainindex.go @@ -10,6 +10,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/events" "github.com/filecoin-project/lotus/chain/index" "github.com/filecoin-project/lotus/chain/messagepool" @@ -17,6 +18,7 @@ import ( "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/impl/full" "github.com/filecoin-project/lotus/node/modules/helpers" "github.com/filecoin-project/lotus/node/repo" ) @@ -79,7 +81,7 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In if err != nil { return err } - go index.WaitForMpoolUpdates(ctx, ch, indexer) + go WaitForMpoolUpdates(ctx, ch, indexer) ev, err := events.NewEvents(ctx, &evapi) if err != nil { @@ -108,3 +110,33 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In }, }) } + +func ChainIndexHandler(cfg config.ChainIndexerConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, index.Indexer) (*full.ChainIndexHandler, error) { + return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, indexer index.Indexer) (*full.ChainIndexHandler, error) { + if !cfg.EnableIndexer { + return nil, nil + } + + return full.NewChainIndexHandler(indexer), nil + } +} + +func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, indexer index.Indexer) { + for ctx.Err() == nil { + select { + case <-ctx.Done(): + return + case u := <-ch: + if u.Type != api.MpoolAdd { + continue + } + if u.Message == nil { + continue + } + err := indexer.IndexSignedMessage(ctx, u.Message) + if err != nil { + log.Errorw("failed to index signed Mpool message", "error", err) + } + } + } +} From 1b5fed3f5947ff2bb09f7b76de37af5cef572082 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 17 Sep 2024 13:17:47 +0530 Subject: [PATCH 02/61] feat: chain indexer todos [skip changelog] (#12462) * feat: finish todos of validation api * feat: add indexed data verification with chain store * feat: address comments and finish TODO * fix: build issue * address comments * fix: ci issue --- build/openrpc/full.json | 4 -- chain/index/api.go | 116 +++++++++++++++++++++++++++++++++++--- chain/index/ddls.go | 2 + chain/index/gc.go | 5 +- chain/index/indexer.go | 27 ++++----- chain/index/read.go | 10 +--- chain/index/reconcile.go | 5 +- chain/types/index.go | 7 +-- itests/eth_filter_test.go | 19 ++++++- 9 files changed, 149 insertions(+), 46 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 8236985c928..ec52f0da4ea 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2059,7 +2059,6 @@ "Height": 42, "TotalMessages": 42, "TotalEvents": 42, - "EventsReverted": true, "Backfilled": true } ], @@ -2068,9 +2067,6 @@ "Backfilled": { "type": "boolean" }, - "EventsReverted": { - "type": "boolean" - }, "Height": { "title": "number", "type": "number" diff --git a/chain/index/api.go b/chain/index/api.go index 3674aa3046f..054322e6828 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -60,6 +60,11 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if !si.started { return nil, xerrors.Errorf("ChainValidateIndex can only be called after the indexer has been started") } + + if si.isClosed() { + return nil, xerrors.Errorf("ChainValidateIndex can only be called before the indexer has been closed") + } + si.writerLk.Lock() defer si.writerLk.Unlock() @@ -126,17 +131,107 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, xerrors.Errorf("failed to cast tipset key cid: %w", err) } - if indexedTsKeyCid != expectedTsKeyCid { + if !indexedTsKeyCid.Equals(expectedTsKeyCid) { return nil, xerrors.Errorf("index corruption: non-reverted tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) } + // indexedTsKeyCid and expectedTsKeyCid are the same, so we can use `expectedTs` to fetch the indexed data + indexedData, err := si.getIndexedTipSetData(ctx, expectedTs) + if err != nil { + return nil, xerrors.Errorf("failed to get tipset message and event counts at height %d: %w", expectedTs.Height(), err) + } + + if indexedData == nil { + return nil, xerrors.Errorf("invalid indexed data for tipset at height %d", expectedTs.Height()) + } + + if err = si.verifyIndexedData(ctx, expectedTs, indexedData); err != nil { + return nil, xerrors.Errorf("failed to verify indexed data at height %d: %w", expectedTs.Height(), err) + } + return &types.IndexValidation{ - TipsetKey: expectedTs.Key().String(), - Height: uint64(expectedTs.Height()), - // TODO Other fields + TipsetKey: expectedTs.Key().String(), + Height: uint64(expectedTs.Height()), + NonRevertedMessageCount: uint64(indexedData.nonRevertedMessageCount), + NonRevertedEventsCount: uint64(indexedData.nonRevertedEventCount), }, nil } +type indexedTipSetData struct { + nonRevertedMessageCount int + nonRevertedEventCount int +} + +// getIndexedTipSetData fetches the indexed tipset data for a tipset +func (si *SqliteIndexer) getIndexedTipSetData(ctx context.Context, ts *types.TipSet) (*indexedTipSetData, error) { + tsKeyCidBytes, err := toTipsetKeyCidBytes(ts) + if err != nil { + return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) + } + + var data indexedTipSetData + err = withTx(ctx, si.db, func(tx *sql.Tx) error { + if err = tx.Stmt(si.stmts.getNonRevertedTipsetMessageCountStmt).QueryRowContext(ctx, tsKeyCidBytes).Scan(&data.nonRevertedMessageCount); err != nil { + return xerrors.Errorf("failed to query non reverted message count: %w", err) + } + + if err = tx.Stmt(si.stmts.getNonRevertedTipsetEventCountStmt).QueryRowContext(ctx, tsKeyCidBytes).Scan(&data.nonRevertedEventCount); err != nil { + return xerrors.Errorf("failed to query non reverted event count: %w", err) + } + + return nil + }) + + return &data, err +} + +// verifyIndexedData verifies that the indexed data for a tipset is correct +// by comparing the number of messages and events in the chainstore to the number of messages and events indexed. +// NOTE: Events are loaded from the executed messages of the tipset at the next epoch (ts.Height() + 1). +func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet, indexedData *indexedTipSetData) (err error) { + tsKeyCid, err := ts.Key().Cid() + if err != nil { + return xerrors.Errorf("failed to get tipset key cid: %w", err) + } + + // get the tipset where the messages of `ts` will be executed (deferred execution) + executionTs, err := si.cs.GetTipsetByHeight(ctx, ts.Height()+1, nil, false) + if err != nil { + return xerrors.Errorf("failed to get tipset by height: %w", err) + } + + eParentTsKeyCid, err := executionTs.Parents().Cid() + if err != nil { + return xerrors.Errorf("failed to get execution tipset parent key cid: %w", err) + } + + // the parent tipset of the execution tipset should be the same as the indexed tipset (`ts` should be the parent of `executionTs`) + if !eParentTsKeyCid.Equals(tsKeyCid) { + return xerrors.Errorf("execution tipset parent key mismatch: chainstore has %s, index has %s", eParentTsKeyCid, tsKeyCid) + } + + executedMsgs, err := si.loadExecutedMessages(ctx, ts, executionTs) + if err != nil { + return xerrors.Errorf("failed to load executed messages: %w", err) + } + + totalEventsCount := 0 + for _, emsg := range executedMsgs { + totalEventsCount += len(emsg.evs) + } + + if totalEventsCount != indexedData.nonRevertedEventCount { + return xerrors.Errorf("tipset event count mismatch: chainstore has %d, index has %d", totalEventsCount, indexedData.nonRevertedEventCount) + } + + totalExecutedMsgCount := len(executedMsgs) + if totalExecutedMsgCount != indexedData.nonRevertedMessageCount { + return xerrors.Errorf("tipset executed message count mismatch: chainstore has %d, index has %d", totalExecutedMsgCount, indexedData.nonRevertedMessageCount) + } + + return nil +} + func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.TipSet, backfill bool) (*types.IndexValidation, error) { if !backfill { return nil, xerrors.Errorf("missing tipset at height %d in the chain index, set backfill to true to backfill", ts.Height()) @@ -159,9 +254,16 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti return nil, xerrors.Errorf("error applying tipset: %w", err) } + indexedData, err := si.getIndexedTipSetData(ctx, ts) + if err != nil { + return nil, xerrors.Errorf("failed to get tipset message and event counts at height %d: %w", ts.Height(), err) + } + return &types.IndexValidation{ - TipsetKey: ts.Key().String(), - Height: uint64(ts.Height()), - Backfilled: true, + TipsetKey: ts.Key().String(), + Height: uint64(ts.Height()), + Backfilled: true, + NonRevertedMessageCount: uint64(indexedData.nonRevertedMessageCount), + NonRevertedEventsCount: uint64(indexedData.nonRevertedEventCount), }, nil } diff --git a/chain/index/ddls.go b/chain/index/ddls.go index 8a1927430e0..922c1c46e27 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -82,5 +82,7 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0", &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", + &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0", + &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", } } diff --git a/chain/index/gc.go b/chain/index/gc.go index e30d4700aaf..0b34eefcfb4 100644 --- a/chain/index/gc.go +++ b/chain/index/gc.go @@ -25,12 +25,9 @@ func (si *SqliteIndexer) gcLoop() { defer cleanupTicker.Stop() for si.ctx.Err() == nil { - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return } - si.closeLk.RUnlock() select { case <-cleanupTicker.C: diff --git a/chain/index/indexer.go b/chain/index/indexer.go index 18dc71a0192..e6756c07bd8 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -48,6 +48,9 @@ type preparedStatements struct { hasNullRoundAtHeightStmt *sql.Stmt getNonRevertedTipsetAtHeightStmt *sql.Stmt countTipsetsAtHeightStmt *sql.Stmt + + getNonRevertedTipsetMessageCountStmt *sql.Stmt + getNonRevertedTipsetEventCountStmt *sql.Stmt } type SqliteIndexer struct { @@ -173,12 +176,9 @@ func (si *SqliteIndexer) initStatements() error { } func (si *SqliteIndexer) IndexEthTxHash(ctx context.Context, txHash ethtypes.EthHash, msgCid cid.Cid) error { - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return ErrClosed } - si.closeLk.RUnlock() return withTx(ctx, si.db, func(tx *sql.Tx) error { return si.indexEthTxHash(ctx, tx, txHash, msgCid) @@ -199,12 +199,10 @@ func (si *SqliteIndexer) IndexSignedMessage(ctx context.Context, msg *types.Sign if msg.Signature.Type != crypto.SigTypeDelegated { return nil } - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + + if si.isClosed() { return ErrClosed } - si.closeLk.RUnlock() return withTx(ctx, si.db, func(tx *sql.Tx) error { return si.indexSignedMessage(ctx, tx, msg) @@ -227,7 +225,7 @@ func (si *SqliteIndexer) indexSignedMessage(ctx context.Context, tx *sql.Tx, msg func (si *SqliteIndexer) Apply(ctx context.Context, from, to *types.TipSet) error { si.closeLk.RLock() - if si.closed { + if si.isClosed() { si.closeLk.RUnlock() return ErrClosed } @@ -346,12 +344,9 @@ func (si *SqliteIndexer) restoreTipsetIfExists(ctx context.Context, tx *sql.Tx, } func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) error { - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return ErrClosed } - si.closeLk.RUnlock() si.writerLk.Lock() defer si.writerLk.Unlock() @@ -398,3 +393,9 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err return nil } + +func (si *SqliteIndexer) isClosed() bool { + si.closeLk.RLock() + defer si.closeLk.RUnlock() + return si.closed +} diff --git a/chain/index/read.go b/chain/index/read.go index 3d03e7957ce..cee9b2c428b 100644 --- a/chain/index/read.go +++ b/chain/index/read.go @@ -16,12 +16,9 @@ import ( const headIndexedWaitTimeout = 5 * time.Second func (si *SqliteIndexer) GetCidFromHash(ctx context.Context, txHash ethtypes.EthHash) (cid.Cid, error) { - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return cid.Undef, ErrClosed } - si.closeLk.RUnlock() var msgCidBytes []byte @@ -44,12 +41,9 @@ func (si *SqliteIndexer) queryMsgCidFromEthHash(ctx context.Context, txHash etht } func (si *SqliteIndexer) GetMsgInfo(ctx context.Context, messageCid cid.Cid) (*MsgInfo, error) { - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return nil, ErrClosed } - si.closeLk.RUnlock() var tipsetKeyCidBytes []byte var height int64 diff --git a/chain/index/reconcile.go b/chain/index/reconcile.go index c2fdb0e8f33..d0d64532f71 100644 --- a/chain/index/reconcile.go +++ b/chain/index/reconcile.go @@ -34,12 +34,9 @@ func (si *SqliteIndexer) ReconcileWithChain(ctx context.Context, head *types.Tip log.Warn("chain indexer is not storing events during reconciliation; please ensure this is intentional") } - si.closeLk.RLock() - if si.closed { - si.closeLk.RUnlock() + if si.isClosed() { return ErrClosed } - si.closeLk.RUnlock() if head == nil { return nil diff --git a/chain/types/index.go b/chain/types/index.go index a43e2a9019d..631aaebd42c 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -4,8 +4,7 @@ type IndexValidation struct { TipsetKey string Height uint64 - TotalMessages uint64 - TotalEvents uint64 - EventsReverted bool - Backfilled bool + NonRevertedMessageCount uint64 + NonRevertedEventsCount uint64 + Backfilled bool } diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index ba86ab57c8e..67dba8f1efe 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -525,16 +525,31 @@ func TestEthGetLogsBasic(t *testing.T) { AssertEthLogs(t, rctLogs, expected, received) - iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(0), false) + epoch := uint64(0) + iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), false) require.NoError(err) require.NotNil(iv) fmt.Printf("index validation: %v\n", iv) - iv, err = client.ChainValidateIndex(ctx, abi.ChainEpoch(22), false) + // Add assertions for IndexValidation fields + require.NotEmpty(t, iv.TipsetKey, "TipsetKey should not be empty") + require.Equal(t, epoch, iv.Height, "Height should be 0") + require.GreaterOrEqual(t, iv.NonRevertedMessageCount, uint64(0), "NonRevertedMessageCount should be non-negative") // TODO: change according to actual number of messages in the tipset + require.GreaterOrEqual(t, iv.NonRevertedEventsCount, uint64(0), "NonRevertedEventsCount should be non-negative") // TODO: change according to actual number of messages in the tipset + require.False(iv.Backfilled, "Backfilled should be flase") + + epoch = 22 + iv, err = client.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), false) require.NoError(err) require.NotNil(iv) fmt.Printf("index validation: %v\n", iv) + + require.NotEmpty(t, iv.TipsetKey, "TipsetKey should not be empty") + require.Equal(t, epoch, iv.Height, "Height should be 22") + require.GreaterOrEqual(t, iv.NonRevertedMessageCount, uint64(0), "NonRevertedMessageCount be non-negative") // TODO: change according to actual number of messages in the tipset + require.GreaterOrEqual(t, iv.NonRevertedEventsCount, uint64(0), "NonRevertedEventsCount be non-negative") // TODO: change according to actual number of messages in the tipset + require.True(iv.Backfilled, "Backfilled should be false") } func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { From 260cde6cfc06e8cf3dd8daec820b09353344ccb2 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Tue, 17 Sep 2024 11:54:29 +0400 Subject: [PATCH 03/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- api/api_full.go | 2 +- chain/index/api.go | 11 ++++++----- chain/index/ddls.go | 2 +- chain/types/index.go | 2 +- node/builder_chain.go | 2 -- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index f786f3b167e..e80f7cad359 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -64,7 +64,7 @@ type FullNode interface { Net // MethodGroup: ChainIndexer - ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) //perm:read + ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) //perm:write // MethodGroup: Chain // The Chain method group contains methods for interacting with the diff --git a/chain/index/api.go b/chain/index/api.go index 054322e6828..4f2c17e682d 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -19,6 +19,7 @@ func (si *SqliteIndexer) sanityCheckBackfillEpoch(ctx context.Context, epoch abi if err != nil { return xerrors.Errorf("failed to get max non reverted height: %w", err) } + // couldn't find any non-reverted entries if !maxNonRevertedHeight.Valid { return nil } @@ -93,6 +94,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if isIndexEmpty { return nil, nil } + // validate the db has a hole here and error if not, we don't attempt to repair because something must be very wrong for this to fail return si.validateNullRound(ctx, epoch) } @@ -108,15 +110,14 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } return nil, xerrors.Errorf("failed to get tipset counts at height: %w", err) } - if revertedCount == 0 && nonRevertedCount == 0 { + switch { + case revertedCount == 0 && nonRevertedCount == 0: return si.backfillMissingTipset(ctx, expectedTs, backfill) - } - if revertedCount > 0 && nonRevertedCount == 0 { + case revertedCount > 0 && nonRevertedCount == 0: return nil, xerrors.Errorf("index corruption: height %d only has reverted tipsets", epoch) - } - if nonRevertedCount > 1 { + case nonRevertedCount > 1: return nil, xerrors.Errorf("index corruption: height %d has multiple non-reverted tipsets", epoch) } diff --git a/chain/index/ddls.go b/chain/index/ddls.go index 922c1c46e27..c21f9228f4b 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -80,7 +80,7 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.insertEventEntryStmt: "INSERT INTO event_entry (event_id, indexed, flags, key, codec, value) VALUES (?, ?, ?, ?, ?, ?)", &ps.getMaxNonRevertedHeightStmt: "SELECT MAX(height) FROM tipset_message WHERE reverted = 0", &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", - &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0", + &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0 LIMIT 1", &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0", &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", diff --git a/chain/types/index.go b/chain/types/index.go index 631aaebd42c..5813aea5b57 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -1,7 +1,7 @@ package types type IndexValidation struct { - TipsetKey string + TipSetKey TipSetKey Height uint64 NonRevertedMessageCount uint64 diff --git a/node/builder_chain.go b/node/builder_chain.go index aa8a80c1c2f..5502c2cc06f 100644 --- a/node/builder_chain.go +++ b/node/builder_chain.go @@ -286,8 +286,6 @@ func ConfigFullNode(c interface{}) Option { Override(new(index.Indexer), modules.ChainIndexer(cfg.ChainIndexer)), If(cfg.ChainIndexer.EnableIndexer, Override(InitChainIndexerKey, modules.InitChainIndexer), - ), - If(cfg.ChainIndexer.EnableIndexer, Override(new(full.ChainIndexerAPI), modules.ChainIndexHandler(cfg.ChainIndexer)), ), ), From 127b14491c7511277f19c716d6b1875aec66234b Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 17 Sep 2024 15:04:39 +0400 Subject: [PATCH 04/61] changes to Index Validation API based on Rodds first review --- api/proxy_gen.go | 2 +- build/openrpc/full.json | 24 ++++++--- chain/index/api.go | 52 +++++++++++------- chain/index/ddls.go | 5 +- chain/index/indexer.go | 14 ++--- chain/types/index.go | 6 +-- documentation/en/api-v1-unstable-methods.md | 16 ++++-- itests/eth_filter_test.go | 60 +++++++++++++-------- 8 files changed, 112 insertions(+), 67 deletions(-) diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 2c1b585c424..edef7d7e73f 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -169,7 +169,7 @@ type FullNodeMethods struct { ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"` - ChainValidateIndex func(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) `perm:"read"` + ChainValidateIndex func(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) `perm:"write"` CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"` diff --git a/build/openrpc/full.json b/build/openrpc/full.json index ec52f0da4ea..2861eb11dfb 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2055,10 +2055,17 @@ "schema": { "examples": [ { - "TipsetKey": "string value", + "TipSetKey": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], "Height": 42, - "TotalMessages": 42, - "TotalEvents": 42, + "IndexedMessagesCount": 42, + "IndexedEventsCount": 42, "Backfilled": true } ], @@ -2071,16 +2078,17 @@ "title": "number", "type": "number" }, - "TipsetKey": { - "type": "string" - }, - "TotalEvents": { + "IndexedEventsCount": { "title": "number", "type": "number" }, - "TotalMessages": { + "IndexedMessagesCount": { "title": "number", "type": "number" + }, + "TipSetKey": { + "additionalProperties": false, + "type": "object" } }, "type": [ diff --git a/chain/index/api.go b/chain/index/api.go index 4f2c17e682d..1aea4fb433f 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -30,7 +30,7 @@ func (si *SqliteIndexer) sanityCheckBackfillEpoch(ctx context.Context, epoch abi return nil } -func (si *SqliteIndexer) validateNullRound(ctx context.Context, epoch abi.ChainEpoch) (*types.IndexValidation, error) { +func (si *SqliteIndexer) validateIsNullRound(ctx context.Context, epoch abi.ChainEpoch) (*types.IndexValidation, error) { // make sure we do not have ANY non-reverted tipset at this epoch var isNullRound bool err := si.stmts.hasNullRoundAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&isNullRound) @@ -84,10 +84,6 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if err != nil { return nil, xerrors.Errorf("failed to get tipset by height: %w", err) } - expectedTsKeyCid, err := expectedTs.Key().Cid() - if err != nil { - return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) - } // Canonical chain has a null round at the epoch -> return if index is empty otherwise validate if expectedTs.Height() != epoch { // Canonical chain has a null round at the epoch @@ -95,7 +91,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, nil } // validate the db has a hole here and error if not, we don't attempt to repair because something must be very wrong for this to fail - return si.validateNullRound(ctx, epoch) + return si.validateIsNullRound(ctx, epoch) } // if the index is empty -> short-circuit and simply backfill if applicable @@ -131,7 +127,10 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if err != nil { return nil, xerrors.Errorf("failed to cast tipset key cid: %w", err) } - + expectedTsKeyCid, err := expectedTs.Key().Cid() + if err != nil { + return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) + } if !indexedTsKeyCid.Equals(expectedTsKeyCid) { return nil, xerrors.Errorf("index corruption: non-reverted tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) } @@ -139,7 +138,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain // indexedTsKeyCid and expectedTsKeyCid are the same, so we can use `expectedTs` to fetch the indexed data indexedData, err := si.getIndexedTipSetData(ctx, expectedTs) if err != nil { - return nil, xerrors.Errorf("failed to get tipset message and event counts at height %d: %w", expectedTs.Height(), err) + return nil, xerrors.Errorf("failed to get indexed data for tipset at height %d: %w", expectedTs.Height(), err) } if indexedData == nil { @@ -151,10 +150,10 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } return &types.IndexValidation{ - TipsetKey: expectedTs.Key().String(), - Height: uint64(expectedTs.Height()), - NonRevertedMessageCount: uint64(indexedData.nonRevertedMessageCount), - NonRevertedEventsCount: uint64(indexedData.nonRevertedEventCount), + TipSetKey: expectedTs.Key(), + Height: uint64(expectedTs.Height()), + IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), + IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), }, nil } @@ -207,8 +206,11 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet } // the parent tipset of the execution tipset should be the same as the indexed tipset (`ts` should be the parent of `executionTs`) + // if that is not the case, it means that the chain forked after we fetched the tipset `ts` from the canonical chain and + // `ts` is no longer part of the canonical chain. Simply return an error here and ask the user to retry. if !eParentTsKeyCid.Equals(tsKeyCid) { - return xerrors.Errorf("execution tipset parent key mismatch: chainstore has %s, index has %s", eParentTsKeyCid, tsKeyCid) + return xerrors.Errorf("execution tipset parent key mismatch: chainstore has %s, index has %s; please retry your request as this could have been caused by a chain reorg", + eParentTsKeyCid, tsKeyCid) } executedMsgs, err := si.loadExecutedMessages(ctx, ts, executionTs) @@ -222,12 +224,22 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet } if totalEventsCount != indexedData.nonRevertedEventCount { - return xerrors.Errorf("tipset event count mismatch: chainstore has %d, index has %d", totalEventsCount, indexedData.nonRevertedEventCount) + return xerrors.Errorf("event count mismatch: chainstore has %d, index has %d", totalEventsCount, indexedData.nonRevertedEventCount) } totalExecutedMsgCount := len(executedMsgs) if totalExecutedMsgCount != indexedData.nonRevertedMessageCount { - return xerrors.Errorf("tipset executed message count mismatch: chainstore has %d, index has %d", totalExecutedMsgCount, indexedData.nonRevertedMessageCount) + return xerrors.Errorf("message count mismatch: chainstore has %d, index has %d", totalExecutedMsgCount, indexedData.nonRevertedMessageCount) + } + + // if non-reverted events exist which means that tipset `ts` has been executed, there should be 0 reverted events in the DB + var hasRevertedEventsInTipset bool + err = si.stmts.hasRevertedEventsInTipsetStmt.QueryRowContext(ctx, tsKeyCid.Bytes()).Scan(&hasRevertedEventsInTipset) + if err != nil { + return xerrors.Errorf("failed to check if there are reverted events in tipset: %w", err) + } + if hasRevertedEventsInTipset { + return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s", tsKeyCid) } return nil @@ -261,10 +273,10 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti } return &types.IndexValidation{ - TipsetKey: ts.Key().String(), - Height: uint64(ts.Height()), - Backfilled: true, - NonRevertedMessageCount: uint64(indexedData.nonRevertedMessageCount), - NonRevertedEventsCount: uint64(indexedData.nonRevertedEventCount), + TipSetKey: ts.Key(), + Height: uint64(ts.Height()), + Backfilled: true, + IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), + IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), }, nil } diff --git a/chain/index/ddls.go b/chain/index/ddls.go index c21f9228f4b..c171b597761 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -82,7 +82,8 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0 LIMIT 1", &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", - &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0", - &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", + &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0 AND message_cid IS NOT NULL", + &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", + &ps.hasRevertedEventsInTipsetStmt: "SELECT EXISTS(SELECT 1 FROM event WHERE reverted = 1 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?))", } } diff --git a/chain/index/indexer.go b/chain/index/indexer.go index e6756c07bd8..f5571a5e06c 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -51,6 +51,7 @@ type preparedStatements struct { getNonRevertedTipsetMessageCountStmt *sql.Stmt getNonRevertedTipsetEventCountStmt *sql.Stmt + hasRevertedEventsInTipsetStmt *sql.Stmt } type SqliteIndexer struct { @@ -224,15 +225,11 @@ func (si *SqliteIndexer) indexSignedMessage(ctx context.Context, tx *sql.Tx, msg } func (si *SqliteIndexer) Apply(ctx context.Context, from, to *types.TipSet) error { - si.closeLk.RLock() if si.isClosed() { - si.closeLk.RUnlock() return ErrClosed } - si.closeLk.RUnlock() si.writerLk.Lock() - defer si.writerLk.Unlock() // We're moving the chain ahead from the `from` tipset to the `to` tipset // Height(to) > Height(from) @@ -245,8 +242,10 @@ func (si *SqliteIndexer) Apply(ctx context.Context, from, to *types.TipSet) erro }) if err != nil { + si.writerLk.Unlock() return xerrors.Errorf("failed to apply tipset: %w", err) } + si.writerLk.Unlock() si.notifyUpdateSubs() @@ -348,9 +347,6 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err return ErrClosed } - si.writerLk.Lock() - defer si.writerLk.Unlock() - // We're reverting the chain from the tipset at `from` to the tipset at `to`. // Height(to) < Height(from) @@ -366,6 +362,8 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err return xerrors.Errorf("failed to get tipset key cid: %w", err) } + si.writerLk.Lock() + err = withTx(ctx, si.db, func(tx *sql.Tx) error { // revert the `from` tipset if _, err := tx.Stmt(si.stmts.updateTipsetToRevertedStmt).ExecContext(ctx, revertTsKeyCid); err != nil { @@ -386,9 +384,11 @@ func (si *SqliteIndexer) Revert(ctx context.Context, from, to *types.TipSet) err return nil }) if err != nil { + si.writerLk.Unlock() return xerrors.Errorf("failed during revert transaction: %w", err) } + si.writerLk.Unlock() si.notifyUpdateSubs() return nil diff --git a/chain/types/index.go b/chain/types/index.go index 5813aea5b57..a9e23389289 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -4,7 +4,7 @@ type IndexValidation struct { TipSetKey TipSetKey Height uint64 - NonRevertedMessageCount uint64 - NonRevertedEventsCount uint64 - Backfilled bool + IndexedMessagesCount uint64 + IndexedEventsCount uint64 + Backfilled bool } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 8594aa34658..3cd904d03de 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1237,7 +1237,7 @@ Response: `"0"` ### ChainValidateIndex There are not yet any comments for this method. -Perms: read +Perms: write Inputs: ```json @@ -1250,11 +1250,17 @@ Inputs: Response: ```json { - "TipsetKey": "string value", + "TipSetKey": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], "Height": 42, - "TotalMessages": 42, - "TotalEvents": 42, - "EventsReverted": true, + "IndexedMessagesCount": 42, + "IndexedEventsCount": 42, "Backfilled": true } ``` diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 67dba8f1efe..430e5ff90fd 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -525,31 +525,49 @@ func TestEthGetLogsBasic(t *testing.T) { AssertEthLogs(t, rctLogs, expected, received) - epoch := uint64(0) - iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), false) + head, err := client.ChainHead(ctx) require.NoError(err) - require.NotNil(iv) - fmt.Printf("index validation: %v\n", iv) + for height := 0; height < int(head.Height()); height++ { + // for each tipset + ts, err := client.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(height), types.EmptyTSK) + require.NoError(err) - // Add assertions for IndexValidation fields - require.NotEmpty(t, iv.TipsetKey, "TipsetKey should not be empty") - require.Equal(t, epoch, iv.Height, "Height should be 0") - require.GreaterOrEqual(t, iv.NonRevertedMessageCount, uint64(0), "NonRevertedMessageCount should be non-negative") // TODO: change according to actual number of messages in the tipset - require.GreaterOrEqual(t, iv.NonRevertedEventsCount, uint64(0), "NonRevertedEventsCount should be non-negative") // TODO: change according to actual number of messages in the tipset - require.False(iv.Backfilled, "Backfilled should be flase") + if ts.Height() != abi.ChainEpoch(height) { + iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(height), false) + require.Nil(iv) + require.NoError(err) + t.Logf("tipset %d is a null round", height) + continue + } - epoch = 22 - iv, err = client.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), false) - require.NoError(err) - require.NotNil(iv) - fmt.Printf("index validation: %v\n", iv) - - require.NotEmpty(t, iv.TipsetKey, "TipsetKey should not be empty") - require.Equal(t, epoch, iv.Height, "Height should be 22") - require.GreaterOrEqual(t, iv.NonRevertedMessageCount, uint64(0), "NonRevertedMessageCount be non-negative") // TODO: change according to actual number of messages in the tipset - require.GreaterOrEqual(t, iv.NonRevertedEventsCount, uint64(0), "NonRevertedEventsCount be non-negative") // TODO: change according to actual number of messages in the tipset - require.True(iv.Backfilled, "Backfilled should be false") + totalMessageCount := 0 + totalEventCount := 0 + messages, err := client.ChainGetMessagesInTipset(ctx, ts.Key()) + require.NoError(err) + totalMessageCount = len(messages) + for _, m := range messages { + receipt, err := client.StateSearchMsg(ctx, types.EmptyTSK, m.Cid, -1, false) + require.NoError(err) + require.NotNil(receipt) + // receipt + if receipt.Receipt.EventsRoot != nil { + events, err := client.ChainGetEvents(ctx, *receipt.Receipt.EventsRoot) + require.NoError(err) + totalEventCount += len(events) + } + } + t.Logf("tipset %d: %d messages, %d events", height, totalMessageCount, totalEventCount) + + iv, err := client.ChainValidateIndex(ctx, abi.ChainEpoch(height), false) + require.NoError(err) + require.NotNil(iv) + t.Logf("tipset %d: %+v", height, iv) + require.EqualValues(height, iv.Height) + require.EqualValues(totalMessageCount, iv.IndexedMessagesCount) + require.EqualValues(totalEventCount, iv.IndexedEventsCount) + require.False(iv.Backfilled) + } } func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { From 05b84ec5a66746aa3710c0506e0f7eeef48df641 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 17 Sep 2024 15:32:34 +0400 Subject: [PATCH 05/61] build chain indexer API --- node/builder_chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/builder_chain.go b/node/builder_chain.go index 5502c2cc06f..6f56f35eab2 100644 --- a/node/builder_chain.go +++ b/node/builder_chain.go @@ -284,9 +284,9 @@ func ConfigFullNode(c interface{}) Option { ApplyIf(isFullNode, Override(new(index.Indexer), modules.ChainIndexer(cfg.ChainIndexer)), + Override(new(full.ChainIndexerAPI), modules.ChainIndexHandler(cfg.ChainIndexer)), If(cfg.ChainIndexer.EnableIndexer, Override(InitChainIndexerKey, modules.InitChainIndexer), - Override(new(full.ChainIndexerAPI), modules.ChainIndexHandler(cfg.ChainIndexer)), ), ), ) From 11712bfa351adeefea62a874da6c702de9684326 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 18 Sep 2024 15:16:11 +0400 Subject: [PATCH 06/61] improve error handling --- chain/index/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 1aea4fb433f..4c2eef510c8 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -16,11 +16,11 @@ func (si *SqliteIndexer) sanityCheckBackfillEpoch(ctx context.Context, epoch abi // should be less than the max non reverted height in the Index var maxNonRevertedHeight sql.NullInt64 err := si.stmts.getMaxNonRevertedHeightStmt.QueryRowContext(ctx).Scan(&maxNonRevertedHeight) - if err != nil { + if err != nil && err != sql.ErrNoRows { return xerrors.Errorf("failed to get max non reverted height: %w", err) } // couldn't find any non-reverted entries - if !maxNonRevertedHeight.Valid { + if err == sql.ErrNoRows || !maxNonRevertedHeight.Valid { return nil } if epoch >= abi.ChainEpoch(maxNonRevertedHeight.Int64) { From e7506ccd42bf8f0b683515cdd66a32802f2b4e08 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 18 Sep 2024 17:16:09 +0530 Subject: [PATCH 07/61] feat: lotus-shed tooling for chain indexer (#12474) * feat: add lotus-shed command for backfilling chain indexer * feat: add lotus-shed command for inspecting the chain indexer * feat: use single lotus-shed command to inspect and backfill * fix: remove the unused queries * small changes * add change log --- CHANGELOG.md | 3 +- cmd/lotus-shed/indexes.go | 177 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 669129d5af5..f3197464ea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Lotus changelog # UNRELEASED - + - https://github.com/filecoin-project/lotus/pull/12474: feat: lotus-shed tooling for chain indexer + ## ☢️ Upgrade Warnings ☢️ ## New features diff --git a/cmd/lotus-shed/indexes.go b/cmd/lotus-shed/indexes.go index 07c934d5162..2abe186542f 100644 --- a/cmd/lotus-shed/indexes.go +++ b/cmd/lotus-shed/indexes.go @@ -3,6 +3,7 @@ package main import ( "context" "database/sql" + "encoding/json" "fmt" "math" "path" @@ -51,6 +52,7 @@ var indexesCmd = &cli.Command{ withCategory("txhash", backfillTxHashCmd), withCategory("events", backfillEventsCmd), withCategory("events", inspectEventsCmd), + withCategory("chainindex_validation", validateChainIndexCmd), }, } @@ -879,3 +881,178 @@ var backfillTxHashCmd = &cli.Command{ return nil }, } + +type IndexValidationJSON struct { + IndexedTipsetKey types.TipSetKey `json:"indexed_tipset_key"` + IndexedHeight uint64 `json:"indexed_height"` + IndexedMsgCount uint64 `json:"indexed_message_count"` + IndexedEventsCount uint64 `json:"indexed_events_count"` +} + +var validateChainIndexCmd = &cli.Command{ + Name: "validate-chainindex ", + Usage: "Validates the chainindex for a range of tipset epochs", + Flags: []cli.Flag{ + &cli.IntFlag{ + Name: "from", + Usage: "The tipset height (epoch) to start backfilling from (0 is head of chain)", + }, + &cli.IntFlag{ + Name: "to", + Usage: "The tipset height (epoch) to end backfilling at", + Required: true, + }, + &cli.BoolFlag{ + Name: "backfill", + Usage: "Backfill missing index entries while validating the chain index. When enabled, the command will perform backfilling for any missing indexes (default: true)", + Value: true, + }, + &cli.BoolFlag{ + Name: "failfast", + Usage: "Failfast when enabled, the validation process will terminate immediately upon encountering the first error (default: true)", + Value: true, + }, + &cli.BoolFlag{ + Name: "output", + Usage: "Output the backfilling results in JSON format", + Value: false, + }, + }, + Action: func(cctx *cli.Context) error { + srv, err := lcli.GetFullNodeServices(cctx) + if err != nil { + return fmt.Errorf("failed to get full node services: %w", err) + } + defer func() { + if closeErr := srv.Close(); closeErr != nil { + log.Errorf("Error closing services: %v", closeErr) + } + }() + + api := srv.FullNodeAPI() + ctx := lcli.ReqContext(cctx) + + fromEpoch := cctx.Int("from") + if fromEpoch == 0 { + curTs, err := api.ChainHead(ctx) + if err != nil { + return err + } + fromEpoch = int(curTs.Height()) - 1 + } else { + fromEpoch = fromEpoch - 1 + } + + if fromEpoch <= 0 { + return fmt.Errorf("invalid from epoch: %d", fromEpoch) + } + + toEpoch := cctx.Int("to") + if toEpoch > fromEpoch { + return fmt.Errorf("to epoch must be less than from epoch") + } + + backfill := cctx.Bool("backfill") + failfast := cctx.Bool("failfast") + output := cctx.Bool("output") + + // Results Tracking + var results []IndexValidationJSON + var backfilledEpochs []int + + log.Infof("Starting %s from epoch: %d to epoch: %d", + func() string { + if backfill { + return "backfill and inspect chainindex" + } + return "inspect chainindex" + }(), + fromEpoch, toEpoch) + + // starting from the FromEpoch-1 and going down to the ToEpoch + // this is because `ChainValidateIndex` fetches the tipset.height()+1, which might not be available in case of chain head + for epoch := fromEpoch; epoch >= toEpoch; epoch-- { + if ctx.Err() != nil { + return ctx.Err() + } + + indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) + if err != nil { + if failfast { + return fmt.Errorf("failed to validate index for epoch %d: %w", epoch, err) + } + log.Warnf("Error validating index for epoch %d: %v", epoch, err) + continue + } + + if !indexValidateResp.TipSetKey.IsEmpty() || indexValidateResp.Height != uint64(epoch) && indexValidateResp.Backfilled == backfill { + errMsg := fmt.Sprintf("epoch %d: invalid index validation response: %+v", epoch, indexValidateResp) + if failfast { + return fmt.Errorf(errMsg) + } + log.Warn(errMsg) + continue + } + + if backfill { + backfilledEpochs = append(backfilledEpochs, epoch) + } + + if output { + results = append(results, IndexValidationJSON{ + IndexedTipsetKey: indexValidateResp.TipSetKey, + IndexedHeight: indexValidateResp.Height, + IndexedMsgCount: indexValidateResp.IndexedMessagesCount, + IndexedEventsCount: indexValidateResp.IndexedEventsCount, + }) + } else { + logEpochResult(epoch, indexValidateResp) + } + } + + // Output JSON Results + if output { + if err := outputResults(results); err != nil { + return err + } + } + + // Log Summary + if backfill { + log.Infof("Backfilled epochs: %v", backfilledEpochs) + } else { + log.Infof("Inspection of chain index from epoch %d to %d completed.", fromEpoch, toEpoch) + } + + return nil + }, +} + +// outputResults marshals the results into JSON and outputs them. +func outputResults(results []IndexValidationJSON) error { + jsonData, err := json.MarshalIndent(results, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal results to JSON: %w", err) + } + fmt.Println(string(jsonData)) + return nil +} + +// logEpochResult logs the result of backfilling for a single epoch. +func logEpochResult(epoch int, indexValidate *types.IndexValidation) { + if indexValidate.Backfilled { + log.Infof("Epoch %d: Backfilled successfully. TipsetKey: %s, TotalMessages: %d, TotalEvents: %d", + epoch, + indexValidate.TipSetKey, + indexValidate.IndexedMessagesCount, + indexValidate.IndexedMessagesCount, + ) + } else { + log.Info("Epoch %d: validated successfully. TipsetKey: %s, TotalMessages: %d, TotalEvents: %d", + epoch, + indexValidate.TipSetKey, + indexValidate.IndexedMessagesCount, + indexValidate.IndexedMessagesCount, + ) + } +} From efbf51fb9079e1914c9f847e99e2e48869dd7769 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 18 Sep 2024 21:25:58 +0400 Subject: [PATCH 08/61] backfilling improvements and fixes --- chain/index/api.go | 21 ++++ cmd/lotus-shed/chain_index.go | 173 +++++++++++++++++++++++++++++++++ cmd/lotus-shed/indexes.go | 178 +--------------------------------- go.mod | 2 + go.sum | 5 +- node/impl/full/chain_index.go | 2 +- node/modules/chainindex.go | 5 - 7 files changed, 201 insertions(+), 185 deletions(-) create mode 100644 cmd/lotus-shed/chain_index.go diff --git a/chain/index/api.go b/chain/index/api.go index 4c2eef510c8..836304c4621 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -99,6 +99,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return si.backfillMissingTipset(ctx, expectedTs, backfill) } + // see if the tipset at this epoch is already indexed or if we need to backfill revertedCount, nonRevertedCount, err := si.getTipsetCountsAtHeight(ctx, epoch) if err != nil { if err == sql.ErrNoRows { @@ -108,6 +109,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } switch { case revertedCount == 0 && nonRevertedCount == 0: + // no tipsets at this epoch in the index, backfill return si.backfillMissingTipset(ctx, expectedTs, backfill) case revertedCount > 0 && nonRevertedCount == 0: @@ -135,6 +137,25 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, xerrors.Errorf("index corruption: non-reverted tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) } + // index the parent tipset and it's events so we dont need to look forward when validating/backfilling the parent + parentTs, err := si.cs.GetTipSetFromKey(ctx, expectedTs.Parents()) + if err != nil { + return nil, xerrors.Errorf("failed to get parent tipset: %w", err) + } + err = withTx(ctx, si.db, func(tx *sql.Tx) error { + if err := si.indexTipset(ctx, tx, parentTs); err != nil { + return xerrors.Errorf("error indexing parent tipset: %w", err) + } + if err := si.indexEvents(ctx, tx, parentTs, expectedTs); err != nil { + return xerrors.Errorf("error indexing events for tipset at height %d: %w", expectedTs.Height(), err) + } + + return nil + }) + if err != nil { + return nil, xerrors.Errorf("error validating tipset: %w", err) + } + // indexedTsKeyCid and expectedTsKeyCid are the same, so we can use `expectedTs` to fetch the indexed data indexedData, err := si.getIndexedTipSetData(ctx, expectedTs) if err != nil { diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go new file mode 100644 index 00000000000..9291c85cdbd --- /dev/null +++ b/cmd/lotus-shed/chain_index.go @@ -0,0 +1,173 @@ +package main + +import ( + "encoding/json" + "fmt" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" +) + +type IndexValidationJSON struct { + TipsetKey types.TipSetKey `json:"tipset_key"` + IndexHeight uint64 `json:"index_height"` + IndexMsgCount uint64 `json:"index_msg_count"` + IndexEventsCount uint64 `json:"index_events_count"` +} + +var validateChainIndexCmd = &cli.Command{ + Name: "validate-chainindex", + Usage: "Validates the chainindex for a range of epochs", + Description: ` + validate-chainindex is a command-line tool that validates the chainindex for a specified range of epochs. + It fetches the chain index entry for each epoch, checks for missing entries, and optionally backfills them. + The command provides options to specify the range of epochs, control backfilling, and handle validation errors. + + Usage: + lotus-shed validate-chainindex --from 200 --to 100 --backfill --output + + Flags: + --from Starting tipset epoch for validation (required) + --to Ending tipset epoch for validation (required) + --backfill Backfill missing index entries (default: true) + --output Output backfilling results in JSON format (default: false) + `, + Flags: []cli.Flag{ + &cli.IntFlag{ + Name: "from", + Usage: "from specifies the starting tipset epoch for validation. If set to 0, validation starts from the tipset just before the current head", + Required: true, + }, + &cli.IntFlag{ + Name: "to", + Usage: "to specifies the ending tipset epoch for validation", + Required: true, + }, + &cli.BoolFlag{ + Name: "backfill", + Usage: "backfill determines whether to backfill missing index entries during validation (default: true)", + Value: true, + }, + &cli.BoolFlag{ + Name: "output", + Usage: "output specifies whether to output the backfilling results in JSON format (default: true)", + Value: true, + }, + }, + Action: func(cctx *cli.Context) error { + srv, err := lcli.GetFullNodeServices(cctx) + if err != nil { + return xerrors.Errorf("failed to get full node services: %w", err) + } + defer func() { + if closeErr := srv.Close(); closeErr != nil { + log.Errorf("error closing services: %v", closeErr) + } + }() + + api := srv.FullNodeAPI() + ctx := lcli.ReqContext(cctx) + + fromEpoch := cctx.Int("from") + if fromEpoch == 0 { + curTs, err := api.ChainHead(ctx) + if err != nil { + return xerrors.Errorf("failed to get chain head: %w", err) + } + fromEpoch = int(curTs.Height()) - 1 + } + + if fromEpoch <= 0 { + return xerrors.Errorf("invalid from epoch: %d, must be greater than 0", fromEpoch) + } + + toEpoch := cctx.Int("to") + if toEpoch > fromEpoch { + return xerrors.Errorf("to epoch (%d) must be less than or equal to from epoch (%d)", toEpoch, fromEpoch) + } + + if toEpoch <= 0 { + return xerrors.Errorf("invalid to epoch: %d, must be greater than 0", toEpoch) + } + + backfill := cctx.Bool("backfill") + output := cctx.Bool("output") + + // Results Tracking + var results []IndexValidationJSON + var backfilledEpochs []int + + action := "chainindex validation" + if backfill { + action = "chainindex backfill and validation" + } + + _, _ = fmt.Fprintf(cctx.App.Writer, "starting %s; from epoch: %d; to epoch: %d\n", action, fromEpoch, toEpoch) + + totalEpochs := fromEpoch - toEpoch + 1 + for epoch := fromEpoch; epoch >= toEpoch; epoch-- { + if ctx.Err() != nil { + return ctx.Err() + } + + if (fromEpoch-epoch+1)%2880 == 0 { + progress := float64(fromEpoch-epoch+1) / float64(totalEpochs) * 100 + _, _ = fmt.Fprintf(cctx.App.Writer, "chain index validation progress: %.2f%%\n", progress) + } + + indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) + if err != nil { + return xerrors.Errorf("failed to validate index for epoch %d: %w", epoch, err) + } + + if indexValidateResp == nil { + results = append(results, IndexValidationJSON{ + TipsetKey: types.EmptyTSK, + IndexHeight: uint64(epoch), + IndexMsgCount: 0, + IndexEventsCount: 0, + }) + // this was a null round -> continue + continue + } + + if backfill { + backfilledEpochs = append(backfilledEpochs, epoch) + } + + if output { + results = append(results, IndexValidationJSON{ + TipsetKey: indexValidateResp.TipSetKey, + IndexHeight: indexValidateResp.Height, + IndexMsgCount: indexValidateResp.IndexedMessagesCount, + IndexEventsCount: indexValidateResp.IndexedEventsCount, + }) + } + } + + // Output JSON Results + if output { + if err := outputResults(cctx, results); err != nil { + return xerrors.Errorf("failed to output results: %w", err) + } + } + + // Log Summary + _, _ = fmt.Fprintf(cctx.App.Writer, "validation of chain index from epoch %d to %d completed successfully; backfilled %d missing epochs\n", fromEpoch, toEpoch, len(backfilledEpochs)) + + return nil + }, +} + +// outputResults marshals the results into JSON and outputs them. +func outputResults(cctx *cli.Context, results []IndexValidationJSON) error { + jsonData, err := json.MarshalIndent(results, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal results to JSON: %w", err) + } + _, _ = fmt.Fprintf(cctx.App.Writer, "chain validation was successful for the following epochs: %s\n", string(jsonData)) + return nil +} diff --git a/cmd/lotus-shed/indexes.go b/cmd/lotus-shed/indexes.go index 2abe186542f..7c3e7baf7b1 100644 --- a/cmd/lotus-shed/indexes.go +++ b/cmd/lotus-shed/indexes.go @@ -3,7 +3,6 @@ package main import ( "context" "database/sql" - "encoding/json" "fmt" "math" "path" @@ -52,7 +51,7 @@ var indexesCmd = &cli.Command{ withCategory("txhash", backfillTxHashCmd), withCategory("events", backfillEventsCmd), withCategory("events", inspectEventsCmd), - withCategory("chainindex_validation", validateChainIndexCmd), + withCategory("chainindex", validateChainIndexCmd), }, } @@ -881,178 +880,3 @@ var backfillTxHashCmd = &cli.Command{ return nil }, } - -type IndexValidationJSON struct { - IndexedTipsetKey types.TipSetKey `json:"indexed_tipset_key"` - IndexedHeight uint64 `json:"indexed_height"` - IndexedMsgCount uint64 `json:"indexed_message_count"` - IndexedEventsCount uint64 `json:"indexed_events_count"` -} - -var validateChainIndexCmd = &cli.Command{ - Name: "validate-chainindex ", - Usage: "Validates the chainindex for a range of tipset epochs", - Flags: []cli.Flag{ - &cli.IntFlag{ - Name: "from", - Usage: "The tipset height (epoch) to start backfilling from (0 is head of chain)", - }, - &cli.IntFlag{ - Name: "to", - Usage: "The tipset height (epoch) to end backfilling at", - Required: true, - }, - &cli.BoolFlag{ - Name: "backfill", - Usage: "Backfill missing index entries while validating the chain index. When enabled, the command will perform backfilling for any missing indexes (default: true)", - Value: true, - }, - &cli.BoolFlag{ - Name: "failfast", - Usage: "Failfast when enabled, the validation process will terminate immediately upon encountering the first error (default: true)", - Value: true, - }, - &cli.BoolFlag{ - Name: "output", - Usage: "Output the backfilling results in JSON format", - Value: false, - }, - }, - Action: func(cctx *cli.Context) error { - srv, err := lcli.GetFullNodeServices(cctx) - if err != nil { - return fmt.Errorf("failed to get full node services: %w", err) - } - defer func() { - if closeErr := srv.Close(); closeErr != nil { - log.Errorf("Error closing services: %v", closeErr) - } - }() - - api := srv.FullNodeAPI() - ctx := lcli.ReqContext(cctx) - - fromEpoch := cctx.Int("from") - if fromEpoch == 0 { - curTs, err := api.ChainHead(ctx) - if err != nil { - return err - } - fromEpoch = int(curTs.Height()) - 1 - } else { - fromEpoch = fromEpoch - 1 - } - - if fromEpoch <= 0 { - return fmt.Errorf("invalid from epoch: %d", fromEpoch) - } - - toEpoch := cctx.Int("to") - if toEpoch > fromEpoch { - return fmt.Errorf("to epoch must be less than from epoch") - } - - backfill := cctx.Bool("backfill") - failfast := cctx.Bool("failfast") - output := cctx.Bool("output") - - // Results Tracking - var results []IndexValidationJSON - var backfilledEpochs []int - - log.Infof("Starting %s from epoch: %d to epoch: %d", - func() string { - if backfill { - return "backfill and inspect chainindex" - } - return "inspect chainindex" - }(), - fromEpoch, toEpoch) - - // starting from the FromEpoch-1 and going down to the ToEpoch - // this is because `ChainValidateIndex` fetches the tipset.height()+1, which might not be available in case of chain head - for epoch := fromEpoch; epoch >= toEpoch; epoch-- { - if ctx.Err() != nil { - return ctx.Err() - } - - indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) - if err != nil { - if failfast { - return fmt.Errorf("failed to validate index for epoch %d: %w", epoch, err) - } - log.Warnf("Error validating index for epoch %d: %v", epoch, err) - continue - } - - if !indexValidateResp.TipSetKey.IsEmpty() || indexValidateResp.Height != uint64(epoch) && indexValidateResp.Backfilled == backfill { - errMsg := fmt.Sprintf("epoch %d: invalid index validation response: %+v", epoch, indexValidateResp) - if failfast { - return fmt.Errorf(errMsg) - } - log.Warn(errMsg) - continue - } - - if backfill { - backfilledEpochs = append(backfilledEpochs, epoch) - } - - if output { - results = append(results, IndexValidationJSON{ - IndexedTipsetKey: indexValidateResp.TipSetKey, - IndexedHeight: indexValidateResp.Height, - IndexedMsgCount: indexValidateResp.IndexedMessagesCount, - IndexedEventsCount: indexValidateResp.IndexedEventsCount, - }) - } else { - logEpochResult(epoch, indexValidateResp) - } - } - - // Output JSON Results - if output { - if err := outputResults(results); err != nil { - return err - } - } - - // Log Summary - if backfill { - log.Infof("Backfilled epochs: %v", backfilledEpochs) - } else { - log.Infof("Inspection of chain index from epoch %d to %d completed.", fromEpoch, toEpoch) - } - - return nil - }, -} - -// outputResults marshals the results into JSON and outputs them. -func outputResults(results []IndexValidationJSON) error { - jsonData, err := json.MarshalIndent(results, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal results to JSON: %w", err) - } - fmt.Println(string(jsonData)) - return nil -} - -// logEpochResult logs the result of backfilling for a single epoch. -func logEpochResult(epoch int, indexValidate *types.IndexValidation) { - if indexValidate.Backfilled { - log.Infof("Epoch %d: Backfilled successfully. TipsetKey: %s, TotalMessages: %d, TotalEvents: %d", - epoch, - indexValidate.TipSetKey, - indexValidate.IndexedMessagesCount, - indexValidate.IndexedMessagesCount, - ) - } else { - log.Info("Epoch %d: validated successfully. TipsetKey: %s, TotalMessages: %d, TotalEvents: %d", - epoch, - indexValidate.TipSetKey, - indexValidate.IndexedMessagesCount, - indexValidate.IndexedMessagesCount, - ) - } -} diff --git a/go.mod b/go.mod index d21a5e1e502..18057fa69d3 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,8 @@ replace github.com/filecoin-project/test-vectors => ./extern/test-vectors // pro replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi // provided via a git submodule +replace github.com/kilic/bls12-381 v0.1.1-0.20220929213557-ca162e8a70f4 => github.com/kilic/bls12-381 v0.1.0 // to fix bls signature validation + require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 github.com/BurntSushi/toml v1.3.2 diff --git a/go.sum b/go.sum index 9dcc39b5d3a..69fe0790322 100644 --- a/go.sum +++ b/go.sum @@ -754,8 +754,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kilic/bls12-381 v0.1.1-0.20220929213557-ca162e8a70f4 h1:xWK4TZ4bRL05WQUU/3x6TG1l+IYAqdXpAeSLt/zZJc4= -github.com/kilic/bls12-381 v0.1.1-0.20220929213557-ca162e8a70f4/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8= +github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -1627,6 +1627,7 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/node/impl/full/chain_index.go b/node/impl/full/chain_index.go index 7276d594c61..282b9bc4ea8 100644 --- a/node/impl/full/chain_index.go +++ b/node/impl/full/chain_index.go @@ -32,7 +32,7 @@ type ChainIndexHandler struct { func (ch *ChainIndexHandler) ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) { if ch.indexer == nil { - return nil, errors.New("chain indexer is not initialized") + return nil, errors.New("chain indexer is disabled") } return ch.indexer.ChainValidateIndex(ctx, epoch, backfill) } diff --git a/node/modules/chainindex.go b/node/modules/chainindex.go index c4c0e606880..f90b41e858f 100644 --- a/node/modules/chainindex.go +++ b/node/modules/chainindex.go @@ -99,7 +99,6 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In unlockObserver() return xerrors.Errorf("error while reconciling chain index with chain state: %w", err) } - log.Infof("chain indexer reconciled with chain state; observer will start upates from height: %d", head.Height()) unlockObserver() if err := indexer.Start(); err != nil { @@ -113,10 +112,6 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In func ChainIndexHandler(cfg config.ChainIndexerConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, index.Indexer) (*full.ChainIndexHandler, error) { return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, indexer index.Indexer) (*full.ChainIndexHandler, error) { - if !cfg.EnableIndexer { - return nil, nil - } - return full.NewChainIndexHandler(indexer), nil } } From c18998d1078273c8381bf13e33759f4146cb3299 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Thu, 19 Sep 2024 13:09:08 +0400 Subject: [PATCH 09/61] finish chain index validation and backfill tooling --- build/openrpc/full.json | 6 +- chain/index/api.go | 192 +++++++++----------- chain/index/ddls.go | 1 - chain/index/indexer.go | 1 - chain/types/index.go | 1 + cmd/lotus-shed/chain_index.go | 139 ++++++-------- cmd/lotus-shed/indexes.go | 1 - cmd/lotus-shed/main.go | 1 + documentation/en/api-v1-unstable-methods.md | 3 +- 9 files changed, 153 insertions(+), 192 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 2861eb11dfb..7cbfef87d27 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2066,7 +2066,8 @@ "Height": 42, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, - "Backfilled": true + "Backfilled": true, + "IsNullRound": true } ], "additionalProperties": false, @@ -2086,6 +2087,9 @@ "title": "number", "type": "number" }, + "IsNullRound": { + "type": "boolean" + }, "TipSetKey": { "additionalProperties": false, "type": "object" diff --git a/chain/index/api.go b/chain/index/api.go index 836304c4621..1556b96f1fb 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -3,6 +3,7 @@ package index import ( "context" "database/sql" + "errors" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -12,65 +13,27 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func (si *SqliteIndexer) sanityCheckBackfillEpoch(ctx context.Context, epoch abi.ChainEpoch) error { - // should be less than the max non reverted height in the Index - var maxNonRevertedHeight sql.NullInt64 - err := si.stmts.getMaxNonRevertedHeightStmt.QueryRowContext(ctx).Scan(&maxNonRevertedHeight) - if err != nil && err != sql.ErrNoRows { - return xerrors.Errorf("failed to get max non reverted height: %w", err) - } - // couldn't find any non-reverted entries - if err == sql.ErrNoRows || !maxNonRevertedHeight.Valid { - return nil - } - if epoch >= abi.ChainEpoch(maxNonRevertedHeight.Int64) { - return xerrors.Errorf("failed to validate index at epoch %d; can only validate at or before epoch %d for safety", epoch, maxNonRevertedHeight.Int64-1) - } - - return nil -} - -func (si *SqliteIndexer) validateIsNullRound(ctx context.Context, epoch abi.ChainEpoch) (*types.IndexValidation, error) { - // make sure we do not have ANY non-reverted tipset at this epoch - var isNullRound bool - err := si.stmts.hasNullRoundAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&isNullRound) - if err != nil { - return nil, xerrors.Errorf("failed to check if null round exists at height %d: %w", epoch, err) - } - if !isNullRound { - return nil, xerrors.Errorf("index corruption: height %d should be a null round but is not", epoch) - } - - return nil, nil -} - -func (si *SqliteIndexer) getTipsetCountsAtHeight(ctx context.Context, height abi.ChainEpoch) (revertedCount, nonRevertedCount int, err error) { - err = si.stmts.countTipsetsAtHeightStmt.QueryRowContext(ctx, height).Scan(&revertedCount, &nonRevertedCount) - if err != nil { - if err == sql.ErrNoRows { - // No tipsets found at this height - return 0, 0, nil - } - return 0, 0, xerrors.Errorf("failed to query tipset counts: %w", err) - } - - return revertedCount, nonRevertedCount, nil -} +var ErrChainForked = xerrors.New("chain forked") func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) { + // return an error if the indexer is not started if !si.started { - return nil, xerrors.Errorf("ChainValidateIndex can only be called after the indexer has been started") + return nil, errors.New("ChainValidateIndex called before indexer start") } + // return an error if the indexer is closed if si.isClosed() { - return nil, xerrors.Errorf("ChainValidateIndex can only be called before the indexer has been closed") + return nil, errors.New("ChainValidateIndex called on closed indexer") } + // we need to take a write lock here so that back-filling does not race with real time chain indexing si.writerLk.Lock() defer si.writerLk.Unlock() - if err := si.sanityCheckBackfillEpoch(ctx, epoch); err != nil { - return nil, err + // this API only works for epoch < head because of deferred execution in Filecoin + head := si.cs.GetHeaviestTipSet() + if epoch >= head.Height() { + return nil, xerrors.Errorf("cannot validate index at epoch %d, can only validate at an epoch less than chain head epoch %d", epoch, head.Height()) } var isIndexEmpty bool @@ -82,13 +45,17 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain // fetch the tipset at the given epoch on the canonical chain expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, nil, true) if err != nil { - return nil, xerrors.Errorf("failed to get tipset by height: %w", err) + return nil, xerrors.Errorf("failed to get tipset at height %d: %w", epoch, err) } - // Canonical chain has a null round at the epoch -> return if index is empty otherwise validate - if expectedTs.Height() != epoch { // Canonical chain has a null round at the epoch + // Canonical chain has a null round at the epoch -> return if index is empty otherwise validate that index also + // has a null round at this epoch i.e. it does not have anything indexed at all for this epoch + if expectedTs.Height() != epoch { if isIndexEmpty { - return nil, nil + return &types.IndexValidation{ + Height: uint64(epoch), + IsNullRound: true, + }, nil } // validate the db has a hole here and error if not, we don't attempt to repair because something must be very wrong for this to fail return si.validateIsNullRound(ctx, epoch) @@ -105,8 +72,9 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if err == sql.ErrNoRows { return si.backfillMissingTipset(ctx, expectedTs, backfill) } - return nil, xerrors.Errorf("failed to get tipset counts at height: %w", err) + return nil, xerrors.Errorf("failed to get tipset counts at height %d: %w", epoch, err) } + switch { case revertedCount == 0 && nonRevertedCount == 0: // no tipsets at this epoch in the index, backfill @@ -123,8 +91,9 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain var indexedTsKeyCidBytes []byte err = si.stmts.getNonRevertedTipsetAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&indexedTsKeyCidBytes) if err != nil { - return nil, xerrors.Errorf("failed to get non-reverted tipset at height: %w", err) + return nil, xerrors.Errorf("failed to get non-reverted tipset at height %d: %w", epoch, err) } + indexedTsKeyCid, err := cid.Cast(indexedTsKeyCidBytes) if err != nil { return nil, xerrors.Errorf("failed to cast tipset key cid: %w", err) @@ -134,26 +103,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) } if !indexedTsKeyCid.Equals(expectedTsKeyCid) { - return nil, xerrors.Errorf("index corruption: non-reverted tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) - } - - // index the parent tipset and it's events so we dont need to look forward when validating/backfilling the parent - parentTs, err := si.cs.GetTipSetFromKey(ctx, expectedTs.Parents()) - if err != nil { - return nil, xerrors.Errorf("failed to get parent tipset: %w", err) - } - err = withTx(ctx, si.db, func(tx *sql.Tx) error { - if err := si.indexTipset(ctx, tx, parentTs); err != nil { - return xerrors.Errorf("error indexing parent tipset: %w", err) - } - if err := si.indexEvents(ctx, tx, parentTs, expectedTs); err != nil { - return xerrors.Errorf("error indexing events for tipset at height %d: %w", expectedTs.Height(), err) - } - - return nil - }) - if err != nil { - return nil, xerrors.Errorf("error validating tipset: %w", err) + return nil, xerrors.Errorf("index corruption: indexed tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) } // indexedTsKeyCid and expectedTsKeyCid are the same, so we can use `expectedTs` to fetch the indexed data @@ -163,7 +113,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } if indexedData == nil { - return nil, xerrors.Errorf("invalid indexed data for tipset at height %d", expectedTs.Height()) + return nil, xerrors.Errorf("nil indexed data for tipset at height %d", expectedTs.Height()) } if err = si.verifyIndexedData(ctx, expectedTs, indexedData); err != nil { @@ -178,6 +128,36 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain }, nil } +func (si *SqliteIndexer) validateIsNullRound(ctx context.Context, epoch abi.ChainEpoch) (*types.IndexValidation, error) { + // make sure we do not have tipset(reverted or non-reverted) indexed at this epoch + var isNullRound bool + err := si.stmts.hasNullRoundAtHeightStmt.QueryRowContext(ctx, epoch).Scan(&isNullRound) + if err != nil { + return nil, xerrors.Errorf("failed to check if null round exists at height %d: %w", epoch, err) + } + if !isNullRound { + return nil, xerrors.Errorf("index corruption: height %d should be a null round but is not", epoch) + } + + return &types.IndexValidation{ + Height: uint64(epoch), + IsNullRound: true, + }, nil +} + +func (si *SqliteIndexer) getTipsetCountsAtHeight(ctx context.Context, height abi.ChainEpoch) (revertedCount, nonRevertedCount int, err error) { + err = si.stmts.countTipsetsAtHeightStmt.QueryRowContext(ctx, height).Scan(&revertedCount, &nonRevertedCount) + if err != nil { + if err == sql.ErrNoRows { + // No tipsets found at this height + return 0, 0, nil + } + return 0, 0, xerrors.Errorf("failed to query tipset counts at height %d: %w", height, err) + } + + return revertedCount, nonRevertedCount, nil +} + type indexedTipSetData struct { nonRevertedMessageCount int nonRevertedEventCount int @@ -212,31 +192,17 @@ func (si *SqliteIndexer) getIndexedTipSetData(ctx context.Context, ts *types.Tip func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet, indexedData *indexedTipSetData) (err error) { tsKeyCid, err := ts.Key().Cid() if err != nil { - return xerrors.Errorf("failed to get tipset key cid: %w", err) + return xerrors.Errorf("failed to get tipset key cid at height %d: %w", ts.Height(), err) } - // get the tipset where the messages of `ts` will be executed (deferred execution) - executionTs, err := si.cs.GetTipsetByHeight(ctx, ts.Height()+1, nil, false) + executionTs, err := si.getNextTipset(ctx, ts) if err != nil { - return xerrors.Errorf("failed to get tipset by height: %w", err) - } - - eParentTsKeyCid, err := executionTs.Parents().Cid() - if err != nil { - return xerrors.Errorf("failed to get execution tipset parent key cid: %w", err) - } - - // the parent tipset of the execution tipset should be the same as the indexed tipset (`ts` should be the parent of `executionTs`) - // if that is not the case, it means that the chain forked after we fetched the tipset `ts` from the canonical chain and - // `ts` is no longer part of the canonical chain. Simply return an error here and ask the user to retry. - if !eParentTsKeyCid.Equals(tsKeyCid) { - return xerrors.Errorf("execution tipset parent key mismatch: chainstore has %s, index has %s; please retry your request as this could have been caused by a chain reorg", - eParentTsKeyCid, tsKeyCid) + return xerrors.Errorf("failed to get next tipset for height %d: %w", ts.Height(), err) } executedMsgs, err := si.loadExecutedMessages(ctx, ts, executionTs) if err != nil { - return xerrors.Errorf("failed to load executed messages: %w", err) + return xerrors.Errorf("failed to load executed messages for height %d: %w", ts.Height(), err) } totalEventsCount := 0 @@ -245,22 +211,22 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet } if totalEventsCount != indexedData.nonRevertedEventCount { - return xerrors.Errorf("event count mismatch: chainstore has %d, index has %d", totalEventsCount, indexedData.nonRevertedEventCount) + return xerrors.Errorf("event count mismatch for height %d: chainstore has %d, index has %d", ts.Height(), totalEventsCount, indexedData.nonRevertedEventCount) } totalExecutedMsgCount := len(executedMsgs) if totalExecutedMsgCount != indexedData.nonRevertedMessageCount { - return xerrors.Errorf("message count mismatch: chainstore has %d, index has %d", totalExecutedMsgCount, indexedData.nonRevertedMessageCount) + return xerrors.Errorf("message count mismatch for height %d: chainstore has %d, index has %d", ts.Height(), totalExecutedMsgCount, indexedData.nonRevertedMessageCount) } // if non-reverted events exist which means that tipset `ts` has been executed, there should be 0 reverted events in the DB var hasRevertedEventsInTipset bool err = si.stmts.hasRevertedEventsInTipsetStmt.QueryRowContext(ctx, tsKeyCid.Bytes()).Scan(&hasRevertedEventsInTipset) if err != nil { - return xerrors.Errorf("failed to check if there are reverted events in tipset: %w", err) + return xerrors.Errorf("failed to check if there are reverted events in tipset for height %d: %w", ts.Height(), err) } if hasRevertedEventsInTipset { - return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s", tsKeyCid) + return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s at height %d", tsKeyCid, ts.Height()) } return nil @@ -268,29 +234,38 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.TipSet, backfill bool) (*types.IndexValidation, error) { if !backfill { - return nil, xerrors.Errorf("missing tipset at height %d in the chain index, set backfill to true to backfill", ts.Height()) + return nil, xerrors.Errorf("missing tipset at height %d in the chain index, set backfill flag to true to fix", ts.Height()) } // backfill the tipset in the Index parentTs, err := si.cs.GetTipSetFromKey(ctx, ts.Parents()) if err != nil { - return nil, xerrors.Errorf("failed to get parent tipset: %w", err) + return nil, xerrors.Errorf("failed to get parent tipset at height %d: %w", ts.Height(), err) + } + + executionTs, err := si.getNextTipset(ctx, ts) + if err != nil { + return nil, xerrors.Errorf("failed to get next tipset at height %d: %w", ts.Height(), err) } err = withTx(ctx, si.db, func(tx *sql.Tx) error { + if err := si.indexTipsetWithParentEvents(ctx, tx, ts, executionTs); err != nil { + return xerrors.Errorf("error indexing (ts, executionTs): %w", err) + } + if err := si.indexTipsetWithParentEvents(ctx, tx, parentTs, ts); err != nil { - return xerrors.Errorf("error indexing tipset: %w", err) + return xerrors.Errorf("error indexing (parentTs, ts): %w", err) } return nil }) if err != nil { - return nil, xerrors.Errorf("error applying tipset: %w", err) + return nil, xerrors.Errorf("failed to backfill tipset a: %w", err) } indexedData, err := si.getIndexedTipSetData(ctx, ts) if err != nil { - return nil, xerrors.Errorf("failed to get tipset message and event counts at height %d: %w", ts.Height(), err) + return nil, xerrors.Errorf("failed to get indexed tipset data: %w", err) } return &types.IndexValidation{ @@ -301,3 +276,16 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), }, nil } + +func (si *SqliteIndexer) getNextTipset(ctx context.Context, ts *types.TipSet) (*types.TipSet, error) { + nextEpochTs, err := si.cs.GetTipsetByHeight(ctx, ts.Height()+1, nil, false) + if err != nil { + return nil, xerrors.Errorf("failed to get tipset at height %d: %w", ts.Height()+1, err) + } + + if nextEpochTs.Parents() != ts.Key() { + return nil, xerrors.Errorf("chain forked at height %d; please retry your request; err: %w", ts.Height(), ErrChainForked) + } + + return nextEpochTs, nil +} diff --git a/chain/index/ddls.go b/chain/index/ddls.go index c171b597761..29e7ded4c88 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -78,7 +78,6 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.getMsgIdForMsgCidAndTipsetStmt: "SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND message_cid = ? AND reverted = 0", &ps.insertEventStmt: "INSERT INTO event (message_id, event_index, emitter_addr, reverted) VALUES (?, ?, ?, ?) ON CONFLICT (message_id, event_index) DO UPDATE SET reverted = 0", &ps.insertEventEntryStmt: "INSERT INTO event_entry (event_id, indexed, flags, key, codec, value) VALUES (?, ?, ?, ?, ?, ?)", - &ps.getMaxNonRevertedHeightStmt: "SELECT MAX(height) FROM tipset_message WHERE reverted = 0", &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0 LIMIT 1", &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", diff --git a/chain/index/indexer.go b/chain/index/indexer.go index f5571a5e06c..bb8a0516801 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -44,7 +44,6 @@ type preparedStatements struct { insertEventStmt *sql.Stmt insertEventEntryStmt *sql.Stmt - getMaxNonRevertedHeightStmt *sql.Stmt hasNullRoundAtHeightStmt *sql.Stmt getNonRevertedTipsetAtHeightStmt *sql.Stmt countTipsetsAtHeightStmt *sql.Stmt diff --git a/chain/types/index.go b/chain/types/index.go index a9e23389289..713297bec46 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -7,4 +7,5 @@ type IndexValidation struct { IndexedMessagesCount uint64 IndexedEventsCount uint64 Backfilled bool + IsNullRound bool } diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 9291c85cdbd..8b1846c696e 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -3,47 +3,50 @@ package main import ( "encoding/json" "fmt" + "strings" - "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/chain/types" - lcli "github.com/filecoin-project/lotus/cli" "github.com/urfave/cli/v2" "golang.org/x/xerrors" + + "github.com/filecoin-project/go-state-types/abi" + + lcli "github.com/filecoin-project/lotus/cli" ) -type IndexValidationJSON struct { - TipsetKey types.TipSetKey `json:"tipset_key"` - IndexHeight uint64 `json:"index_height"` - IndexMsgCount uint64 `json:"index_msg_count"` - IndexEventsCount uint64 `json:"index_events_count"` +var chainIndexCmds = &cli.Command{ + Name: "chainindex", + Usage: "Commands related to managing the chainindex", + HideHelpCommand: true, + Subcommands: []*cli.Command{ + withCategory("chainindex", validateBackfillChainIndexCmd), + }, } -var validateChainIndexCmd = &cli.Command{ - Name: "validate-chainindex", - Usage: "Validates the chainindex for a range of epochs", +var validateBackfillChainIndexCmd = &cli.Command{ + Name: "validate-backfill", + Usage: "Validates and optionally backfills the chainindex for a range of epochs", Description: ` - validate-chainindex is a command-line tool that validates the chainindex for a specified range of epochs. - It fetches the chain index entry for each epoch, checks for missing entries, and optionally backfills them. - The command provides options to specify the range of epochs, control backfilling, and handle validation errors. + './lotus-shed chainindex validate-backfill' is a command-line tool that validates the chainindex for a specified range of epochs. + It validates the chain index entries for each epoch, checks for missing entries, and optionally backfills them. Usage: - lotus-shed validate-chainindex --from 200 --to 100 --backfill --output + lotus-shed chainindex validate-backfill --from 200 --to 100 --backfill --log-good Flags: - --from Starting tipset epoch for validation (required) - --to Ending tipset epoch for validation (required) + --from Starting tipset epoch for validation (inclusive) (required) + --to Ending tipset epoch for validation (inclusive) (required) --backfill Backfill missing index entries (default: true) - --output Output backfilling results in JSON format (default: false) + --log-good Log tipsets that have no detected problems (default: false) `, Flags: []cli.Flag{ &cli.IntFlag{ Name: "from", - Usage: "from specifies the starting tipset epoch for validation. If set to 0, validation starts from the tipset just before the current head", + Usage: "from specifies the starting tipset epoch for validation (inclusive)", Required: true, }, &cli.IntFlag{ Name: "to", - Usage: "to specifies the ending tipset epoch for validation", + Usage: "to specifies the ending tipset epoch for validation (inclusive)", Required: true, }, &cli.BoolFlag{ @@ -52,9 +55,9 @@ var validateChainIndexCmd = &cli.Command{ Value: true, }, &cli.BoolFlag{ - Name: "output", - Usage: "output specifies whether to output the backfilling results in JSON format (default: true)", - Value: true, + Name: "log-good", + Usage: "log tipsets that have no detected problems", + Value: false, }, }, Action: func(cctx *cli.Context) error { @@ -64,7 +67,7 @@ var validateChainIndexCmd = &cli.Command{ } defer func() { if closeErr := srv.Close(); closeErr != nil { - log.Errorf("error closing services: %v", closeErr) + log.Errorf("error closing services: %w", closeErr) } }() @@ -72,40 +75,25 @@ var validateChainIndexCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) fromEpoch := cctx.Int("from") - if fromEpoch == 0 { - curTs, err := api.ChainHead(ctx) - if err != nil { - return xerrors.Errorf("failed to get chain head: %w", err) - } - fromEpoch = int(curTs.Height()) - 1 - } - if fromEpoch <= 0 { return xerrors.Errorf("invalid from epoch: %d, must be greater than 0", fromEpoch) } toEpoch := cctx.Int("to") - if toEpoch > fromEpoch { - return xerrors.Errorf("to epoch (%d) must be less than or equal to from epoch (%d)", toEpoch, fromEpoch) - } - if toEpoch <= 0 { return xerrors.Errorf("invalid to epoch: %d, must be greater than 0", toEpoch) } + if toEpoch > fromEpoch { + return xerrors.Errorf("to epoch (%d) must be less than or equal to from epoch (%d)", toEpoch, fromEpoch) + } backfill := cctx.Bool("backfill") - output := cctx.Bool("output") // Results Tracking - var results []IndexValidationJSON - var backfilledEpochs []int - - action := "chainindex validation" - if backfill { - action = "chainindex backfill and validation" - } + logGood := cctx.Bool("log-good") - _, _ = fmt.Fprintf(cctx.App.Writer, "starting %s; from epoch: %d; to epoch: %d\n", action, fromEpoch, toEpoch) + _, _ = fmt.Fprintf(cctx.App.Writer, "starting chainindex validation; from epoch: %d; to epoch: %d; backfill: %t; log-good: %t\n", fromEpoch, toEpoch, + backfill, logGood) totalEpochs := fromEpoch - toEpoch + 1 for epoch := fromEpoch; epoch >= toEpoch; epoch-- { @@ -115,59 +103,40 @@ var validateChainIndexCmd = &cli.Command{ if (fromEpoch-epoch+1)%2880 == 0 { progress := float64(fromEpoch-epoch+1) / float64(totalEpochs) * 100 - _, _ = fmt.Fprintf(cctx.App.Writer, "chain index validation progress: %.2f%%\n", progress) + log.Infof("-------- chain index validation progress: %.2f%%\n", progress) } indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) if err != nil { - return xerrors.Errorf("failed to validate index for epoch %d: %w", epoch, err) + // is it a retryable error ? + if strings.Contains(err.Error(), "retry") { + log.Warnf("epoch %d; failed to validate index with re-tryable error: %s. retrying...", epoch, err) + epoch++ // Increment epoch to retry the same epoch + continue + } + + _, _ = fmt.Fprintf(cctx.App.Writer, "✗ Epoch %d; failure: %s\n", epoch, err) } - if indexValidateResp == nil { - results = append(results, IndexValidationJSON{ - TipsetKey: types.EmptyTSK, - IndexHeight: uint64(epoch), - IndexMsgCount: 0, - IndexEventsCount: 0, - }) - // this was a null round -> continue + // is it a null round ? + if indexValidateResp.IsNullRound { + if logGood { + _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d; null round\n", epoch) + } continue } - if backfill { - backfilledEpochs = append(backfilledEpochs, epoch) - } - - if output { - results = append(results, IndexValidationJSON{ - TipsetKey: indexValidateResp.TipSetKey, - IndexHeight: indexValidateResp.Height, - IndexMsgCount: indexValidateResp.IndexedMessagesCount, - IndexEventsCount: indexValidateResp.IndexedEventsCount, - }) - } - } + // log success + if logGood { + jsonData, err := json.Marshal(indexValidateResp) + if err != nil { + return fmt.Errorf("failed to marshal results to JSON: %w", err) + } - // Output JSON Results - if output { - if err := outputResults(cctx, results); err != nil { - return xerrors.Errorf("failed to output results: %w", err) + _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d (%s)\n", epoch, string(jsonData)) } } - // Log Summary - _, _ = fmt.Fprintf(cctx.App.Writer, "validation of chain index from epoch %d to %d completed successfully; backfilled %d missing epochs\n", fromEpoch, toEpoch, len(backfilledEpochs)) - return nil }, } - -// outputResults marshals the results into JSON and outputs them. -func outputResults(cctx *cli.Context, results []IndexValidationJSON) error { - jsonData, err := json.MarshalIndent(results, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal results to JSON: %w", err) - } - _, _ = fmt.Fprintf(cctx.App.Writer, "chain validation was successful for the following epochs: %s\n", string(jsonData)) - return nil -} diff --git a/cmd/lotus-shed/indexes.go b/cmd/lotus-shed/indexes.go index 7c3e7baf7b1..07c934d5162 100644 --- a/cmd/lotus-shed/indexes.go +++ b/cmd/lotus-shed/indexes.go @@ -51,7 +51,6 @@ var indexesCmd = &cli.Command{ withCategory("txhash", backfillTxHashCmd), withCategory("events", backfillEventsCmd), withCategory("events", inspectEventsCmd), - withCategory("chainindex", validateChainIndexCmd), }, } diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 911da346e97..704a777a9ff 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -87,6 +87,7 @@ func main() { gasTraceCmd, replayOfflineCmd, indexesCmd, + chainIndexCmds, FevmAnalyticsCmd, mismatchesCmd, blockCmd, diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 3cd904d03de..3ac41f9eb14 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1261,7 +1261,8 @@ Response: "Height": 42, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, - "Backfilled": true + "Backfilled": true, + "IsNullRound": true } ``` From 67f81a95287e55019822ca3dfe985c0d0bbcd83a Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 23 Sep 2024 13:05:32 +0400 Subject: [PATCH 10/61] user documentation for the --- chain/index/README.MD | 188 ++++++++++++++++++++++++++++++++++ cmd/lotus-shed/chain_index.go | 21 ++-- 2 files changed, 194 insertions(+), 15 deletions(-) create mode 100644 chain/index/README.MD diff --git a/chain/index/README.MD b/chain/index/README.MD new file mode 100644 index 00000000000..710da28d4ee --- /dev/null +++ b/chain/index/README.MD @@ -0,0 +1,188 @@ +# ChainIndexer Documentation for RPC Providers + +## Introduction + +We're shipping a new Indexer implementation in Lotus (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for reliable and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which suffer from a multitude of known problems documented [here](https://github.com/filecoin-project/lotus/issues/12293). + +**Note: If you are a Storage Provider or node operator who does not serve RPC requests, you can skip this document as the `ChainIndexer` is already disabled by default**. + +This document is aimed at RPC providers and node operators who serve RPC requests and aims to walk through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. + +## ChainIndexer Config + +The `ChainIndexer` must be enabled on an RPC node as it is disabled by default. Here is the mandatory config to use for all RPC providers to enable the `ChainIndexer` and for ensuring the `EthRPC` and `ActorEventsAPI` are enabled: + +```toml +[ChainIndexer] +# This is set to false by default which disables the ChainIndexer. +# Please ensure that you set it to true before starting your node. + EnableIndexer = true + +[Fevm] +# This is set to false by default which disables the ETH RPC API. +# Please ensure that you set it to true before starting your node. + EnableEthRPC = true + +[Events] +# This is set to false by default which disables the Actor Events API. +# Please ensure that you set it to true before starting your node. + EnableActorEventsAPI = true +``` + +### Garbage Collection + +The `ChainIndexer` includes a garbage collection (GC) mechanism to manage the amount of historical data retained. By default, GC is disabled to preserve all indexed data. + +#### Configuration + +To configure GC, use the `GCRetentionEpochs` parameter in the `ChainIndexer` section of your config. + +The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. + +```toml +[ChainIndexer] + GCRetentionEpochs = X # Replace X with your desired value +``` + +- Setting `GCRetentionEpochs` to 0 (**this is the default**) completely disables GC. +- Any non-zero value enables GC and determines the number of epochs of historical data to retain. + +#### Recommendations + +1. **Archival Nodes**: **Keep GC disabled** (`GCRetentionEpochs` = 0) to retain all indexed data. + +2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains +(*for example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to (number of Filecoin epochs in a day *2) = 5760). + +--- + +**Note: The following config options no longer exist in Lotus and have been removed in favor of the `ChainIndexer` config options explained above:** + +```toml +[Fevm] +EthTxHashMappingLifetimeDays = 0 + +[Events] +DisableHistoricFilterAPI = false +DatabasePath = "" +``` + +These options are now deprecated and will not have any effect if used in your configuration file. Please use the `ChainIndexer` config options as described above. + +--- + +## Migration Guide + +Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition. Here's a guide to help you through the process: + +1. **Backup Existing Index Databases** + - Before restarting your Lotus node, create a backup of your existing index databases. + - These files are located in the `{$LOTUS_PATH/sqlite}` directory. + - While not used in the migration process, these backups are crucial for potential rollbacks. + +2. **Remove Old Index Files** + - After creating backups, remove the SQLite database files for `MsgIndex`, `EthTxIndex`, and `EventIndex` from the `{$LOTUS_PATH/sqlite}` directory. + +3. **Update Configuration** + - Modify your Lotus configuration to enable the `ChainIndexer` as described in the `ChainIndexer Config` section above. + +4. **Restart Lotus Node** + - Restart your Lotus node with the new configuration. + - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. + +Once Lotus starts with the `ChainIndexer` enabled, it will begin indexing real-time chain state changes i.e. new incoming tipsets. However, it will not index any historical chain state i.e. any previously existing chain state. To index historical chain state (aka **"backfilling"**), you can use the following tools that we're shipping with the `ChainIndexer`: + +### The `ChainValidateIndex` JSON RPC API + +The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does have data for the specified epoch. + +```go +// IndexValidation contains detailed information about the validation status of a specific chain epoch. +type IndexValidation struct { + // TipSetKey is the key of the canonical tipset for this epoch. + TipSetKey TipSetKey + // Height is the epoch height at which the validation is performed. + Height uint64 + // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. + IndexedMessagesCount uint64 + // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. + IndexedEventsCount uint64 + // Backfilled denotes whether missing data was successfully backfilled during validation. + Backfilled bool + // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. + IsNullRound bool +} + +// ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. +// +// Parameters: +// - epoch: The specific chain epoch for which to validate/backfill the index. +// - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the +// specified epoch. +// +// Returns: +// - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. +// - error: An error object if the validation/backfill fails. The error message will contain details about the index +// corruption if the call fails because of an incosistency between indexed data and the actual chain state. +// +// Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. +func ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) +``` + +The `ChainValidateIndex` API serves multiple purposes: + +1. Validates the chain index at a specific epoch: + - Ensures consistency between indexed data and actual chain state + - Reports any errors found during validation + +2. Optionally backfills missing data: + - Backfills data if the index is missing information for the specified epoch + - Backfilling only occurs when the `backfill` parameter is set to `true` + +3. Detects "holes" in the index: + - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data + +This API is available for use once the Lotus daemon has started with the `ChainIndexer` enabled. However, calling the API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. + +To simplify this process, we're also providing a command-line tool in `lotus-shed`. + +### The `lotus-shed chainindex validate-backfill` command-line tool + +**Note: This command can only be run when the Lotus daemon is already running with the `ChainIndexer` enabled as it depends on the `ChainValidateIndex` RPC API described above.** + +The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. + +#### Usage: +``` +lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] +``` + +#### Parameters: +- `--from` (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. +- `--to` (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to `from`. +- `--backfill` (optional, default: true): Whether to backfill missing index entries during validation. +- `--log-good` (optional, default: false): Whether to log details for tipsets that have no detected problems. + +The command validates the chain index entries for each epoch in the specified range, checking for missing or inconsistent entries. If `--backfill` is enabled (which it is by default), it will attempt to backfill any missing entries using the `ChainValidateIndex` API. + +#### Error conditions: +- If `from` or `to` are invalid (<=0 or `to` > `from`), an error is returned. +- If the `ChainValidateIndex` API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. + +#### Logging: +- **Progress is logged every 2880 epochs (1 day worth of epochs) during the validation process.** +- If `--log-good` is enabled, details are also logged for each epoch that has no detected problems. This includes: + - Null rounds with no messages/events. + - Epochs with a valid indexed entry. + +#### Example usage: + +To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: + +``` +lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good +``` + +This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity.** + +Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on Lotus [GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 8b1846c696e..2cacec92ab2 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -3,7 +3,6 @@ package main import ( "encoding/json" "fmt" - "strings" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -108,26 +107,18 @@ var validateBackfillChainIndexCmd = &cli.Command{ indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) if err != nil { - // is it a retryable error ? - if strings.Contains(err.Error(), "retry") { - log.Warnf("epoch %d; failed to validate index with re-tryable error: %s. retrying...", epoch, err) - epoch++ // Increment epoch to retry the same epoch - continue - } - _, _ = fmt.Fprintf(cctx.App.Writer, "✗ Epoch %d; failure: %s\n", epoch, err) + continue } - // is it a null round ? - if indexValidateResp.IsNullRound { - if logGood { - _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d; null round\n", epoch) - } + if !logGood { continue } - // log success - if logGood { + // is it a null round ? + if indexValidateResp.IsNullRound { + _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d; null round\n", epoch) + } else { jsonData, err := json.Marshal(indexValidateResp) if err != nil { return fmt.Errorf("failed to marshal results to JSON: %w", err) From a84b38e4d4dc79c82ffde75e7cf1d0a2a6c7c0eb Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 23 Sep 2024 13:17:42 +0400 Subject: [PATCH 11/61] validate from epoch --- cmd/lotus-shed/chain_index.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 2cacec92ab2..3bde0a53968 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -86,6 +86,14 @@ var validateBackfillChainIndexCmd = &cli.Command{ return xerrors.Errorf("to epoch (%d) must be less than or equal to from epoch (%d)", toEpoch, fromEpoch) } + head, err := api.ChainHead(ctx) + if err != nil { + return xerrors.Errorf("failed to get chain head: %w", err) + } + if head.Height() <= abi.ChainEpoch(fromEpoch) { + return xerrors.Errorf("from epoch (%d) must be less than chain head (%d)", fromEpoch, head.Height()) + } + backfill := cctx.Bool("backfill") // Results Tracking From 24527bdbd8ae976714ecbf243cdc0a50f5af86f2 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Tue, 24 Sep 2024 11:25:35 +0400 Subject: [PATCH 12/61] Apply suggestions from code review Suggestions from Steve's read of the user doc. Co-authored-by: Steve Loeppky --- chain/index/README.MD | 48 ++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/chain/index/README.MD b/chain/index/README.MD index 710da28d4ee..56304544cc0 100644 --- a/chain/index/README.MD +++ b/chain/index/README.MD @@ -9,23 +9,21 @@ We're shipping a new Indexer implementation in Lotus (`ChainIndexer`) to index F This document is aimed at RPC providers and node operators who serve RPC requests and aims to walk through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. ## ChainIndexer Config +### Enablement -The `ChainIndexer` must be enabled on an RPC node as it is disabled by default. Here is the mandatory config to use for all RPC providers to enable the `ChainIndexer` and for ensuring the `EthRPC` and `ActorEventsAPI` are enabled: +The following must be enabled on an RPC node before starting as they are disabled by default: ```toml [ChainIndexer] -# This is set to false by default which disables the ChainIndexer. -# Please ensure that you set it to true before starting your node. +# Enable the ChainIndexer. EnableIndexer = true [Fevm] -# This is set to false by default which disables the ETH RPC API. -# Please ensure that you set it to true before starting your node. +# Enable the ETH RPC APIs. EnableEthRPC = true [Events] -# This is set to false by default which disables the Actor Events API. -# Please ensure that you set it to true before starting your node. +# Enable the Actor Events APIs. EnableActorEventsAPI = true ``` @@ -33,8 +31,6 @@ The `ChainIndexer` must be enabled on an RPC node as it is disabled by default. The `ChainIndexer` includes a garbage collection (GC) mechanism to manage the amount of historical data retained. By default, GC is disabled to preserve all indexed data. -#### Configuration - To configure GC, use the `GCRetentionEpochs` parameter in the `ChainIndexer` section of your config. The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. @@ -44,8 +40,8 @@ The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes GCRetentionEpochs = X # Replace X with your desired value ``` -- Setting `GCRetentionEpochs` to 0 (**this is the default**) completely disables GC. -- Any non-zero value enables GC and determines the number of epochs of historical data to retain. +- Setting `GCRetentionEpochs` to 0 (**default**) disables GC. +- Any positive value enables GC and determines the number of epochs of historical data to retain. #### Recommendations @@ -54,7 +50,7 @@ The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes 2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains (*for example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to (number of Filecoin epochs in a day *2) = 5760). ---- +### Removed Options **Note: The following config options no longer exist in Lotus and have been removed in favor of the `ChainIndexer` config options explained above:** @@ -67,13 +63,10 @@ DisableHistoricFilterAPI = false DatabasePath = "" ``` -These options are now deprecated and will not have any effect if used in your configuration file. Please use the `ChainIndexer` config options as described above. - ---- ## Migration Guide -Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition. Here's a guide to help you through the process: +Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition: 1. **Backup Existing Index Databases** - Before restarting your Lotus node, create a backup of your existing index databases. @@ -84,15 +77,16 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr - After creating backups, remove the SQLite database files for `MsgIndex`, `EthTxIndex`, and `EventIndex` from the `{$LOTUS_PATH/sqlite}` directory. 3. **Update Configuration** - - Modify your Lotus configuration to enable the `ChainIndexer` as described in the `ChainIndexer Config` section above. + - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config] . 4. **Restart Lotus Node** - Restart your Lotus node with the new configuration. - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. -Once Lotus starts with the `ChainIndexer` enabled, it will begin indexing real-time chain state changes i.e. new incoming tipsets. However, it will not index any historical chain state i.e. any previously existing chain state. To index historical chain state (aka **"backfilling"**), you can use the following tools that we're shipping with the `ChainIndexer`: +### Backfilling +Once Lotus starts with the `ChainIndexer` enabled, it will begin indexing real-time chain state changes (i.e., new incoming tipsets). However, it will not index any historical chain state (i.e., any previously existing chain state). To index historical chain state (i.e., **"backfilling"**), you can use the following tools. -### The `ChainValidateIndex` JSON RPC API +#### The `ChainValidateIndex` JSON RPC API The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does have data for the specified epoch. @@ -107,7 +101,7 @@ type IndexValidation struct { IndexedMessagesCount uint64 // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. IndexedEventsCount uint64 - // Backfilled denotes whether missing data was successfully backfilled during validation. + // Backfilled denotes whether missing data was successfully backfilled into the index during validation. Backfilled bool // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. IsNullRound bool @@ -142,15 +136,12 @@ The `ChainValidateIndex` API serves multiple purposes: 3. Detects "holes" in the index: - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data -This API is available for use once the Lotus daemon has started with the `ChainIndexer` enabled. However, calling the API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. - -To simplify this process, we're also providing a command-line tool in `lotus-shed`. - -### The `lotus-shed chainindex validate-backfill` command-line tool +The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with [`ChainIndexer` enabled](#link-to-section). -**Note: This command can only be run when the Lotus daemon is already running with the `ChainIndexer` enabled as it depends on the `ChainValidateIndex` RPC API described above.** +#### `lotus-shed chainindex validate-backfill` tool +The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs since calling the API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. -The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. +**Note: This command can only be run when the Lotus daemon is already running with the [`ChainIndexer` enabled](#link-to-appropriate-sectoin) as it depends on the [`ChainValidateIndex` RPC API](#link-to-appropriate-section).** #### Usage: ``` @@ -170,7 +161,7 @@ The command validates the chain index entries for each epoch in the specified ra - If the `ChainValidateIndex` API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. #### Logging: -- **Progress is logged every 2880 epochs (1 day worth of epochs) during the validation process.** +- **Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process.** - If `--log-good` is enabled, details are also logged for each epoch that has no detected problems. This includes: - Null rounds with no messages/events. - Epochs with a valid indexed entry. @@ -185,4 +176,5 @@ lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity.** +## Need more help? Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on Lotus [GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file From ec8da8ab18d270c7ff7d9d545ae58732ccef7717 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 24 Sep 2024 16:20:38 +0400 Subject: [PATCH 13/61] changes to user doc as per review --- CHANGELOG.md | 3 +- api/api_full.go | 45 +++ build/openrpc/full.json | 2 +- chain/index/README.MD | 180 ------------ ...ain-indexing-overview-for-rpc-providers.MD | 258 ++++++++++++++++++ cmd/lotus-shed/chain_index.go | 33 ++- documentation/en/api-v1-unstable-methods.md | 44 ++- 7 files changed, 371 insertions(+), 194 deletions(-) delete mode 100644 chain/index/README.MD create mode 100644 chain/index/chain-indexing-overview-for-rpc-providers.MD diff --git a/CHANGELOG.md b/CHANGELOG.md index f3197464ea5..4eb7bb57d74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Lotus changelog # UNRELEASED - - https://github.com/filecoin-project/lotus/pull/12474: feat: lotus-shed tooling for chain indexer + - We're shipping a new Indexer implementation in Lotus (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for reliable and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which suffer from a multitude of known problems documented [here](https://github.com/filecoin-project/lotus/issues/12293). If you are an RPC provider/node operator who serves RPC requests, please refer to the [ChainIndexer documentation for RPC providers](TODO: URL) on the Lotus docs website for information on how to enable, configure and use the new Indexer. + ## ☢️ Upgrade Warnings ☢️ diff --git a/api/api_full.go b/api/api_full.go index e80f7cad359..7bdbbcfc9a1 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -64,6 +64,51 @@ type FullNode interface { Net // MethodGroup: ChainIndexer + // The ChainIndexer method group contains methods for interacting with the chain indexer. + + // IndexValidation contains detailed information about the validation status of a specific chain epoch. + //type IndexValidation struct { + // // TipSetKey is the key of the canonical tipset for this epoch. + // TipSetKey TipSetKey + // // Height is the epoch height at which the validation is performed. + // Height uint64 + // // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. + // IndexedMessagesCount uint64 + // // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. + // IndexedEventsCount uint64 + // // Backfilled denotes whether missing data was successfully backfilled into the index during validation. + // Backfilled bool + // // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. + // IsNullRound bool + //} + // + // ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. + // + // Parameters: + // - epoch: The specific chain epoch for which to validate/backfill the index. + // - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the + // specified epoch. + // + // Returns: + // - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. + // - error: An error object if the validation/backfill fails. The error message will contain details about the index + // corruption if the call fails because of an incosistency between indexed data and the actual chain state. + // + // Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. + // + // The `ChainValidateIndex` API serves multiple purposes: + // + // 1. Validates the chain index at a specific epoch: + // - Ensures consistency between indexed data and actual chain state + // - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.) + // + // 2. Optionally backfills missing data: + // - Backfills data if the index is missing information for the specified epoch + // - Backfilling only occurs when the `backfill` parameter is set to `true` + // + // 3. Detects "holes" in the index: + // - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data + // ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) //perm:write // MethodGroup: Chain diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 7cbfef87d27..54470f8230e 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2012,7 +2012,7 @@ { "name": "Filecoin.ChainValidateIndex", "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", - "summary": "There are not yet any comments for this method.", + "summary": "IndexValidation contains detailed information about the validation status of a specific chain epoch.\ntype IndexValidation struct {\n\t// TipSetKey is the key of the canonical tipset for this epoch.\n\tTipSetKey TipSetKey\n\t// Height is the epoch height at which the validation is performed.\n\tHeight uint64\n\t// IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch.\n\tIndexedMessagesCount uint64\n\t// IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch.\n\tIndexedEventsCount uint64\n\t// Backfilled denotes whether missing data was successfully backfilled into the index during validation.\n\tBackfilled bool\n\t// IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events.\n\tIsNullRound bool\n}\n\nChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data.\n\nParameters:\n - epoch: The specific chain epoch for which to validate/backfill the index.\n - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the\n specified epoch.\n\nReturns:\n - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill.\n - error: An error object if the validation/backfill fails. The error message will contain details about the index\n corruption if the call fails because of an incosistency between indexed data and the actual chain state.\n\nNote: The API returns an error if the index does not have data for the specified epoch and backfill is set to false.\n\nThe `ChainValidateIndex` API serves multiple purposes:\n\n1. Validates the chain index at a specific epoch:\n - Ensures consistency between indexed data and actual chain state\n - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.)\n\n2. Optionally backfills missing data:\n - Backfills data if the index is missing information for the specified epoch\n - Backfilling only occurs when the `backfill` parameter is set to `true`\n\n3. Detects \"holes\" in the index:\n - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data\n", "paramStructure": "by-position", "params": [ { diff --git a/chain/index/README.MD b/chain/index/README.MD deleted file mode 100644 index 56304544cc0..00000000000 --- a/chain/index/README.MD +++ /dev/null @@ -1,180 +0,0 @@ -# ChainIndexer Documentation for RPC Providers - -## Introduction - -We're shipping a new Indexer implementation in Lotus (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for reliable and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which suffer from a multitude of known problems documented [here](https://github.com/filecoin-project/lotus/issues/12293). - -**Note: If you are a Storage Provider or node operator who does not serve RPC requests, you can skip this document as the `ChainIndexer` is already disabled by default**. - -This document is aimed at RPC providers and node operators who serve RPC requests and aims to walk through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. - -## ChainIndexer Config -### Enablement - -The following must be enabled on an RPC node before starting as they are disabled by default: - -```toml -[ChainIndexer] -# Enable the ChainIndexer. - EnableIndexer = true - -[Fevm] -# Enable the ETH RPC APIs. - EnableEthRPC = true - -[Events] -# Enable the Actor Events APIs. - EnableActorEventsAPI = true -``` - -### Garbage Collection - -The `ChainIndexer` includes a garbage collection (GC) mechanism to manage the amount of historical data retained. By default, GC is disabled to preserve all indexed data. - -To configure GC, use the `GCRetentionEpochs` parameter in the `ChainIndexer` section of your config. - -The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. - -```toml -[ChainIndexer] - GCRetentionEpochs = X # Replace X with your desired value -``` - -- Setting `GCRetentionEpochs` to 0 (**default**) disables GC. -- Any positive value enables GC and determines the number of epochs of historical data to retain. - -#### Recommendations - -1. **Archival Nodes**: **Keep GC disabled** (`GCRetentionEpochs` = 0) to retain all indexed data. - -2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains -(*for example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to (number of Filecoin epochs in a day *2) = 5760). - -### Removed Options - -**Note: The following config options no longer exist in Lotus and have been removed in favor of the `ChainIndexer` config options explained above:** - -```toml -[Fevm] -EthTxHashMappingLifetimeDays = 0 - -[Events] -DisableHistoricFilterAPI = false -DatabasePath = "" -``` - - -## Migration Guide - -Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition: - -1. **Backup Existing Index Databases** - - Before restarting your Lotus node, create a backup of your existing index databases. - - These files are located in the `{$LOTUS_PATH/sqlite}` directory. - - While not used in the migration process, these backups are crucial for potential rollbacks. - -2. **Remove Old Index Files** - - After creating backups, remove the SQLite database files for `MsgIndex`, `EthTxIndex`, and `EventIndex` from the `{$LOTUS_PATH/sqlite}` directory. - -3. **Update Configuration** - - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config] . - -4. **Restart Lotus Node** - - Restart your Lotus node with the new configuration. - - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. - -### Backfilling -Once Lotus starts with the `ChainIndexer` enabled, it will begin indexing real-time chain state changes (i.e., new incoming tipsets). However, it will not index any historical chain state (i.e., any previously existing chain state). To index historical chain state (i.e., **"backfilling"**), you can use the following tools. - -#### The `ChainValidateIndex` JSON RPC API - -The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does have data for the specified epoch. - -```go -// IndexValidation contains detailed information about the validation status of a specific chain epoch. -type IndexValidation struct { - // TipSetKey is the key of the canonical tipset for this epoch. - TipSetKey TipSetKey - // Height is the epoch height at which the validation is performed. - Height uint64 - // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. - IndexedMessagesCount uint64 - // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. - IndexedEventsCount uint64 - // Backfilled denotes whether missing data was successfully backfilled into the index during validation. - Backfilled bool - // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. - IsNullRound bool -} - -// ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. -// -// Parameters: -// - epoch: The specific chain epoch for which to validate/backfill the index. -// - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the -// specified epoch. -// -// Returns: -// - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. -// - error: An error object if the validation/backfill fails. The error message will contain details about the index -// corruption if the call fails because of an incosistency between indexed data and the actual chain state. -// -// Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. -func ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) -``` - -The `ChainValidateIndex` API serves multiple purposes: - -1. Validates the chain index at a specific epoch: - - Ensures consistency between indexed data and actual chain state - - Reports any errors found during validation - -2. Optionally backfills missing data: - - Backfills data if the index is missing information for the specified epoch - - Backfilling only occurs when the `backfill` parameter is set to `true` - -3. Detects "holes" in the index: - - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data - -The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with [`ChainIndexer` enabled](#link-to-section). - -#### `lotus-shed chainindex validate-backfill` tool -The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs since calling the API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. - -**Note: This command can only be run when the Lotus daemon is already running with the [`ChainIndexer` enabled](#link-to-appropriate-sectoin) as it depends on the [`ChainValidateIndex` RPC API](#link-to-appropriate-section).** - -#### Usage: -``` -lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] -``` - -#### Parameters: -- `--from` (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. -- `--to` (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to `from`. -- `--backfill` (optional, default: true): Whether to backfill missing index entries during validation. -- `--log-good` (optional, default: false): Whether to log details for tipsets that have no detected problems. - -The command validates the chain index entries for each epoch in the specified range, checking for missing or inconsistent entries. If `--backfill` is enabled (which it is by default), it will attempt to backfill any missing entries using the `ChainValidateIndex` API. - -#### Error conditions: -- If `from` or `to` are invalid (<=0 or `to` > `from`), an error is returned. -- If the `ChainValidateIndex` API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. - -#### Logging: -- **Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process.** -- If `--log-good` is enabled, details are also logged for each epoch that has no detected problems. This includes: - - Null rounds with no messages/events. - - Epochs with a valid indexed entry. - -#### Example usage: - -To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: - -``` -lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good -``` - -This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity.** - -## Need more help? -Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on Lotus [GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD new file mode 100644 index 00000000000..4a9e0f0500a --- /dev/null +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -0,0 +1,258 @@ +# ChainIndexer Documentation for RPC Providers + +# Table of Contents + +- [ChainIndexer Documentation for RPC Providers](#chainindexer-documentation-for-rpc-providers) + - [Introduction](#introduction) + - [ChainIndexer Config](#chainindexer-config) + - [Enablement](#enablement) + - [Garbage Collection](#garbage-collection) + - [Recommendations](#recommendations) + - [Removed Options](#removed-options) + - [Migration Guide](#migration-guide) + - [Backfilling](#backfilling) + - [The `ChainValidateIndex` JSON RPC API](#the-chainvalidateindex-json-rpc-api) + - [`lotus-shed chainindex validate-backfill` CLI tool](#lotus-shed-chainindex-validate-backfill-cli-tool) + - [Usage](#usage) + - [Parameters](#parameters) + - [Error conditions](#error-conditions) + - [Logging](#logging) + - [Example usage](#example-usage) + - [Rollback](#rollback) + - [Need more help?](#need-more-help) + +## Introduction + +This document is aimed at RPC providers and node operators who serve RPC requests and aims to walk through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. + +**Note: If you are a Storage Provider or node operator who does not serve RPC requests, you can skip this document as the `ChainIndexer` is already disabled by default**. + + +## ChainIndexer Config +### Enablement + +The following must be enabled on an RPC node before starting as they are disabled by default: + +```toml +[ChainIndexer] +# Enable the ChainIndexer. + EnableIndexer = true + +[Fevm] +# Enable the ETH RPC APIs. + EnableEthRPC = true + +[Events] +# Enable the Actor Events APIs. + EnableActorEventsAPI = true +``` + +You can learn more about these configuration options and other configuration options available for the `ChainIndexer` [here](https://github.com/filecoin-project/lotus/blob/master/documentation/en/default-lotus-config.toml). + + +### Garbage Collection + +The `ChainIndexer` includes a garbage collection (GC) mechanism to manage the amount of historical data retained. By default, GC is disabled to preserve all indexed data. + +To configure GC, use the `GCRetentionEpochs` parameter in the `ChainIndexer` section of your config. + +The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. + +```toml +[ChainIndexer] + GCRetentionEpochs = X # Replace X with your desired value +``` + +- Setting `GCRetentionEpochs` to 0 (**default**) disables GC. +- Any positive value enables GC and determines the number of epochs of historical data to retain. + +#### Recommendations + +1. **Archival Nodes**: **Keep GC disabled** (`GCRetentionEpochs` = 0) to retain all indexed data. + +2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains +(*for example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to (number of Filecoin epochs in a day *2) = 5760). + +### Removed Options + +**Note: The following config options no longer exist in Lotus and have been removed in favor of the ChainIndexer config options explained above. They can be removed when upgrading to the Lotus vX.XX.X version.** + +```toml +[Fevm] +EthTxHashMappingLifetimeDays = 0 + +[Events] +DisableHistoricFilterAPI = false +DatabasePath = "" +``` + +## Migration Guide + +Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition: + +1. **Stop the Lotus Node** + - Stop your Lotus node before starting the upgrade and migration process. + +2. **Backup Existing Index Databases** + - Before restarting your Lotus node, back up the directory containing your existing index databases (`MsgIndex`, `EthTxIndex`, and `EventIndex`). + - These databases are located in the `{$LOTUS_PATH/sqlite}` directory. + - Use the following command to copy the entire directory: + ```bash + cp -r $LOTUS_PATH/sqlite {destination_path} + ``` + - **Note: If you have configured a custom directory path for the Index databases using the `Events.DatabasePath` config option, replace `{$LOTUS_PATH/sqlite}` with your custom path.** + - These backups are essential for potential rollbacks, even though they are not used in the migration process. + +3. **Remove Old Index Files** + - After creating backups, remove the `{$LOTUS_PATH/sqlite}` directory (*or your custom index database path*) using the following command: + ```bash + rm -rf $LOTUS_PATH/sqlite + ``` + - **Warning: Please ensure and validate that you have made backups of your existing index databases before removing the directory.** + +4. **Update Configuration** + - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config). + +5. **Restart Lotus Node** + - Restart your Lotus node with the new configuration. + - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. + - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfilling` section below](#backfilling).** + +### Backfilling +To index historical chain state (i.e., **"backfilling"**), you can use the following tools: + +#### The `ChainValidateIndex` JSON RPC API + +Please refer to the [Lotus API documentation](https://github.com/filecoin-project/lotus/blob/master/documentation/en/api-v1-unstable-methods.md) for detailed documentation of the `ChainValidateIndex` JSON RPC API. + +The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does not have data for the specified epoch. + +Here are some examples of how to use the `ChainValidateIndex` JSON RPC API for validating/ backfilling the index: + +``` +1) Validating the index for an epoch that is a NULL round: + + curl -X POST -H "Content-Type: application/json" --data '{ + "jsonrpc": "2.0", + "method": "Filecoin.ChainValidateIndex", + "params": [1954383, false], + "id": 1 +}' http://localhost:1234/rpc/v1 | jq . + +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "TipSetKey": [], + "Height": 1954383, + "IndexedMessagesCount": 0, + "IndexedEventsCount": 0, + "Backfilled": false, + "IsNullRound": true + } +} + +2) Validating the Index for an epoch for which the Indexer has missing data with backfilling disabled: + +curl -X POST -H "Content-Type: application/json" --data '{ + "jsonrpc": "2.0", + "method": "Filecoin.ChainValidateIndex", + "params": [1995103, false], + "id": 1 +}' http://localhost:1234/rpc/v1 | jq . + +{ + "error": { + "code": 1, + "message": "missing tipset at height 1995103 in the chain index, set backfill flag to true to fix" + }, + "id": 1, + "jsonrpc": "2.0" +} + +3) Validating the Index for an epoch for which the Indexer has missing data with backfilling enabled: + +curl -X POST -H "Content-Type: application/json" --data '{ + "jsonrpc": "2.0", + "method": "Filecoin.ChainValidateIndex", + "params": [1995103, true], + "id": 1 +}' http://localhost:1234/rpc/v1 | jq . + +{ + "id": 1, + "jsonrpc": "2.0", + "result": { + "TipSetKey": [ + { + "/": "bafy2bzacebvzbpbdwxsclwyorlzclv6cbsvcbtq34sajow2sn7mnksy3wehew" + }, + { + "/": "bafy2bzacedgei4ve3spkfp3oou5oajwd5cogn7lljsuvoj644fgj3gv7luamu" + }, + { + "/": "bafy2bzacebbpcnjoi46obpaheylyxfy5y2lrtdsyglqw3hx2qg64quip5u76s" + } + ], + "Height": 1995103, + "IndexedMessagesCount": 0, + "IndexedEventsCount": 0, + "Backfilled": true, + "IsNullRound": false + } +} +``` + +The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with `ChainIndexer` [enabled](#enablement). + +#### `lotus-shed chainindex validate-backfill` CLI tool +The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs since calling the `ChainValidateIndex` API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. + +**Note: This command can only be run when the Lotus daemon is already running with the [`ChainIndexer` enabled](#enablement) as it depends on the `ChainValidateIndex` RPC API.** + +#### Usage: +``` +lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] +``` + +The command validates the chain index entries for each epoch in the specified range, checking for missing or inconsistent entries(i.e. the indexed data does not match the actual chain state). If `--backfill` is enabled (which it is by default), it will attempt to backfill any missing entries using the `ChainValidateIndex` API. + +#### Parameters: +- `--from` (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. +- `--to` (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to `from`. +- `--backfill` (optional, default: true): Whether to backfill missing index entries during validation. +- `--log-good` (optional, default: false): Whether to log details for tipsets that have no detected problems. + +#### Error conditions: +- If `from` or `to` are invalid (<=0 or `to` > `from`), an error is returned. +- If the `ChainValidateIndex` API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. + +#### Logging: +- **Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process.** +- If `--log-good` is enabled, details are also logged for each epoch that has no detected problems. This includes: + - Null rounds with no messages/events. + - Epochs with a valid indexed entry. + +#### Example usage: + +To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: + +``` +lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good +``` + +This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity.** + +## Rollback + +In case you need to rollback to the previous indexing system (`EthTxIndex`, `MsgIndex`, and `EventIndex`), follow these steps: + +1. Stop your Lotus node. +2. Remove the current `${LOTUS_PATH}/sqlite` directory and replace it with the backup taken in the "**Backup Existing Index Databases**" section of the [Migration Guide](#migration-guide). +3. Build your Lotus binary for the rollback version which has the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. +4. Ensure that you've set the correct config for the existing `EthTxIndex`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. +5. Restart your Lotus node. +6. Perform backfilling for the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. + +## Need more help? +Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on [Lotus GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 3bde0a53968..015437aeaf5 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -25,17 +25,28 @@ var validateBackfillChainIndexCmd = &cli.Command{ Name: "validate-backfill", Usage: "Validates and optionally backfills the chainindex for a range of epochs", Description: ` - './lotus-shed chainindex validate-backfill' is a command-line tool that validates the chainindex for a specified range of epochs. - It validates the chain index entries for each epoch, checks for missing entries, and optionally backfills them. - - Usage: - lotus-shed chainindex validate-backfill --from 200 --to 100 --backfill --log-good - - Flags: - --from Starting tipset epoch for validation (inclusive) (required) - --to Ending tipset epoch for validation (inclusive) (required) - --backfill Backfill missing index entries (default: true) - --log-good Log tipsets that have no detected problems (default: false) +lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] + +The command validates the chain index entries for each epoch in the specified range, +checking for missing or inconsistent entries (i.e. the indexed data does not match the actual chain state). +If '--backfill' is enabled (which it is by default), it will attempt to backfill any missing entries using +the 'ChainValidateIndex' API. + +Parameters: + - '--from' (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. + - '--to' (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to 'from'. + - '--backfill' (optional, default: true): Whether to backfill missing index entries during validation. + - '--log-good' (optional, default: false): Whether to log details for tipsets that have no detected problems. + +Error conditions: + - If 'from' or 'to' are invalid (<=0 or 'to' > 'from'), an error is returned. + - If the 'ChainValidateIndex' API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. + +Logging: + - Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process. + - If '--log-good' is enabled, details are also logged for each epoch that has no detected problems. This includes: + - Null rounds with no messages/events. + - Epochs with a valid indexed entry. `, Flags: []cli.Flag{ &cli.IntFlag{ diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 3ac41f9eb14..87fd167a956 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1235,7 +1235,49 @@ Inputs: Response: `"0"` ### ChainValidateIndex -There are not yet any comments for this method. +IndexValidation contains detailed information about the validation status of a specific chain epoch. +type IndexValidation struct { + // TipSetKey is the key of the canonical tipset for this epoch. + TipSetKey TipSetKey + // Height is the epoch height at which the validation is performed. + Height uint64 + // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. + IndexedMessagesCount uint64 + // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. + IndexedEventsCount uint64 + // Backfilled denotes whether missing data was successfully backfilled into the index during validation. + Backfilled bool + // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. + IsNullRound bool +} + +ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. + +Parameters: + - epoch: The specific chain epoch for which to validate/backfill the index. + - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the + specified epoch. + +Returns: + - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. + - error: An error object if the validation/backfill fails. The error message will contain details about the index + corruption if the call fails because of an incosistency between indexed data and the actual chain state. + +Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. + +The `ChainValidateIndex` API serves multiple purposes: + +1. Validates the chain index at a specific epoch: + - Ensures consistency between indexed data and actual chain state + - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.) + +2. Optionally backfills missing data: + - Backfills data if the index is missing information for the specified epoch + - Backfilling only occurs when the `backfill` parameter is set to `true` + +3. Detects "holes" in the index: + - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data + Perms: write From 651e7b90b2819b69da7c018db355522047fe106a Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 25 Sep 2024 08:53:17 +0400 Subject: [PATCH 14/61] Apply suggestions from code review Co-authored-by: Steve Loeppky --- ...ain-indexing-overview-for-rpc-providers.MD | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 4a9e0f0500a..734e22c6c00 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -23,7 +23,7 @@ ## Introduction -This document is aimed at RPC providers and node operators who serve RPC requests and aims to walk through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. +This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. **Note: If you are a Storage Provider or node operator who does not serve RPC requests, you can skip this document as the `ChainIndexer` is already disabled by default**. @@ -56,7 +56,7 @@ The `ChainIndexer` includes a garbage collection (GC) mechanism to manage the am To configure GC, use the `GCRetentionEpochs` parameter in the `ChainIndexer` section of your config. -The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. +The ChainIndexer [periodically runs](https://github.com/filecoin-project/lotus/blob/master/chain/index/gc.go#L15) GC if `GCRetentionEpochs` is > 0 and removes indexed data for epochs older than `(current_head_height - GCRetentionEpochs)`. ```toml [ChainIndexer] @@ -71,11 +71,11 @@ The ChainIndexer periodically runs GC if `GCRetentionEpochs` is > 0 and removes 1. **Archival Nodes**: **Keep GC disabled** (`GCRetentionEpochs` = 0) to retain all indexed data. 2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains -(*for example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to (number of Filecoin epochs in a day *2) = 5760). +(*Example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to `retentionDays * epochsPerDay = 2 * 2880 = 5760`.) ### Removed Options -**Note: The following config options no longer exist in Lotus and have been removed in favor of the ChainIndexer config options explained above. They can be removed when upgrading to the Lotus vX.XX.X version.** +**Note: The following config options no longer exist in Lotus and have been removed in favor of the ChainIndexer config options explained above. They can be removed when upgrading to Lotus v1.31.0.** ```toml [Fevm] @@ -94,7 +94,7 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr - Stop your Lotus node before starting the upgrade and migration process. 2. **Backup Existing Index Databases** - - Before restarting your Lotus node, back up the directory containing your existing index databases (`MsgIndex`, `EthTxIndex`, and `EventIndex`). + - Back up the directory containing your existing index databases (`MsgIndex`, `EthTxIndex`, and `EventIndex`). - These databases are located in the `{$LOTUS_PATH/sqlite}` directory. - Use the following command to copy the entire directory: ```bash @@ -121,7 +121,7 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr ### Backfilling To index historical chain state (i.e., **"backfilling"**), you can use the following tools: -#### The `ChainValidateIndex` JSON RPC API +#### `ChainValidateIndex` JSON RPC API Please refer to the [Lotus API documentation](https://github.com/filecoin-project/lotus/blob/master/documentation/en/api-v1-unstable-methods.md) for detailed documentation of the `ChainValidateIndex` JSON RPC API. @@ -129,16 +129,18 @@ The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagno Here are some examples of how to use the `ChainValidateIndex` JSON RPC API for validating/ backfilling the index: -``` + 1) Validating the index for an epoch that is a NULL round: + ```bash curl -X POST -H "Content-Type: application/json" --data '{ "jsonrpc": "2.0", "method": "Filecoin.ChainValidateIndex", "params": [1954383, false], "id": 1 }' http://localhost:1234/rpc/v1 | jq . - +``` +```json { "id": 1, "jsonrpc": "2.0", @@ -151,16 +153,19 @@ Here are some examples of how to use the `ChainValidateIndex` JSON RPC API for v "IsNullRound": true } } +``` 2) Validating the Index for an epoch for which the Indexer has missing data with backfilling disabled: +```bash curl -X POST -H "Content-Type: application/json" --data '{ "jsonrpc": "2.0", "method": "Filecoin.ChainValidateIndex", "params": [1995103, false], "id": 1 }' http://localhost:1234/rpc/v1 | jq . - +``` +```json { "error": { "code": 1, @@ -169,16 +174,19 @@ curl -X POST -H "Content-Type: application/json" --data '{ "id": 1, "jsonrpc": "2.0" } +``` 3) Validating the Index for an epoch for which the Indexer has missing data with backfilling enabled: +```bash curl -X POST -H "Content-Type: application/json" --data '{ "jsonrpc": "2.0", "method": "Filecoin.ChainValidateIndex", "params": [1995103, true], "id": 1 }' http://localhost:1234/rpc/v1 | jq . - +``` +```json { "id": 1, "jsonrpc": "2.0", @@ -233,7 +241,7 @@ The command validates the chain index entries for each epoch in the specified ra - Null rounds with no messages/events. - Epochs with a valid indexed entry. -#### Example usage: +#### Example usage To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: @@ -241,7 +249,7 @@ To validate and backfill the chain index for the last 5760 epochs (2 days) and l lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good ``` -This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity.** +This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity using system schedulers like `cron`.** ## Rollback @@ -252,7 +260,7 @@ In case you need to rollback to the previous indexing system (`EthTxIndex`, `Msg 3. Build your Lotus binary for the rollback version which has the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. 4. Ensure that you've set the correct config for the existing `EthTxIndex`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. 5. Restart your Lotus node. -6. Perform backfilling for the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. +6. Backfill the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. ## Need more help? Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on [Lotus GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file From 149b94431ab12708d48d818fd984e284a51c4a9a Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 25 Sep 2024 09:47:45 +0400 Subject: [PATCH 15/61] changes to user doc as per review --- ...ain-indexing-overview-for-rpc-providers.MD | 68 +++---------------- cmd/lotus-shed/chain_index.go | 23 +++++-- 2 files changed, 28 insertions(+), 63 deletions(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 734e22c6c00..c942d69e878 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -1,26 +1,5 @@ # ChainIndexer Documentation for RPC Providers - -# Table of Contents - -- [ChainIndexer Documentation for RPC Providers](#chainindexer-documentation-for-rpc-providers) - - [Introduction](#introduction) - - [ChainIndexer Config](#chainindexer-config) - - [Enablement](#enablement) - - [Garbage Collection](#garbage-collection) - - [Recommendations](#recommendations) - - [Removed Options](#removed-options) - - [Migration Guide](#migration-guide) - - [Backfilling](#backfilling) - - [The `ChainValidateIndex` JSON RPC API](#the-chainvalidateindex-json-rpc-api) - - [`lotus-shed chainindex validate-backfill` CLI tool](#lotus-shed-chainindex-validate-backfill-cli-tool) - - [Usage](#usage) - - [Parameters](#parameters) - - [Error conditions](#error-conditions) - - [Logging](#logging) - - [Example usage](#example-usage) - - [Rollback](#rollback) - - [Need more help?](#need-more-help) - + ## Introduction This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. @@ -71,7 +50,8 @@ The ChainIndexer [periodically runs](https://github.com/filecoin-project/lotus/b 1. **Archival Nodes**: **Keep GC disabled** (`GCRetentionEpochs` = 0) to retain all indexed data. 2. **Non-Archival Nodes**: Set `GCRetentionEpochs` to match the amount of chain state your node retains -(*Example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to `retentionDays * epochsPerDay = 2 * 2880 = 5760`.) +(*Example:* if your node is configured to retain 2 days of Filecoin chain state with the Splitstore, set `GCRetentionEpochs` to `retentionDays * epochsPerDay = 2 * 2880 = 5760`). +**Warning:** Setting this value below the chain state retention period will degrade RPC performance and reliability because the Index will lack data for epochs still present in the chain state. ### Removed Options @@ -118,15 +98,18 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfilling` section below](#backfilling).** -### Backfilling +## Backfill To index historical chain state (i.e., **"backfilling"**), you can use the following tools: -#### `ChainValidateIndex` JSON RPC API +### `ChainValidateIndex` JSON RPC API Please refer to the [Lotus API documentation](https://github.com/filecoin-project/lotus/blob/master/documentation/en/api-v1-unstable-methods.md) for detailed documentation of the `ChainValidateIndex` JSON RPC API. The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does not have data for the specified epoch. + +The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with `ChainIndexer` [enabled](#enablement). + Here are some examples of how to use the `ChainValidateIndex` JSON RPC API for validating/ backfilling the index: @@ -211,9 +194,7 @@ curl -X POST -H "Content-Type: application/json" --data '{ } ``` -The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with `ChainIndexer` [enabled](#enablement). - -#### `lotus-shed chainindex validate-backfill` CLI tool +### `lotus-shed chainindex validate-backfill` CLI tool The `lotus-shed chainindex validate-backfill` command is a tool for validating and optionally backfilling the chain index over a range of epochs since calling the `ChainValidateIndex` API for a single epoch at a time can be cumbersome, especially when backfilling or validating the index over a range of historical epochs, such as during a migration. It wraps the `ChainValidateIndex` API to efficiently process multiple epochs. **Note: This command can only be run when the Lotus daemon is already running with the [`ChainIndexer` enabled](#enablement) as it depends on the `ChainValidateIndex` RPC API.** @@ -225,31 +206,7 @@ lotus-shed chainindex validate-backfill --from --to [- The command validates the chain index entries for each epoch in the specified range, checking for missing or inconsistent entries(i.e. the indexed data does not match the actual chain state). If `--backfill` is enabled (which it is by default), it will attempt to backfill any missing entries using the `ChainValidateIndex` API. -#### Parameters: -- `--from` (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. -- `--to` (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to `from`. -- `--backfill` (optional, default: true): Whether to backfill missing index entries during validation. -- `--log-good` (optional, default: false): Whether to log details for tipsets that have no detected problems. - -#### Error conditions: -- If `from` or `to` are invalid (<=0 or `to` > `from`), an error is returned. -- If the `ChainValidateIndex` API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. - -#### Logging: -- **Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process.** -- If `--log-good` is enabled, details are also logged for each epoch that has no detected problems. This includes: - - Null rounds with no messages/events. - - Epochs with a valid indexed entry. - -#### Example usage - -To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: - -``` -lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good -``` - -This command is useful for backfilling the chain index over a range of historical epochs during the migration to the new `ChainIndexer`. **It can also be run periodically to validate the index's integrity using system schedulers like `cron`.** +You can learn about how to use the tool with `lotus-shed chainindex validate-backfill -h`. ## Rollback @@ -260,7 +217,4 @@ In case you need to rollback to the previous indexing system (`EthTxIndex`, `Msg 3. Build your Lotus binary for the rollback version which has the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. 4. Ensure that you've set the correct config for the existing `EthTxIndex`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. 5. Restart your Lotus node. -6. Backfill the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. - -## Need more help? -Please free to ask questions on `#fil-lotus-dev` on Filecoin Slack or create issues on [Lotus GitHub](https://github.com/filecoin-project/lotus/issues) for any questions/bugs/comments/concerns. \ No newline at end of file +6. Backfill the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. \ No newline at end of file diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 015437aeaf5..d7b7575ce38 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -27,26 +27,37 @@ var validateBackfillChainIndexCmd = &cli.Command{ Description: ` lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] -The command validates the chain index entries for each epoch in the specified range, -checking for missing or inconsistent entries (i.e. the indexed data does not match the actual chain state). -If '--backfill' is enabled (which it is by default), it will attempt to backfill any missing entries using -the 'ChainValidateIndex' API. +The command validates the chain index entries for each epoch in the specified range, checking for missing or +inconsistent entries (i.e. the indexed data does not match the actual chain state). If '--backfill' is enabled +(which it is by default), it will attempt to backfill any missing entries using the 'ChainValidateIndex' API. Parameters: - '--from' (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. - - '--to' (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to 'from'. + - '--to' (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less + than or equal to 'from'. - '--backfill' (optional, default: true): Whether to backfill missing index entries during validation. - '--log-good' (optional, default: false): Whether to log details for tipsets that have no detected problems. Error conditions: - If 'from' or 'to' are invalid (<=0 or 'to' > 'from'), an error is returned. - - If the 'ChainValidateIndex' API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. + - If the 'ChainValidateIndex' API returns an error for an epoch, indicating an inconsistency between the index + and chain state, an error message is logged for that epoch. Logging: - Progress is logged every 2880 epochs (1 day worth of epochs) processed during the validation process. - If '--log-good' is enabled, details are also logged for each epoch that has no detected problems. This includes: - Null rounds with no messages/events. - Epochs with a valid indexed entry. + +Example usage: + +To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: + +lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good + +This command is useful for backfilling the chain index over a range of historical epochs during the migration to +the new ChainIndexer. It can also be run periodically to validate the index's integrity using system schedulers +like cron. `, Flags: []cli.Flag{ &cli.IntFlag{ From ee6a5a17943f1586f95458aaa8cdf4ad4f38dab2 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 25 Sep 2024 09:49:32 +0400 Subject: [PATCH 16/61] Apply suggestions from code review Co-authored-by: Steve Loeppky --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eb7bb57d74..38595b01b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Lotus changelog # UNRELEASED - - We're shipping a new Indexer implementation in Lotus (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for reliable and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which suffer from a multitude of known problems documented [here](https://github.com/filecoin-project/lotus/issues/12293). If you are an RPC provider/node operator who serves RPC requests, please refer to the [ChainIndexer documentation for RPC providers](TODO: URL) on the Lotus docs website for information on how to enable, configure and use the new Indexer. + (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for accurate and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which[ suffer from a multitude of known problems](https://github.com/filecoin-project/lotus/issues/12293). If you are an RPC provider/node operator , please refer to the [ChainIndexer documentation for RPC providers](TODO: URL) for information on how to enable, configure and use the new Indexer. ## ☢️ Upgrade Warnings ☢️ From c07ca441f55cbad44c7ced54efc89de778cad1f3 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 25 Sep 2024 10:01:17 +0400 Subject: [PATCH 17/61] changes as per review --- api/api_full.go | 42 ++++++-------------- build/openrpc/full.json | 2 +- chain/types/index.go | 16 +++++--- documentation/en/api-v1-unstable-methods.md | 44 +-------------------- 4 files changed, 25 insertions(+), 79 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 7bdbbcfc9a1..365ddac1b96 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -65,36 +65,6 @@ type FullNode interface { // MethodGroup: ChainIndexer // The ChainIndexer method group contains methods for interacting with the chain indexer. - - // IndexValidation contains detailed information about the validation status of a specific chain epoch. - //type IndexValidation struct { - // // TipSetKey is the key of the canonical tipset for this epoch. - // TipSetKey TipSetKey - // // Height is the epoch height at which the validation is performed. - // Height uint64 - // // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. - // IndexedMessagesCount uint64 - // // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. - // IndexedEventsCount uint64 - // // Backfilled denotes whether missing data was successfully backfilled into the index during validation. - // Backfilled bool - // // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. - // IsNullRound bool - //} - // - // ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. - // - // Parameters: - // - epoch: The specific chain epoch for which to validate/backfill the index. - // - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the - // specified epoch. - // - // Returns: - // - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. - // - error: An error object if the validation/backfill fails. The error message will contain details about the index - // corruption if the call fails because of an incosistency between indexed data and the actual chain state. - // - // Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. // // The `ChainValidateIndex` API serves multiple purposes: // @@ -109,6 +79,18 @@ type FullNode interface { // 3. Detects "holes" in the index: // - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data // + // ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. + // + // Parameters: + // - epoch: The specific chain epoch for which to validate/backfill the index. + // - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the + // specified epoch. + // + // Returns: + // - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. + // - error: An error object if the validation/backfill fails. The error message will contain details about the index + // corruption if the call fails because of an incosistency between indexed data and the actual chain state. + // Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. ChainValidateIndex(ctx context.Context, epoch abi.ChainEpoch, backfill bool) (*types.IndexValidation, error) //perm:write // MethodGroup: Chain diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 54470f8230e..7cbfef87d27 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2012,7 +2012,7 @@ { "name": "Filecoin.ChainValidateIndex", "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", - "summary": "IndexValidation contains detailed information about the validation status of a specific chain epoch.\ntype IndexValidation struct {\n\t// TipSetKey is the key of the canonical tipset for this epoch.\n\tTipSetKey TipSetKey\n\t// Height is the epoch height at which the validation is performed.\n\tHeight uint64\n\t// IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch.\n\tIndexedMessagesCount uint64\n\t// IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch.\n\tIndexedEventsCount uint64\n\t// Backfilled denotes whether missing data was successfully backfilled into the index during validation.\n\tBackfilled bool\n\t// IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events.\n\tIsNullRound bool\n}\n\nChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data.\n\nParameters:\n - epoch: The specific chain epoch for which to validate/backfill the index.\n - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the\n specified epoch.\n\nReturns:\n - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill.\n - error: An error object if the validation/backfill fails. The error message will contain details about the index\n corruption if the call fails because of an incosistency between indexed data and the actual chain state.\n\nNote: The API returns an error if the index does not have data for the specified epoch and backfill is set to false.\n\nThe `ChainValidateIndex` API serves multiple purposes:\n\n1. Validates the chain index at a specific epoch:\n - Ensures consistency between indexed data and actual chain state\n - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.)\n\n2. Optionally backfills missing data:\n - Backfills data if the index is missing information for the specified epoch\n - Backfilling only occurs when the `backfill` parameter is set to `true`\n\n3. Detects \"holes\" in the index:\n - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data\n", + "summary": "There are not yet any comments for this method.", "paramStructure": "by-position", "params": [ { diff --git a/chain/types/index.go b/chain/types/index.go index 713297bec46..15d03c26cab 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -1,11 +1,17 @@ package types +// IndexValidation contains detailed information about the validation status of a specific chain epoch. type IndexValidation struct { + // TipSetKey is the key of the canonical tipset for this epoch. TipSetKey TipSetKey - Height uint64 - + // Height is the epoch height at which the validation is performed. + Height uint64 + // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. IndexedMessagesCount uint64 - IndexedEventsCount uint64 - Backfilled bool - IsNullRound bool + // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. + IndexedEventsCount uint64 + // Backfilled denotes whether missing data was successfully backfilled into the index during validation. + Backfilled bool + // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. + IsNullRound bool } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 87fd167a956..3ac41f9eb14 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1235,49 +1235,7 @@ Inputs: Response: `"0"` ### ChainValidateIndex -IndexValidation contains detailed information about the validation status of a specific chain epoch. -type IndexValidation struct { - // TipSetKey is the key of the canonical tipset for this epoch. - TipSetKey TipSetKey - // Height is the epoch height at which the validation is performed. - Height uint64 - // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. - IndexedMessagesCount uint64 - // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. - IndexedEventsCount uint64 - // Backfilled denotes whether missing data was successfully backfilled into the index during validation. - Backfilled bool - // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. - IsNullRound bool -} - -ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. - -Parameters: - - epoch: The specific chain epoch for which to validate/backfill the index. - - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the - specified epoch. - -Returns: - - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. - - error: An error object if the validation/backfill fails. The error message will contain details about the index - corruption if the call fails because of an incosistency between indexed data and the actual chain state. - -Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. - -The `ChainValidateIndex` API serves multiple purposes: - -1. Validates the chain index at a specific epoch: - - Ensures consistency between indexed data and actual chain state - - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.) - -2. Optionally backfills missing data: - - Backfills data if the index is missing information for the specified epoch - - Backfilling only occurs when the `backfill` parameter is set to `true` - -3. Detects "holes" in the index: - - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data - +There are not yet any comments for this method. Perms: write From 4c94b2853da255587ab6120ddd245d64e249bdd3 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 25 Sep 2024 13:29:29 +0530 Subject: [PATCH 18/61] feat: add event entries count in validation API (#12506) * feat: add event entry count in validation API * address comments --- build/openrpc/full.json | 5 ++ chain/index/api.go | 57 +++++++++++++-------- chain/index/ddls.go | 51 +++++++++--------- chain/index/indexer.go | 7 +-- chain/types/index.go | 6 ++- documentation/en/api-v1-unstable-methods.md | 1 + itests/eth_filter_test.go | 5 ++ 7 files changed, 82 insertions(+), 50 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 7cbfef87d27..12328f8f0f2 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2066,6 +2066,7 @@ "Height": 42, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, + "IndexedEventEntriesCount": 42, "Backfilled": true, "IsNullRound": true } @@ -2079,6 +2080,10 @@ "title": "number", "type": "number" }, + "IndexedEventEntriesCount": { + "title": "number", + "type": "number" + }, "IndexedEventsCount": { "title": "number", "type": "number" diff --git a/chain/index/api.go b/chain/index/api.go index 1556b96f1fb..2871010d703 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -121,10 +121,11 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } return &types.IndexValidation{ - TipSetKey: expectedTs.Key(), - Height: uint64(expectedTs.Height()), - IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), - IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), + TipSetKey: expectedTs.Key(), + Height: uint64(expectedTs.Height()), + IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), + IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), + IndexedEventEntriesCount: uint64(indexedData.nonRevertedEventEntriesCount), }, nil } @@ -159,8 +160,9 @@ func (si *SqliteIndexer) getTipsetCountsAtHeight(ctx context.Context, height abi } type indexedTipSetData struct { - nonRevertedMessageCount int - nonRevertedEventCount int + nonRevertedMessageCount int + nonRevertedEventCount int + nonRevertedEventEntriesCount int } // getIndexedTipSetData fetches the indexed tipset data for a tipset @@ -180,6 +182,10 @@ func (si *SqliteIndexer) getIndexedTipSetData(ctx context.Context, ts *types.Tip return xerrors.Errorf("failed to query non reverted event count: %w", err) } + if err = tx.Stmt(si.stmts.getNonRevertedTipsetEventEntriesCountStmt).QueryRowContext(ctx, tsKeyCidBytes).Scan(&data.nonRevertedEventEntriesCount); err != nil { + return xerrors.Errorf("failed to query non reverted event entries count: %w", err) + } + return nil }) @@ -200,14 +206,30 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return xerrors.Errorf("failed to get next tipset for height %d: %w", ts.Height(), err) } + // if non-reverted events exist which means that tipset `ts` has been executed, there should be 0 reverted events in the DB + var hasRevertedEventsInTipset bool + err = si.stmts.hasRevertedEventsInTipsetStmt.QueryRowContext(ctx, tsKeyCid.Bytes()).Scan(&hasRevertedEventsInTipset) + if err != nil { + return xerrors.Errorf("failed to check if there are reverted events in tipset for height %d: %w", ts.Height(), err) + } + if hasRevertedEventsInTipset { + return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s at height %d", tsKeyCid, ts.Height()) + } + executedMsgs, err := si.loadExecutedMessages(ctx, ts, executionTs) if err != nil { return xerrors.Errorf("failed to load executed messages for height %d: %w", ts.Height(), err) } - totalEventsCount := 0 + var ( + totalEventsCount = 0 + totalEventEntriesCount = 0 + ) for _, emsg := range executedMsgs { totalEventsCount += len(emsg.evs) + for _, ev := range emsg.evs { + totalEventEntriesCount += len(ev.Entries) + } } if totalEventsCount != indexedData.nonRevertedEventCount { @@ -219,14 +241,8 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return xerrors.Errorf("message count mismatch for height %d: chainstore has %d, index has %d", ts.Height(), totalExecutedMsgCount, indexedData.nonRevertedMessageCount) } - // if non-reverted events exist which means that tipset `ts` has been executed, there should be 0 reverted events in the DB - var hasRevertedEventsInTipset bool - err = si.stmts.hasRevertedEventsInTipsetStmt.QueryRowContext(ctx, tsKeyCid.Bytes()).Scan(&hasRevertedEventsInTipset) - if err != nil { - return xerrors.Errorf("failed to check if there are reverted events in tipset for height %d: %w", ts.Height(), err) - } - if hasRevertedEventsInTipset { - return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s at height %d", tsKeyCid, ts.Height()) + if indexedData.nonRevertedEventEntriesCount != totalEventEntriesCount { + return xerrors.Errorf("event entries count mismatch for height %d: chainstore has %d, index has %d", ts.Height(), totalEventEntriesCount, indexedData.nonRevertedEventEntriesCount) } return nil @@ -269,11 +285,12 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti } return &types.IndexValidation{ - TipSetKey: ts.Key(), - Height: uint64(ts.Height()), - Backfilled: true, - IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), - IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), + TipSetKey: ts.Key(), + Height: uint64(ts.Height()), + Backfilled: true, + IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), + IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), + IndexedEventEntriesCount: uint64(indexedData.nonRevertedEventEntriesCount), }, nil } diff --git a/chain/index/ddls.go b/chain/index/ddls.go index fd4d7ed482a..5acfb8b87be 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -59,30 +59,31 @@ var ddls = []string{ // the preparedStatements struct. func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { return map[**sql.Stmt]string{ - &ps.getNonRevertedMsgInfoStmt: "SELECT tipset_key_cid, height FROM tipset_message WHERE message_cid = ? AND reverted = 0 LIMIT 1", - &ps.getMsgCidFromEthHashStmt: "SELECT message_cid FROM eth_tx_hash WHERE tx_hash = ? LIMIT 1", - &ps.insertEthTxHashStmt: "INSERT INTO eth_tx_hash (tx_hash, message_cid) VALUES (?, ?) ON CONFLICT (tx_hash) DO UPDATE SET inserted_at = CURRENT_TIMESTAMP", - &ps.insertTipsetMessageStmt: "INSERT INTO tipset_message (tipset_key_cid, height, reverted, message_cid, message_index) VALUES (?, ?, ?, ?, ?) ON CONFLICT (tipset_key_cid, message_cid) DO UPDATE SET reverted = 0", - &ps.hasTipsetStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message WHERE tipset_key_cid = ?)", - &ps.updateTipsetToNonRevertedStmt: "UPDATE tipset_message SET reverted = 0 WHERE tipset_key_cid = ?", - &ps.updateTipsetToRevertedStmt: "UPDATE tipset_message SET reverted = 1 WHERE tipset_key_cid = ?", - &ps.removeTipsetsBeforeHeightStmt: "DELETE FROM tipset_message WHERE height < ?", - &ps.removeEthHashesOlderThanStmt: "DELETE FROM eth_tx_hash WHERE inserted_at < datetime('now', ?)", - &ps.updateTipsetsToRevertedFromHeightStmt: "UPDATE tipset_message SET reverted = 1 WHERE height >= ?", - &ps.updateEventsToRevertedFromHeightStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE height >= ?)", - &ps.isIndexEmptyStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message LIMIT 1)", - &ps.getMinNonRevertedHeightStmt: "SELECT MIN(height) FROM tipset_message WHERE reverted = 0", - &ps.hasNonRevertedTipsetStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", - &ps.updateEventsToRevertedStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", - &ps.updateEventsToNonRevertedStmt: "UPDATE event SET reverted = 0 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", - &ps.getMsgIdForMsgCidAndTipsetStmt: "SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND message_cid = ? AND reverted = 0", - &ps.insertEventStmt: "INSERT INTO event (message_id, event_index, emitter_addr, reverted) VALUES (?, ?, ?, ?) ON CONFLICT (message_id, event_index) DO UPDATE SET reverted = 0", - &ps.insertEventEntryStmt: "INSERT INTO event_entry (event_id, indexed, flags, key, codec, value) VALUES (?, ?, ?, ?, ?, ?)", - &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", - &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0 LIMIT 1", - &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", - &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0 AND message_cid IS NOT NULL", - &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", - &ps.hasRevertedEventsInTipsetStmt: "SELECT EXISTS(SELECT 1 FROM event WHERE reverted = 1 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?))", + &ps.getNonRevertedMsgInfoStmt: "SELECT tipset_key_cid, height FROM tipset_message WHERE message_cid = ? AND reverted = 0 LIMIT 1", + &ps.getMsgCidFromEthHashStmt: "SELECT message_cid FROM eth_tx_hash WHERE tx_hash = ? LIMIT 1", + &ps.insertEthTxHashStmt: "INSERT INTO eth_tx_hash (tx_hash, message_cid) VALUES (?, ?) ON CONFLICT (tx_hash) DO UPDATE SET inserted_at = CURRENT_TIMESTAMP", + &ps.insertTipsetMessageStmt: "INSERT INTO tipset_message (tipset_key_cid, height, reverted, message_cid, message_index) VALUES (?, ?, ?, ?, ?) ON CONFLICT (tipset_key_cid, message_cid) DO UPDATE SET reverted = 0", + &ps.hasTipsetStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message WHERE tipset_key_cid = ?)", + &ps.updateTipsetToNonRevertedStmt: "UPDATE tipset_message SET reverted = 0 WHERE tipset_key_cid = ?", + &ps.updateTipsetToRevertedStmt: "UPDATE tipset_message SET reverted = 1 WHERE tipset_key_cid = ?", + &ps.removeTipsetsBeforeHeightStmt: "DELETE FROM tipset_message WHERE height < ?", + &ps.removeEthHashesOlderThanStmt: "DELETE FROM eth_tx_hash WHERE inserted_at < datetime('now', ?)", + &ps.updateTipsetsToRevertedFromHeightStmt: "UPDATE tipset_message SET reverted = 1 WHERE height >= ?", + &ps.updateEventsToRevertedFromHeightStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE height >= ?)", + &ps.isIndexEmptyStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message LIMIT 1)", + &ps.getMinNonRevertedHeightStmt: "SELECT MIN(height) FROM tipset_message WHERE reverted = 0", + &ps.hasNonRevertedTipsetStmt: "SELECT EXISTS(SELECT 1 FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", + &ps.updateEventsToRevertedStmt: "UPDATE event SET reverted = 1 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", + &ps.updateEventsToNonRevertedStmt: "UPDATE event SET reverted = 0 WHERE message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?)", + &ps.getMsgIdForMsgCidAndTipsetStmt: "SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND message_cid = ? AND reverted = 0", + &ps.insertEventStmt: "INSERT INTO event (message_id, event_index, emitter_addr, reverted) VALUES (?, ?, ?, ?) ON CONFLICT (message_id, event_index) DO UPDATE SET reverted = 0", + &ps.insertEventEntryStmt: "INSERT INTO event_entry (event_id, indexed, flags, key, codec, value) VALUES (?, ?, ?, ?, ?, ?)", + &ps.hasNullRoundAtHeightStmt: "SELECT NOT EXISTS(SELECT 1 FROM tipset_message WHERE height = ?)", + &ps.getNonRevertedTipsetAtHeightStmt: "SELECT tipset_key_cid FROM tipset_message WHERE height = ? AND reverted = 0 LIMIT 1", + &ps.countTipsetsAtHeightStmt: "SELECT COUNT(CASE WHEN reverted = 1 THEN 1 END) AS reverted_count, COUNT(CASE WHEN reverted = 0 THEN 1 END) AS non_reverted_count FROM (SELECT tipset_key_cid, MAX(reverted) AS reverted FROM tipset_message WHERE height = ? GROUP BY tipset_key_cid) AS unique_tipsets", + &ps.getNonRevertedTipsetMessageCountStmt: "SELECT COUNT(*) FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0 AND message_cid IS NOT NULL", + &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", + &ps.hasRevertedEventsInTipsetStmt: "SELECT EXISTS(SELECT 1 FROM event WHERE reverted = 1 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?))", + &ps.getNonRevertedTipsetEventEntriesCountStmt: "SELECT COUNT(ee.event_id) AS entry_count FROM event_entry ee JOIN event e ON ee.event_id = e.event_id JOIN tipset_message tm ON e.message_id = tm.message_id WHERE tm.tipset_key_cid = ? AND tm.reverted = 0", } } diff --git a/chain/index/indexer.go b/chain/index/indexer.go index e3d559d1a0e..3607ce1126e 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -49,9 +49,10 @@ type preparedStatements struct { getNonRevertedTipsetAtHeightStmt *sql.Stmt countTipsetsAtHeightStmt *sql.Stmt - getNonRevertedTipsetMessageCountStmt *sql.Stmt - getNonRevertedTipsetEventCountStmt *sql.Stmt - hasRevertedEventsInTipsetStmt *sql.Stmt + getNonRevertedTipsetMessageCountStmt *sql.Stmt + getNonRevertedTipsetEventCountStmt *sql.Stmt + getNonRevertedTipsetEventEntriesCountStmt *sql.Stmt + hasRevertedEventsInTipsetStmt *sql.Stmt } type SqliteIndexer struct { diff --git a/chain/types/index.go b/chain/types/index.go index 15d03c26cab..c322ae971c0 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -6,10 +6,12 @@ type IndexValidation struct { TipSetKey TipSetKey // Height is the epoch height at which the validation is performed. Height uint64 - // IndexedMessagesCount indicates the number of indexed messages for the canonical tipset at this epoch. + // IndexedMessagesCount is the number of indexed messages for the canonical tipset at this epoch. IndexedMessagesCount uint64 - // IndexedEventsCount signifies the number of indexed events for the canonical tipset at this epoch. + // IndexedEventsCount is the number of indexed events for the canonical tipset at this epoch. IndexedEventsCount uint64 + // IndexedEventEntriesCount is the number of indexed event entries for the canonical tipset at this epoch. + IndexedEventEntriesCount uint64 // Backfilled denotes whether missing data was successfully backfilled into the index during validation. Backfilled bool // IsNullRound indicates if the epoch corresponds to a null round and therefore does not have any indexed messages or events. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 3ac41f9eb14..2eb784ec94a 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1261,6 +1261,7 @@ Response: "Height": 42, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, + "IndexedEventEntriesCount": 42, "Backfilled": true, "IsNullRound": true } diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 430e5ff90fd..5e18e8c0773 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -543,6 +543,7 @@ func TestEthGetLogsBasic(t *testing.T) { totalMessageCount := 0 totalEventCount := 0 + totalEventEntriesCount := 0 messages, err := client.ChainGetMessagesInTipset(ctx, ts.Key()) require.NoError(err) totalMessageCount = len(messages) @@ -555,6 +556,9 @@ func TestEthGetLogsBasic(t *testing.T) { events, err := client.ChainGetEvents(ctx, *receipt.Receipt.EventsRoot) require.NoError(err) totalEventCount += len(events) + for _, event := range events { + totalEventEntriesCount += len(event.Entries) + } } } t.Logf("tipset %d: %d messages, %d events", height, totalMessageCount, totalEventCount) @@ -566,6 +570,7 @@ func TestEthGetLogsBasic(t *testing.T) { require.EqualValues(height, iv.Height) require.EqualValues(totalMessageCount, iv.IndexedMessagesCount) require.EqualValues(totalEventCount, iv.IndexedEventsCount) + require.EqualValues(totalEventEntriesCount, iv.IndexedEventEntriesCount) require.False(iv.Backfilled) } } From 8190b4dbfee9ed649c93158a6df78452e0fac90d Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Wed, 25 Sep 2024 12:10:01 +0400 Subject: [PATCH 19/61] use sqllite defaults (#12504) --- lib/sqlite/sqlite.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/sqlite/sqlite.go b/lib/sqlite/sqlite.go index ffb15a7b17e..96d3b5fa9ba 100644 --- a/lib/sqlite/sqlite.go +++ b/lib/sqlite/sqlite.go @@ -23,12 +23,10 @@ var pragmas = []string{ "PRAGMA synchronous = normal", "PRAGMA temp_store = memory", "PRAGMA mmap_size = 30000000000", - "PRAGMA page_size = 32768", "PRAGMA auto_vacuum = NONE", "PRAGMA automatic_index = OFF", "PRAGMA journal_mode = WAL", - "PRAGMA wal_autocheckpoint = 256", // checkpoint @ 256 pages - "PRAGMA journal_size_limit = 0", // always reset journal and wal files + "PRAGMA journal_size_limit = 0", // always reset journal and wal files "PRAGMA foreign_keys = ON", } From 4e3aa889466601eaef2c75bad310ac544f373189 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 30 Sep 2024 16:42:46 +0400 Subject: [PATCH 20/61] Apply suggestions from code review Co-authored-by: Steve Loeppky --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38595b01b47..161f9d14370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Lotus changelog # UNRELEASED - (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for accurate and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus which[ suffer from a multitude of known problems](https://github.com/filecoin-project/lotus/issues/12293). If you are an RPC provider/node operator , please refer to the [ChainIndexer documentation for RPC providers](TODO: URL) for information on how to enable, configure and use the new Indexer. + (`ChainIndexer`) to index Filecoin chain state such as tipsets, messages, events and ETH transactions for accurate and faster RPC responses. The `ChainIndexer` replaces the existing `MsgIndex`, `EthTxIndex` and `EventIndex` implementations in Lotus, which [suffer from a multitude of known problems](https://github.com/filecoin-project/lotus/issues/12293). If you are an RPC provider/node operator, please refer to the [ChainIndexer documentation for RPC providers](TODO: URL) for information on how to enable, configure and use the new Indexer. ## ☢️ Upgrade Warnings ☢️ From 9a13d591bc6ac10095323330b9bb6acbe01a24d8 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 30 Sep 2024 17:49:46 +0400 Subject: [PATCH 21/61] write chain index to a different dir --- ...ain-indexing-overview-for-rpc-providers.MD | 28 ++++--------------- cmd/lotus/daemon.go | 2 +- node/modules/chainindex.go | 4 +-- node/repo/fsrepo.go | 20 ++++++------- node/repo/interface.go | 4 +-- node/repo/memrepo.go | 8 +++--- 6 files changed, 24 insertions(+), 42 deletions(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index c942d69e878..b3a4b37919b 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -72,30 +72,13 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr 1. **Stop the Lotus Node** - Stop your Lotus node before starting the upgrade and migration process. - -2. **Backup Existing Index Databases** - - Back up the directory containing your existing index databases (`MsgIndex`, `EthTxIndex`, and `EventIndex`). - - These databases are located in the `{$LOTUS_PATH/sqlite}` directory. - - Use the following command to copy the entire directory: - ```bash - cp -r $LOTUS_PATH/sqlite {destination_path} - ``` - - **Note: If you have configured a custom directory path for the Index databases using the `Events.DatabasePath` config option, replace `{$LOTUS_PATH/sqlite}` with your custom path.** - - These backups are essential for potential rollbacks, even though they are not used in the migration process. - -3. **Remove Old Index Files** - - After creating backups, remove the `{$LOTUS_PATH/sqlite}` directory (*or your custom index database path*) using the following command: - ```bash - rm -rf $LOTUS_PATH/sqlite - ``` - - **Warning: Please ensure and validate that you have made backups of your existing index databases before removing the directory.** - -4. **Update Configuration** + - +2. **Update Configuration** - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config). -5. **Restart Lotus Node** +3. **Restart Lotus Node** - Restart your Lotus node with the new configuration. - - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately. + - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfilling` section below](#backfilling).** ## Backfill @@ -213,8 +196,7 @@ You can learn about how to use the tool with `lotus-shed chainindex validate-bac In case you need to rollback to the previous indexing system (`EthTxIndex`, `MsgIndex`, and `EventIndex`), follow these steps: 1. Stop your Lotus node. -2. Remove the current `${LOTUS_PATH}/sqlite` directory and replace it with the backup taken in the "**Backup Existing Index Databases**" section of the [Migration Guide](#migration-guide). -3. Build your Lotus binary for the rollback version which has the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. +2. Build your Lotus binary for the rollback version which has the implementation of the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. 4. Ensure that you've set the correct config for the existing `EthTxIndex`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. 5. Restart your Lotus node. 6. Backfill the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. \ No newline at end of file diff --git a/cmd/lotus/daemon.go b/cmd/lotus/daemon.go index 5dcf124c39b..a77a67fd131 100644 --- a/cmd/lotus/daemon.go +++ b/cmd/lotus/daemon.go @@ -644,7 +644,7 @@ func ImportChain(ctx context.Context, r repo.Repo, fname string, snapshot bool) } // populate the chain Index from the snapshot - basePath, err := lr.SqlitePath() + basePath, err := lr.ChainIndexPath() if err != nil { return err } diff --git a/node/modules/chainindex.go b/node/modules/chainindex.go index f90b41e858f..250d82873f8 100644 --- a/node/modules/chainindex.go +++ b/node/modules/chainindex.go @@ -30,13 +30,13 @@ func ChainIndexer(cfg config.ChainIndexerConfig) func(lc fx.Lifecycle, mctx help return nil, nil } - sqlitePath, err := r.SqlitePath() + chainIndexPath, err := r.ChainIndexPath() if err != nil { return nil, err } // TODO Implement config driven auto-backfilling - chainIndexer, err := index.NewSqliteIndexer(filepath.Join(sqlitePath, index.DefaultDbFilename), + chainIndexer, err := index.NewSqliteIndexer(filepath.Join(chainIndexPath, index.DefaultDbFilename), cs, cfg.GCRetentionEpochs, cfg.ReconcileEmptyIndex, cfg.MaxReconcileTipsets) if err != nil { return nil, err diff --git a/node/repo/fsrepo.go b/node/repo/fsrepo.go index 26cbbd6b135..1c2e9f738d4 100644 --- a/node/repo/fsrepo.go +++ b/node/repo/fsrepo.go @@ -37,7 +37,7 @@ const ( fsDatastore = "datastore" fsLock = "repo.lock" fsKeystore = "keystore" - fsSqlite = "sqlite" + fsChainIndex = "chainindex" ) func NewRepoTypeFromString(t string) RepoType { @@ -376,9 +376,9 @@ type fsLockedRepo struct { ssErr error ssOnce sync.Once - sqlPath string - sqlErr error - sqlOnce sync.Once + chainIndexPath string + chainIndexErr error + chainIndexOnce sync.Once storageLk sync.Mutex configLk sync.Mutex @@ -473,19 +473,19 @@ func (fsr *fsLockedRepo) SplitstorePath() (string, error) { return fsr.ssPath, fsr.ssErr } -func (fsr *fsLockedRepo) SqlitePath() (string, error) { - fsr.sqlOnce.Do(func() { - path := fsr.join(fsSqlite) +func (fsr *fsLockedRepo) ChainIndexPath() (string, error) { + fsr.chainIndexOnce.Do(func() { + path := fsr.join(fsChainIndex) if err := os.MkdirAll(path, 0755); err != nil { - fsr.sqlErr = err + fsr.chainIndexErr = err return } - fsr.sqlPath = path + fsr.chainIndexPath = path }) - return fsr.sqlPath, fsr.sqlErr + return fsr.chainIndexPath, fsr.chainIndexErr } // join joins path elements with fsr.path diff --git a/node/repo/interface.go b/node/repo/interface.go index 11c965bf55c..100d0dc58d5 100644 --- a/node/repo/interface.go +++ b/node/repo/interface.go @@ -69,8 +69,8 @@ type LockedRepo interface { // SplitstorePath returns the path for the SplitStore SplitstorePath() (string, error) - // SqlitePath returns the path for the Sqlite database - SqlitePath() (string, error) + // ChainIndexPath returns the path for the chain index database + ChainIndexPath() (string, error) // Returns config in this repo Config() (interface{}, error) diff --git a/node/repo/memrepo.go b/node/repo/memrepo.go index d1e9b214b4a..cda00f985f2 100644 --- a/node/repo/memrepo.go +++ b/node/repo/memrepo.go @@ -268,12 +268,12 @@ func (lmem *lockedMemRepo) SplitstorePath() (string, error) { return splitstorePath, nil } -func (lmem *lockedMemRepo) SqlitePath() (string, error) { - sqlitePath := filepath.Join(lmem.Path(), "sqlite") - if err := os.MkdirAll(sqlitePath, 0755); err != nil { +func (lmem *lockedMemRepo) ChainIndexPath() (string, error) { + chainIndexPath := filepath.Join(lmem.Path(), "chainindex") + if err := os.MkdirAll(chainIndexPath, 0755); err != nil { return "", err } - return sqlitePath, nil + return chainIndexPath, nil } func (lmem *lockedMemRepo) ListDatastores(ns string) ([]int64, error) { From bca9ed0e659fe05c17faa2ad60501e5fd149a2ea Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Tue, 1 Oct 2024 10:48:26 +0400 Subject: [PATCH 22/61] Apply suggestions from code review Co-authored-by: Steve Loeppky --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index b3a4b37919b..e7af402a37e 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -72,7 +72,6 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr 1. **Stop the Lotus Node** - Stop your Lotus node before starting the upgrade and migration process. - - 2. **Update Configuration** - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config). @@ -81,6 +80,7 @@ Migrating to the new `ChainIndexer` involves several steps to ensure a smooth tr - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfilling` section below](#backfilling).** +Note: The ChainIndexer will write state to `${LOTUS_HOME}/chainindex` rather than the [removed option](#removed-options) for `Events.DatabasePath` (which defaulted to `${LOTUS_HOME}/sqllite`). It's recommended to keep the legacy directory around until you've confirmed you don't need to [rollback](#rollback). ## Backfill To index historical chain state (i.e., **"backfilling"**), you can use the following tools: From 35ccc7d81e03c03d1dcb7cb6d04381922ca6cba3 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 1 Oct 2024 11:08:34 +0400 Subject: [PATCH 23/61] fix conflicts --- build/openrpc/full.json | 566 ++++++++++++++++++++++--------------- build/openrpc/gateway.json | 204 ++++++------- build/openrpc/miner.json | 176 ++++++------ build/openrpc/worker.json | 74 ++--- 4 files changed, 562 insertions(+), 458 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index b0a861ecc33..54ecd4c7efd 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -37,7 +37,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1340" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1342" } }, { @@ -60,7 +60,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1351" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1353" } }, { @@ -103,7 +103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1362" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1364" } }, { @@ -214,7 +214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1384" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1386" } }, { @@ -454,7 +454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1395" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1397" } }, { @@ -685,7 +685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1406" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1408" } }, { @@ -784,7 +784,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1417" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1419" } }, { @@ -816,7 +816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1428" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1430" } }, { @@ -922,7 +922,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1439" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1441" } }, { @@ -1019,7 +1019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1450" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1452" } }, { @@ -1078,7 +1078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1461" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1463" } }, { @@ -1171,7 +1171,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1472" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1474" } }, { @@ -1255,7 +1255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1483" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1485" } }, { @@ -1355,7 +1355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1494" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1496" } }, { @@ -1411,7 +1411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1505" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1507" } }, { @@ -1484,7 +1484,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1516" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1518" } }, { @@ -1557,7 +1557,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1527" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1529" } }, { @@ -1604,7 +1604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1538" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1540" } }, { @@ -1636,7 +1636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1549" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1551" } }, { @@ -1691,7 +1691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1560" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1562" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1582" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1584" } }, { @@ -1780,7 +1780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1593" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1595" } }, { @@ -1827,7 +1827,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1604" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1606" } }, { @@ -1874,7 +1874,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1615" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1617" } }, { @@ -1954,7 +1954,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1626" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1628" } }, { @@ -2006,7 +2006,111 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1637" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1639" + } + }, + { + "name": "Filecoin.ChainValidateIndex", + "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", + "summary": "There are not yet any comments for this method.", + "paramStructure": "by-position", + "params": [ + { + "name": "p1", + "description": "abi.ChainEpoch", + "summary": "", + "schema": { + "title": "number", + "description": "Number is a number", + "examples": [ + 10101 + ], + "type": [ + "number" + ] + }, + "required": true, + "deprecated": false + }, + { + "name": "p2", + "description": "bool", + "summary": "", + "schema": { + "examples": [ + true + ], + "type": [ + "boolean" + ] + }, + "required": true, + "deprecated": false + } + ], + "result": { + "name": "*types.IndexValidation", + "description": "*types.IndexValidation", + "summary": "", + "schema": { + "examples": [ + { + "TipSetKey": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 42, + "IndexedMessagesCount": 42, + "IndexedEventsCount": 42, + "IndexedEventEntriesCount": 42, + "Backfilled": true, + "IsNullRound": true + } + ], + "additionalProperties": false, + "properties": { + "Backfilled": { + "type": "boolean" + }, + "Height": { + "title": "number", + "type": "number" + }, + "IndexedEventEntriesCount": { + "title": "number", + "type": "number" + }, + "IndexedEventsCount": { + "title": "number", + "type": "number" + }, + "IndexedMessagesCount": { + "title": "number", + "type": "number" + }, + "IsNullRound": { + "type": "boolean" + }, + "TipSetKey": { + "additionalProperties": false, + "type": "object" + } + }, + "type": [ + "object" + ] + }, + "required": true, + "deprecated": false + }, + "deprecated": false, + "externalDocs": { + "description": "Github remote link", + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1650" } }, { @@ -2045,7 +2149,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1648" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1661" } }, { @@ -2092,7 +2196,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1659" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1672" } }, { @@ -2147,7 +2251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1670" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1683" } }, { @@ -2176,7 +2280,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1681" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1694" } }, { @@ -2313,7 +2417,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1692" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1705" } }, { @@ -2342,7 +2446,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1703" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1716" } }, { @@ -2396,7 +2500,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1714" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1727" } }, { @@ -2487,7 +2591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1725" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1738" } }, { @@ -2515,7 +2619,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1736" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1749" } }, { @@ -2605,7 +2709,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1747" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1760" } }, { @@ -2861,7 +2965,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1758" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1771" } }, { @@ -3106,7 +3210,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1769" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1782" } }, { @@ -3382,7 +3486,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1780" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1793" } }, { @@ -3675,7 +3779,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1791" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1804" } }, { @@ -3731,7 +3835,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1802" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1815" } }, { @@ -3778,7 +3882,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1813" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1826" } }, { @@ -3876,7 +3980,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1824" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1837" } }, { @@ -3942,7 +4046,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1835" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1848" } }, { @@ -4008,7 +4112,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1846" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1859" } }, { @@ -4117,7 +4221,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1857" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1870" } }, { @@ -4175,7 +4279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1868" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1881" } }, { @@ -4297,7 +4401,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1879" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1892" } }, { @@ -4506,7 +4610,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1890" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1903" } }, { @@ -4706,7 +4810,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1901" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1914" } }, { @@ -4898,7 +5002,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1912" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1925" } }, { @@ -5107,7 +5211,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1923" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1936" } }, { @@ -5198,7 +5302,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1934" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1947" } }, { @@ -5256,7 +5360,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1945" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1958" } }, { @@ -5514,7 +5618,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1956" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1969" } }, { @@ -5789,7 +5893,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1967" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1980" } }, { @@ -5817,7 +5921,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1978" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1991" } }, { @@ -5855,7 +5959,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1989" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2002" } }, { @@ -5963,7 +6067,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2000" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2013" } }, { @@ -6001,7 +6105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2011" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2024" } }, { @@ -6030,7 +6134,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2022" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2035" } }, { @@ -6093,7 +6197,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2033" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2046" } }, { @@ -6156,7 +6260,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2044" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2057" } }, { @@ -6219,7 +6323,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2055" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2068" } }, { @@ -6264,7 +6368,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2066" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2079" } }, { @@ -6386,7 +6490,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2077" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2090" } }, { @@ -6562,7 +6666,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2088" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2101" } }, { @@ -6717,7 +6821,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2099" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2112" } }, { @@ -6839,7 +6943,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2110" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2123" } }, { @@ -6893,7 +6997,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2121" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2134" } }, { @@ -6947,7 +7051,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2132" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2145" } }, { @@ -7132,7 +7236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2143" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2156" } }, { @@ -7215,7 +7319,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2154" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2167" } }, { @@ -7298,7 +7402,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2165" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2178" } }, { @@ -7465,7 +7569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2176" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2189" } }, { @@ -7666,7 +7770,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2187" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2200" } }, { @@ -7693,7 +7797,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2198" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2211" } }, { @@ -7769,7 +7873,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2209" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2222" } }, { @@ -7832,7 +7936,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2220" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2233" } }, { @@ -7975,7 +8079,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2231" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2244" } }, { @@ -8102,7 +8206,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2242" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2255" } }, { @@ -8204,7 +8308,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2253" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2266" } }, { @@ -8427,7 +8531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2264" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2277" } }, { @@ -8610,7 +8714,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2275" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2288" } }, { @@ -8690,7 +8794,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2286" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2299" } }, { @@ -8735,7 +8839,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2297" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2310" } }, { @@ -8791,7 +8895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2308" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2321" } }, { @@ -8871,7 +8975,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2319" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2332" } }, { @@ -8951,7 +9055,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2330" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2343" } }, { @@ -9436,7 +9540,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2341" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2354" } }, { @@ -9630,7 +9734,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2352" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2365" } }, { @@ -9785,7 +9889,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2363" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2376" } }, { @@ -10034,7 +10138,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2374" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2387" } }, { @@ -10189,7 +10293,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2385" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2398" } }, { @@ -10366,7 +10470,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2396" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2409" } }, { @@ -10464,7 +10568,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2407" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2420" } }, { @@ -10629,7 +10733,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2418" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2431" } }, { @@ -10668,7 +10772,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2429" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2442" } }, { @@ -10733,7 +10837,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2440" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2453" } }, { @@ -10779,7 +10883,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2451" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2464" } }, { @@ -10929,7 +11033,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2462" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2475" } }, { @@ -11066,7 +11170,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2473" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2486" } }, { @@ -11297,7 +11401,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2484" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2497" } }, { @@ -11434,7 +11538,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2495" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2508" } }, { @@ -11599,7 +11703,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2506" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2519" } }, { @@ -11676,7 +11780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2517" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2530" } }, { @@ -11871,7 +11975,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2539" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2552" } }, { @@ -12050,7 +12154,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2550" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2563" } }, { @@ -12212,7 +12316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2561" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2574" } }, { @@ -12360,7 +12464,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2572" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2585" } }, { @@ -12588,7 +12692,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2583" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2596" } }, { @@ -12736,7 +12840,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2594" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2607" } }, { @@ -12948,7 +13052,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2605" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2618" } }, { @@ -13154,7 +13258,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2616" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2629" } }, { @@ -13222,7 +13326,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2627" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2640" } }, { @@ -13339,7 +13443,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2638" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2651" } }, { @@ -13430,7 +13534,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2649" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2662" } }, { @@ -13516,7 +13620,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2660" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2673" } }, { @@ -13711,7 +13815,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2671" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2684" } }, { @@ -13873,7 +13977,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2682" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2695" } }, { @@ -14069,7 +14173,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2693" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2706" } }, { @@ -14249,7 +14353,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2704" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2717" } }, { @@ -14412,7 +14516,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2715" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2728" } }, { @@ -14439,7 +14543,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2726" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2739" } }, { @@ -14466,7 +14570,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2737" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2750" } }, { @@ -14565,7 +14669,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2748" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2761" } }, { @@ -14611,7 +14715,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2759" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2772" } }, { @@ -14711,7 +14815,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2770" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2783" } }, { @@ -14827,7 +14931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2781" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2794" } }, { @@ -14875,7 +14979,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2792" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2805" } }, { @@ -14967,7 +15071,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2803" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2816" } }, { @@ -15082,7 +15186,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2814" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2827" } }, { @@ -15130,7 +15234,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2825" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2838" } }, { @@ -15167,7 +15271,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2836" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2849" } }, { @@ -15439,7 +15543,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2847" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2860" } }, { @@ -15487,7 +15591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2858" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2871" } }, { @@ -15545,7 +15649,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2869" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2882" } }, { @@ -15750,7 +15854,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2880" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2893" } }, { @@ -15953,7 +16057,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2891" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2904" } }, { @@ -16122,7 +16226,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2902" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2915" } }, { @@ -16326,7 +16430,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2913" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2926" } }, { @@ -16493,7 +16597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2924" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2937" } }, { @@ -16700,7 +16804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2935" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2948" } }, { @@ -16768,7 +16872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2946" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2959" } }, { @@ -16820,7 +16924,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2957" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2970" } }, { @@ -16869,7 +16973,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2968" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2981" } }, { @@ -16960,7 +17064,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2979" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2992" } }, { @@ -17466,7 +17570,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2990" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3003" } }, { @@ -17572,7 +17676,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3001" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3014" } }, { @@ -17624,7 +17728,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3012" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3025" } }, { @@ -18176,7 +18280,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3023" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3036" } }, { @@ -18290,7 +18394,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3034" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3047" } }, { @@ -18387,7 +18491,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3045" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3058" } }, { @@ -18487,7 +18591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3056" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3069" } }, { @@ -18575,7 +18679,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3067" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3080" } }, { @@ -18675,7 +18779,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3078" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3091" } }, { @@ -18762,7 +18866,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3089" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3102" } }, { @@ -18853,7 +18957,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3100" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3113" } }, { @@ -18978,7 +19082,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3111" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3124" } }, { @@ -19087,7 +19191,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3122" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3135" } }, { @@ -19157,7 +19261,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3133" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3146" } }, { @@ -19260,7 +19364,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3144" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3157" } }, { @@ -19321,7 +19425,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3155" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3168" } }, { @@ -19451,7 +19555,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3166" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3179" } }, { @@ -19558,7 +19662,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3177" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3190" } }, { @@ -19777,7 +19881,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3188" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3201" } }, { @@ -19854,7 +19958,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3199" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3212" } }, { @@ -19931,7 +20035,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3210" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3223" } }, { @@ -20040,7 +20144,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3221" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3234" } }, { @@ -20149,7 +20253,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3232" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3245" } }, { @@ -20210,7 +20314,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3243" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3256" } }, { @@ -20320,7 +20424,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3254" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3267" } }, { @@ -20381,7 +20485,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3265" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3278" } }, { @@ -20449,7 +20553,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3276" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3289" } }, { @@ -20517,7 +20621,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3287" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3300" } }, { @@ -20598,7 +20702,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3298" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3311" } }, { @@ -20752,7 +20856,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3309" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3322" } }, { @@ -20824,7 +20928,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3320" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3333" } }, { @@ -20988,7 +21092,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3331" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3344" } }, { @@ -21153,7 +21257,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3342" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3355" } }, { @@ -21223,7 +21327,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3353" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3366" } }, { @@ -21291,7 +21395,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3364" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3377" } }, { @@ -21384,7 +21488,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3375" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3388" } }, { @@ -21455,7 +21559,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3386" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3399" } }, { @@ -21656,7 +21760,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3397" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3410" } }, { @@ -21788,7 +21892,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3408" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3421" } }, { @@ -21891,7 +21995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3419" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3432" } }, { @@ -22028,7 +22132,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3430" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3443" } }, { @@ -22139,7 +22243,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3441" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3454" } }, { @@ -22271,7 +22375,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3452" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3465" } }, { @@ -22402,7 +22506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3463" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3476" } }, { @@ -22473,7 +22577,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3474" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3487" } }, { @@ -22557,7 +22661,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3485" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3498" } }, { @@ -22643,7 +22747,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3496" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3509" } }, { @@ -22826,7 +22930,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3507" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3520" } }, { @@ -22853,7 +22957,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3518" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3531" } }, { @@ -22906,7 +23010,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3529" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3542" } }, { @@ -22994,7 +23098,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3540" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3553" } }, { @@ -23445,7 +23549,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3551" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3564" } }, { @@ -23612,7 +23716,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3562" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3575" } }, { @@ -23710,7 +23814,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3573" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3586" } }, { @@ -23883,7 +23987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3584" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3597" } }, { @@ -23981,7 +24085,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3595" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3608" } }, { @@ -24132,7 +24236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3606" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3619" } }, { @@ -24217,7 +24321,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3617" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3630" } }, { @@ -24285,7 +24389,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3628" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3641" } }, { @@ -24337,7 +24441,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3639" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3652" } }, { @@ -24405,7 +24509,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3650" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3663" } }, { @@ -24566,7 +24670,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3661" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3674" } }, { @@ -24613,7 +24717,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3683" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3696" } }, { @@ -24660,7 +24764,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3694" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3707" } }, { @@ -24703,7 +24807,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3716" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3729" } }, { @@ -24799,7 +24903,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3727" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3740" } }, { @@ -25065,7 +25169,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3738" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3751" } }, { @@ -25088,7 +25192,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3749" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3762" } }, { @@ -25131,7 +25235,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3760" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3773" } }, { @@ -25182,7 +25286,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3771" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3784" } }, { @@ -25227,7 +25331,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3782" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3795" } }, { @@ -25255,7 +25359,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3793" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3806" } }, { @@ -25295,7 +25399,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3804" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3817" } }, { @@ -25354,7 +25458,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3815" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3828" } }, { @@ -25398,7 +25502,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3826" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3839" } }, { @@ -25457,7 +25561,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3837" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3850" } }, { @@ -25494,7 +25598,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3848" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3861" } }, { @@ -25538,7 +25642,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3859" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3872" } }, { @@ -25578,7 +25682,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3870" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3883" } }, { @@ -25653,7 +25757,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3881" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3894" } }, { @@ -25861,7 +25965,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3892" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3905" } }, { @@ -25905,7 +26009,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3903" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3916" } }, { @@ -25995,7 +26099,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3914" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3927" } }, { @@ -26022,7 +26126,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3925" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3938" } } ] diff --git a/build/openrpc/gateway.json b/build/openrpc/gateway.json index 71d1dd9cc92..66913eec201 100644 --- a/build/openrpc/gateway.json +++ b/build/openrpc/gateway.json @@ -242,7 +242,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3936" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3949" } }, { @@ -473,7 +473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3947" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3960" } }, { @@ -572,7 +572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3958" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3971" } }, { @@ -604,7 +604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3969" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3982" } }, { @@ -710,7 +710,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3980" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3993" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3991" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4004" } }, { @@ -887,7 +887,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4002" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4015" } }, { @@ -987,7 +987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4013" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4026" } }, { @@ -1043,7 +1043,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4024" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4037" } }, { @@ -1116,7 +1116,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4035" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4048" } }, { @@ -1189,7 +1189,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4046" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4059" } }, { @@ -1236,7 +1236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4057" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4070" } }, { @@ -1268,7 +1268,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4068" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4081" } }, { @@ -1305,7 +1305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4090" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4103" } }, { @@ -1352,7 +1352,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4101" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4114" } }, { @@ -1392,7 +1392,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4112" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4125" } }, { @@ -1439,7 +1439,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4123" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4136" } }, { @@ -1494,7 +1494,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4134" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4147" } }, { @@ -1523,7 +1523,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4145" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4158" } }, { @@ -1660,7 +1660,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4156" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4169" } }, { @@ -1689,7 +1689,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4167" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4180" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4178" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4191" } }, { @@ -1834,7 +1834,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4189" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4202" } }, { @@ -1862,7 +1862,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4200" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4213" } }, { @@ -1952,7 +1952,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4211" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4224" } }, { @@ -2208,7 +2208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4222" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4235" } }, { @@ -2453,7 +2453,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4233" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4246" } }, { @@ -2729,7 +2729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4244" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4257" } }, { @@ -3022,7 +3022,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4255" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4268" } }, { @@ -3078,7 +3078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4266" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4279" } }, { @@ -3125,7 +3125,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4277" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4290" } }, { @@ -3223,7 +3223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4288" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4301" } }, { @@ -3289,7 +3289,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4299" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4312" } }, { @@ -3355,7 +3355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4310" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4323" } }, { @@ -3464,7 +3464,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4321" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4334" } }, { @@ -3522,7 +3522,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4332" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4345" } }, { @@ -3644,7 +3644,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4343" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4356" } }, { @@ -3836,7 +3836,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4354" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4367" } }, { @@ -4045,7 +4045,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4365" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4378" } }, { @@ -4136,7 +4136,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4376" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4389" } }, { @@ -4194,7 +4194,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4387" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4400" } }, { @@ -4452,7 +4452,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4398" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4411" } }, { @@ -4727,7 +4727,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4409" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4422" } }, { @@ -4755,7 +4755,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4420" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4433" } }, { @@ -4793,7 +4793,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4431" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4444" } }, { @@ -4901,7 +4901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4442" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4455" } }, { @@ -4939,7 +4939,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4453" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4466" } }, { @@ -4968,7 +4968,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4464" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4477" } }, { @@ -5031,7 +5031,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4475" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4488" } }, { @@ -5094,7 +5094,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4486" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4499" } }, { @@ -5139,7 +5139,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4497" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4510" } }, { @@ -5261,7 +5261,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4508" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4521" } }, { @@ -5437,7 +5437,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4519" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4532" } }, { @@ -5592,7 +5592,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4530" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4543" } }, { @@ -5714,7 +5714,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4541" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4554" } }, { @@ -5768,7 +5768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4552" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4565" } }, { @@ -5822,7 +5822,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4563" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4576" } }, { @@ -5885,7 +5885,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4574" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4587" } }, { @@ -5987,7 +5987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4585" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4598" } }, { @@ -6210,7 +6210,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4596" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4609" } }, { @@ -6393,7 +6393,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4607" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4620" } }, { @@ -6587,7 +6587,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4618" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4631" } }, { @@ -6633,7 +6633,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4629" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4642" } }, { @@ -6783,7 +6783,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4640" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4653" } }, { @@ -6920,7 +6920,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4651" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4664" } }, { @@ -6988,7 +6988,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4662" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4675" } }, { @@ -7105,7 +7105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4673" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4686" } }, { @@ -7196,7 +7196,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4684" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4697" } }, { @@ -7282,7 +7282,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4695" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4708" } }, { @@ -7309,7 +7309,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4706" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4719" } }, { @@ -7336,7 +7336,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4717" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4730" } }, { @@ -7404,7 +7404,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4728" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4741" } }, { @@ -7910,7 +7910,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4739" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4752" } }, { @@ -8007,7 +8007,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4750" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4763" } }, { @@ -8107,7 +8107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4761" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4774" } }, { @@ -8207,7 +8207,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4772" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4785" } }, { @@ -8332,7 +8332,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4783" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4796" } }, { @@ -8441,7 +8441,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4794" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4807" } }, { @@ -8544,7 +8544,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4805" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4818" } }, { @@ -8674,7 +8674,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4816" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4829" } }, { @@ -8781,7 +8781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4827" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4840" } }, { @@ -8842,7 +8842,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4838" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4851" } }, { @@ -8910,7 +8910,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4849" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4862" } }, { @@ -8991,7 +8991,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4860" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4873" } }, { @@ -9155,7 +9155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4871" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4884" } }, { @@ -9248,7 +9248,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4882" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4895" } }, { @@ -9449,7 +9449,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4893" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4906" } }, { @@ -9560,7 +9560,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4904" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4917" } }, { @@ -9691,7 +9691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4915" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4928" } }, { @@ -9777,7 +9777,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4926" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4939" } }, { @@ -9804,7 +9804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4937" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4950" } }, { @@ -9857,7 +9857,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4948" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4961" } }, { @@ -9945,7 +9945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4959" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4972" } }, { @@ -10396,7 +10396,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4970" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4983" } }, { @@ -10563,7 +10563,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4981" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4994" } }, { @@ -10736,7 +10736,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4992" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5005" } }, { @@ -10804,7 +10804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5003" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5016" } }, { @@ -10872,7 +10872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5014" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5027" } }, { @@ -11033,7 +11033,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5025" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5038" } }, { @@ -11078,7 +11078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5047" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5060" } }, { @@ -11123,7 +11123,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5058" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5071" } }, { @@ -11150,7 +11150,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5069" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5082" } } ] diff --git a/build/openrpc/miner.json b/build/openrpc/miner.json index 64f8aa7ed7e..cddf0d55883 100644 --- a/build/openrpc/miner.json +++ b/build/openrpc/miner.json @@ -30,7 +30,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5355" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5368" } }, { @@ -109,7 +109,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5366" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5379" } }, { @@ -155,7 +155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5377" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5390" } }, { @@ -203,7 +203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5388" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5401" } }, { @@ -251,7 +251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5399" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5412" } }, { @@ -354,7 +354,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5410" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5423" } }, { @@ -428,7 +428,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5421" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5434" } }, { @@ -591,7 +591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5432" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5445" } }, { @@ -742,7 +742,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5443" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5456" } }, { @@ -781,7 +781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5454" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5467" } }, { @@ -913,7 +913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5465" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5478" } }, { @@ -945,7 +945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5476" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5489" } }, { @@ -986,7 +986,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5487" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5500" } }, { @@ -1054,7 +1054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5498" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5511" } }, { @@ -1185,7 +1185,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5509" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5522" } }, { @@ -1316,7 +1316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5520" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5533" } }, { @@ -1416,7 +1416,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5531" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5544" } }, { @@ -1516,7 +1516,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5542" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5555" } }, { @@ -1616,7 +1616,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5553" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5566" } }, { @@ -1716,7 +1716,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5564" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5577" } }, { @@ -1816,7 +1816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5575" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5588" } }, { @@ -1916,7 +1916,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5586" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5599" } }, { @@ -2040,7 +2040,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5597" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5610" } }, { @@ -2164,7 +2164,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5608" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5621" } }, { @@ -2279,7 +2279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5619" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5632" } }, { @@ -2379,7 +2379,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5630" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5643" } }, { @@ -2512,7 +2512,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5641" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5654" } }, { @@ -2636,7 +2636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5652" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5665" } }, { @@ -2760,7 +2760,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5663" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5676" } }, { @@ -2884,7 +2884,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5674" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5687" } }, { @@ -3017,7 +3017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5685" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5698" } }, { @@ -3117,7 +3117,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5696" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5709" } }, { @@ -3157,7 +3157,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5707" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5720" } }, { @@ -3229,7 +3229,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5718" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5731" } }, { @@ -3279,7 +3279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5729" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5742" } }, { @@ -3323,7 +3323,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5740" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5753" } }, { @@ -3364,7 +3364,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5751" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5764" } }, { @@ -3608,7 +3608,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5762" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5775" } }, { @@ -3682,7 +3682,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5773" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5786" } }, { @@ -3732,7 +3732,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5784" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5797" } }, { @@ -3761,7 +3761,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5795" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5808" } }, { @@ -3790,7 +3790,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5806" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5819" } }, { @@ -3846,7 +3846,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5817" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5830" } }, { @@ -3869,7 +3869,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5828" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5841" } }, { @@ -3929,7 +3929,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5839" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5852" } }, { @@ -3968,7 +3968,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5850" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5863" } }, { @@ -4008,7 +4008,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5861" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5874" } }, { @@ -4081,7 +4081,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5872" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5885" } }, { @@ -4145,7 +4145,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5883" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5896" } }, { @@ -4208,7 +4208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5894" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5907" } }, { @@ -4258,7 +4258,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5905" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5918" } }, { @@ -4817,7 +4817,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5916" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5929" } }, { @@ -4858,7 +4858,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5927" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5940" } }, { @@ -4899,7 +4899,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5938" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5951" } }, { @@ -4940,7 +4940,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5949" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5962" } }, { @@ -4981,7 +4981,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5960" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5973" } }, { @@ -5022,7 +5022,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5971" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5984" } }, { @@ -5053,7 +5053,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5982" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5995" } }, { @@ -5103,7 +5103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5993" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6006" } }, { @@ -5144,7 +5144,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6004" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6017" } }, { @@ -5183,7 +5183,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6015" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6028" } }, { @@ -5247,7 +5247,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6026" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6039" } }, { @@ -5305,7 +5305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6037" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6050" } }, { @@ -5752,7 +5752,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6048" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6061" } }, { @@ -5788,7 +5788,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6059" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6072" } }, { @@ -5931,7 +5931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6070" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6083" } }, { @@ -5987,7 +5987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6081" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6094" } }, { @@ -6026,7 +6026,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6092" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6105" } }, { @@ -6203,7 +6203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6103" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6116" } }, { @@ -6255,7 +6255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6114" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6127" } }, { @@ -6447,7 +6447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6125" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6138" } }, { @@ -6547,7 +6547,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6136" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6149" } }, { @@ -6601,7 +6601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6147" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6160" } }, { @@ -6640,7 +6640,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6158" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6171" } }, { @@ -6725,7 +6725,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6169" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6182" } }, { @@ -6919,7 +6919,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6180" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6193" } }, { @@ -7017,7 +7017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6191" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6204" } }, { @@ -7149,7 +7149,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6202" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6215" } }, { @@ -7203,7 +7203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6213" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6226" } }, { @@ -7237,7 +7237,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6224" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6237" } }, { @@ -7324,7 +7324,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6235" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6248" } }, { @@ -7378,7 +7378,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6246" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6259" } }, { @@ -7478,7 +7478,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6257" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6270" } }, { @@ -7555,7 +7555,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6268" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6281" } }, { @@ -7646,7 +7646,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6279" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6292" } }, { @@ -7685,7 +7685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6290" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6303" } }, { @@ -7801,7 +7801,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6301" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6314" } }, { @@ -9901,7 +9901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6312" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6325" } } ] diff --git a/build/openrpc/worker.json b/build/openrpc/worker.json index 791c933fb60..f6f6ec5eed7 100644 --- a/build/openrpc/worker.json +++ b/build/openrpc/worker.json @@ -161,7 +161,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6400" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6413" } }, { @@ -252,7 +252,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6411" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6424" } }, { @@ -420,7 +420,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6422" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6435" } }, { @@ -447,7 +447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6433" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6446" } }, { @@ -597,7 +597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6444" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6457" } }, { @@ -700,7 +700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6455" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6468" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6466" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6479" } }, { @@ -925,7 +925,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6477" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6490" } }, { @@ -1135,7 +1135,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6488" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6501" } }, { @@ -1306,7 +1306,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6499" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6512" } }, { @@ -3350,7 +3350,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6510" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6523" } }, { @@ -3470,7 +3470,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6521" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6534" } }, { @@ -3531,7 +3531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6532" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6545" } }, { @@ -3569,7 +3569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6543" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6556" } }, { @@ -3729,7 +3729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6554" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6567" } }, { @@ -3913,7 +3913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6565" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6578" } }, { @@ -4054,7 +4054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6576" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6589" } }, { @@ -4107,7 +4107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6587" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6600" } }, { @@ -4250,7 +4250,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6598" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6611" } }, { @@ -4474,7 +4474,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6609" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6622" } }, { @@ -4601,7 +4601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6620" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6633" } }, { @@ -4768,7 +4768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6631" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6644" } }, { @@ -4895,7 +4895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6642" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6655" } }, { @@ -4933,7 +4933,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6653" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6666" } }, { @@ -4972,7 +4972,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6664" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6677" } }, { @@ -4995,7 +4995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6675" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6688" } }, { @@ -5034,7 +5034,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6686" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6699" } }, { @@ -5057,7 +5057,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6697" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6710" } }, { @@ -5096,7 +5096,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6708" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6721" } }, { @@ -5130,7 +5130,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6719" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6732" } }, { @@ -5184,7 +5184,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6730" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6743" } }, { @@ -5223,7 +5223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6741" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6754" } }, { @@ -5262,7 +5262,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6752" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6765" } }, { @@ -5297,7 +5297,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6763" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6776" } }, { @@ -5477,7 +5477,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6774" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6787" } }, { @@ -5506,7 +5506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6785" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6798" } }, { @@ -5529,7 +5529,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6796" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6809" } } ] From 0207fa23325a9af1445b98a39a659d045fa9151c Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 2 Oct 2024 15:13:23 +0400 Subject: [PATCH 24/61] UX improvements to backfilling --- chain/index/api.go | 35 +++++++++++++++++++++++-------- cmd/lotus-shed/chain_index.go | 39 +++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 2871010d703..c9aaa5fa90e 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -106,18 +106,35 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, xerrors.Errorf("index corruption: indexed tipset at height %d has key %s, but canonical chain has %s", epoch, indexedTsKeyCid, expectedTsKeyCid) } - // indexedTsKeyCid and expectedTsKeyCid are the same, so we can use `expectedTs` to fetch the indexed data - indexedData, err := si.getIndexedTipSetData(ctx, expectedTs) - if err != nil { - return nil, xerrors.Errorf("failed to get indexed data for tipset at height %d: %w", expectedTs.Height(), err) + getAndVerifyIndexedData := func() (*indexedTipSetData, error) { + indexedData, err := si.getIndexedTipSetData(ctx, expectedTs) + if err != nil { + return nil, xerrors.Errorf("failed to get indexed data for tipset at height %d: %w", expectedTs.Height(), err) + } + if indexedData == nil { + return nil, xerrors.Errorf("nil indexed data for tipset at height %d", expectedTs.Height()) + } + if err = si.verifyIndexedData(ctx, expectedTs, indexedData); err != nil { + return nil, err + } + return indexedData, nil } - if indexedData == nil { - return nil, xerrors.Errorf("nil indexed data for tipset at height %d", expectedTs.Height()) - } + indexedData, err := getAndVerifyIndexedData() + if err != nil { + if !backfill { + return nil, xerrors.Errorf("failed to verify indexed data at height %d: %w", expectedTs.Height(), err) + } - if err = si.verifyIndexedData(ctx, expectedTs, indexedData); err != nil { - return nil, xerrors.Errorf("failed to verify indexed data at height %d: %w", expectedTs.Height(), err) + log.Warnf("failed to verify indexed data at height %d; err:%s; backfilling once and validating again", expectedTs.Height(), err) + if _, err := si.backfillMissingTipset(ctx, expectedTs, backfill); err != nil { + return nil, xerrors.Errorf("failed to backfill missing tipset at height %d during validation; err: %w", expectedTs.Height(), err) + } + + indexedData, err = getAndVerifyIndexedData() + if err != nil { + return nil, xerrors.Errorf("failed to verify indexed data at height %d after backfill: %w", expectedTs.Height(), err) + } } return &types.IndexValidation{ diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index d7b7575ce38..0aab0431002 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "time" "github.com/urfave/cli/v2" "golang.org/x/xerrors" @@ -27,20 +28,20 @@ var validateBackfillChainIndexCmd = &cli.Command{ Description: ` lotus-shed chainindex validate-backfill --from --to [--backfill] [--log-good] -The command validates the chain index entries for each epoch in the specified range, checking for missing or -inconsistent entries (i.e. the indexed data does not match the actual chain state). If '--backfill' is enabled +The command validates the chain index entries for each epoch in the specified range, checking for missing or +inconsistent entries (i.e. the indexed data does not match the actual chain state). If '--backfill' is enabled (which it is by default), it will attempt to backfill any missing entries using the 'ChainValidateIndex' API. Parameters: - '--from' (required): The starting epoch (inclusive) for the validation range. Must be greater than 0. - - '--to' (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less + - '--to' (required): The ending epoch (inclusive) for the validation range. Must be greater than 0 and less than or equal to 'from'. - - '--backfill' (optional, default: true): Whether to backfill missing index entries during validation. + - '--backfill' (optional, default: true): Whether to backfill missing index entries during validation. - '--log-good' (optional, default: false): Whether to log details for tipsets that have no detected problems. Error conditions: - If 'from' or 'to' are invalid (<=0 or 'to' > 'from'), an error is returned. - - If the 'ChainValidateIndex' API returns an error for an epoch, indicating an inconsistency between the index + - If the 'ChainValidateIndex' API returns an error for an epoch, indicating an inconsistency between the index and chain state, an error message is logged for that epoch. Logging: @@ -53,10 +54,10 @@ Example usage: To validate and backfill the chain index for the last 5760 epochs (2 days) and log details for all epochs: -lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good +lotus-shed chainindex validate-backfill --from 1000000 --to 994240 --log-good -This command is useful for backfilling the chain index over a range of historical epochs during the migration to -the new ChainIndexer. It can also be run periodically to validate the index's integrity using system schedulers +This command is useful for backfilling the chain index over a range of historical epochs during the migration to +the new ChainIndexer. It can also be run periodically to validate the index's integrity using system schedulers like cron. `, Flags: []cli.Flag{ @@ -121,8 +122,9 @@ like cron. // Results Tracking logGood := cctx.Bool("log-good") - _, _ = fmt.Fprintf(cctx.App.Writer, "starting chainindex validation; from epoch: %d; to epoch: %d; backfill: %t; log-good: %t\n", fromEpoch, toEpoch, - backfill, logGood) + startTime := time.Now() + _, _ = fmt.Fprintf(cctx.App.Writer, "%s starting chainindex validation; from epoch: %d; to epoch: %d; backfill: %t; log-good: %t\n", currentTimeString(), + fromEpoch, toEpoch, backfill, logGood) totalEpochs := fromEpoch - toEpoch + 1 for epoch := fromEpoch; epoch >= toEpoch; epoch-- { @@ -130,14 +132,16 @@ like cron. return ctx.Err() } - if (fromEpoch-epoch+1)%2880 == 0 { + if (fromEpoch-epoch+1)%2880 == 0 || epoch == toEpoch { progress := float64(fromEpoch-epoch+1) / float64(totalEpochs) * 100 - log.Infof("-------- chain index validation progress: %.2f%%\n", progress) + elapsed := time.Since(startTime) + _, _ = fmt.Fprintf(cctx.App.Writer, "%s -------- Chain index validation progress: %.2f%%; Time elapsed: %s Minutes\n", + currentTimeString(), progress, elapsed.Round(time.Minute)) } indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) if err != nil { - _, _ = fmt.Fprintf(cctx.App.Writer, "✗ Epoch %d; failure: %s\n", epoch, err) + _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✗ Epoch %d; failure: %s\n", currentTimeString(), epoch, err) continue } @@ -147,17 +151,22 @@ like cron. // is it a null round ? if indexValidateResp.IsNullRound { - _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d; null round\n", epoch) + _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✓ Epoch %d; null round\n", currentTimeString(), epoch) } else { jsonData, err := json.Marshal(indexValidateResp) if err != nil { return fmt.Errorf("failed to marshal results to JSON: %w", err) } - _, _ = fmt.Fprintf(cctx.App.Writer, "✓ Epoch %d (%s)\n", epoch, string(jsonData)) + _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✓ Epoch %d (%s)\n", currentTimeString(), epoch, string(jsonData)) } } return nil }, } + +func currentTimeString() string { + currentTime := time.Now().Format("2006-01-02 15:04:05.000") + return currentTime +} From 3c4864438c1be520c03c0a1f40ec3a0c49f8cae5 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Fri, 4 Oct 2024 11:06:49 +0400 Subject: [PATCH 25/61] feat: tests for the chain indexer (#12521) * ddl tests * tests for the chain indexer * finish unit tests for chain indexer * fix formatting --- chain/index/api.go | 5 +- chain/index/api_test.go | 483 ++++++++++++++++++++++++ chain/index/ddls_test.go | 708 ++++++++++++++++++++++++++++++++++++ chain/index/events.go | 25 +- chain/index/events_test.go | 238 ++++++++++++ chain/index/gc_test.go | 67 ++++ chain/index/helpers.go | 4 + chain/index/indexer.go | 9 +- chain/index/indexer_test.go | 54 +++ chain/index/interface.go | 3 +- chain/index/read_test.go | 303 +++++++++++++++ node/modules/chainindex.go | 9 +- 12 files changed, 1891 insertions(+), 17 deletions(-) create mode 100644 chain/index/api_test.go create mode 100644 chain/index/ddls_test.go create mode 100644 chain/index/events_test.go create mode 100644 chain/index/gc_test.go create mode 100644 chain/index/indexer_test.go create mode 100644 chain/index/read_test.go diff --git a/chain/index/api.go b/chain/index/api.go index c9aaa5fa90e..72c1aaa8e15 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -223,7 +223,8 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return xerrors.Errorf("failed to get next tipset for height %d: %w", ts.Height(), err) } - // if non-reverted events exist which means that tipset `ts` has been executed, there should be 0 reverted events in the DB + // given that `ts` is on the canonical chain and `executionTs` is the next tipset in the chain + // `ts` can not have reverted events var hasRevertedEventsInTipset bool err = si.stmts.hasRevertedEventsInTipsetStmt.QueryRowContext(ctx, tsKeyCid.Bytes()).Scan(&hasRevertedEventsInTipset) if err != nil { @@ -233,7 +234,7 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s at height %d", tsKeyCid, ts.Height()) } - executedMsgs, err := si.loadExecutedMessages(ctx, ts, executionTs) + executedMsgs, err := si.eventLoaderFunc(ctx, si.cs, ts, executionTs) if err != nil { return xerrors.Errorf("failed to load executed messages for height %d: %w", ts.Height(), err) } diff --git a/chain/index/api_test.go b/chain/index/api_test.go new file mode 100644 index 00000000000..44ac9aae6a0 --- /dev/null +++ b/chain/index/api_test.go @@ -0,0 +1,483 @@ +package index + +import ( + "context" + pseudo "math/rand" + "testing" + "time" + + "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/chain/types" +) + +func TestValidateIsNullRound(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + tests := []struct { + name string + epoch abi.ChainEpoch + setupFunc func(*SqliteIndexer) + expectedResult bool + expectError bool + errorContains string + }{ + { + name: "happy path - null round", + epoch: 50, + expectedResult: true, + }, + { + name: "failure - non-null round", + epoch: 50, + setupFunc: func(si *SqliteIndexer) { + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: randomCid(t, rng).Bytes(), + height: 50, + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + }, + expectError: true, + errorContains: "index corruption", + }, + { + name: "edge case - epoch 0", + epoch: 0, + expectedResult: true, + }, + { + name: "edge case - epoch above head", + epoch: headHeight + 1, + expectedResult: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + si, _, _ := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + + if tt.setupFunc != nil { + tt.setupFunc(si) + } + + res, err := si.validateIsNullRound(ctx, tt.epoch) + + if tt.expectError { + require.Error(t, err) + if tt.errorContains != "" { + require.Contains(t, err.Error(), tt.errorContains) + } + } else { + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, tt.expectedResult, res.IsNullRound) + require.Equal(t, uint64(tt.epoch), res.Height) + } + }) + } +} + +func TestFailureHeadHeight(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + si, head, _ := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + _ = si.Start() + + _, err := si.ChainValidateIndex(ctx, head.Height(), false) + require.Error(t, err) + require.Contains(t, err.Error(), "cannot validate index at epoch") +} + +func TestBackfillNullRound(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + _ = si.Start() + + nullRoundEpoch := abi.ChainEpoch(50) + nonNullRoundEpoch := abi.ChainEpoch(51) + + // Create a tipset with a height different from the requested epoch + nonNullTs := fakeTipSet(t, rng, nonNullRoundEpoch, []cid.Cid{}) + + // Set up the chainstore to return the non-null tipset for the null round epoch + cs.SetTipsetByHeightAndKey(nullRoundEpoch, nonNullTs.Key(), nonNullTs) + + // Attempt to validate the null round epoch + result, err := si.ChainValidateIndex(ctx, nullRoundEpoch, true) + require.NoError(t, err) + require.NotNil(t, result) + require.False(t, result.Backfilled) + require.True(t, result.IsNullRound) +} + +func TestBackfillReturnsError(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + _ = si.Start() + + missingEpoch := abi.ChainEpoch(50) + + // Create a tipset for the missing epoch, but don't index it + missingTs := fakeTipSet(t, rng, missingEpoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(missingEpoch, missingTs.Key(), missingTs) + + // Attempt to validate the missing epoch with backfill flag set to false + _, err := si.ChainValidateIndex(ctx, missingEpoch, false) + require.Error(t, err) + require.Contains(t, err.Error(), "missing tipset at height 50 in the chain index") +} + +func TestBackfillMissingEpoch(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + _ = si.Start() + + // Initialize address resolver + si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + idAddr, err := address.NewIDAddress(uint64(emitter)) + if err != nil { + return address.Undef, false + } + return idAddr, true + }) + + missingEpoch := abi.ChainEpoch(50) + + parentTs := fakeTipSet(t, rng, missingEpoch-1, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(missingEpoch-1, parentTs.Key(), parentTs) + + missingTs := fakeTipSet(t, rng, missingEpoch, parentTs.Cids()) + cs.SetTipsetByHeightAndKey(missingEpoch, missingTs.Key(), missingTs) + + executionTs := fakeTipSet(t, rng, missingEpoch+1, missingTs.Key().Cids()) + cs.SetTipsetByHeightAndKey(missingEpoch+1, executionTs.Key(), executionTs) + + // Create fake messages and events + fakeMsg := fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng)) + fakeEvent := fakeEvent(1, []kv{{k: "test", v: []byte("value")}, {k: "test2", v: []byte("value2")}}, nil) + + executedMsg := executedMessage{ + msg: fakeMsg, + evs: []types.Event{*fakeEvent}, + } + + cs.SetMessagesForTipset(missingTs, []types.ChainMsg{fakeMsg}) + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + if msgTs.Height() == missingTs.Height() { + return []executedMessage{executedMsg}, nil + } + return nil, nil + }) + + // Attempt to validate and backfill the missing epoch + result, err := si.ChainValidateIndex(ctx, missingEpoch, true) + require.NoError(t, err) + require.NotNil(t, result) + require.True(t, result.Backfilled) + require.Equal(t, uint64(missingEpoch), result.Height) + require.Equal(t, uint64(1), result.IndexedMessagesCount) + require.Equal(t, uint64(1), result.IndexedEventsCount) + require.Equal(t, uint64(2), result.IndexedEventEntriesCount) + + // Verify that the epoch is now indexed + verificationResult, err := si.ChainValidateIndex(ctx, missingEpoch, false) + require.NoError(t, err) + require.NotNil(t, verificationResult) + require.False(t, verificationResult.Backfilled) + require.Equal(t, result.IndexedMessagesCount, verificationResult.IndexedMessagesCount) + require.Equal(t, result.IndexedEventsCount, verificationResult.IndexedEventsCount) + require.Equal(t, result.IndexedEventEntriesCount, verificationResult.IndexedEventEntriesCount) +} + +func TestIndexCorruption(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(100) + + tests := []struct { + name string + setupFunc func(*testing.T, *SqliteIndexer, *dummyChainStore) + epoch abi.ChainEpoch + errorContains string + }{ + { + name: "only reverted tipsets", + setupFunc: func(t *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts.Key(), ts) + keyBz, err := ts.Key().Cid() + require.NoError(t, err) + + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: true, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + }, + epoch: 50, + errorContains: "index corruption: height 50 only has reverted tipsets", + }, + { + name: "multiple non-reverted tipsets", + setupFunc: func(t *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts1 := fakeTipSet(t, rng, epoch, []cid.Cid{}) + ts2 := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts1.Key(), ts1) + + t1Bz, err := toTipsetKeyCidBytes(ts1) + require.NoError(t, err) + t2Bz, err := toTipsetKeyCidBytes(ts2) + require.NoError(t, err) + + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: t1Bz, + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: t2Bz, + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + }, + epoch: 50, + errorContains: "index corruption: height 50 has multiple non-reverted tipsets", + }, + { + name: "tipset key mismatch", + setupFunc: func(_ *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts1 := fakeTipSet(t, rng, epoch, []cid.Cid{}) + ts2 := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts1.Key(), ts1) + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: ts2.Key().Cids()[0].Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + }, + epoch: 50, + errorContains: "index corruption: indexed tipset at height 50 has key", + }, + { + name: "reverted events for executed tipset", + setupFunc: func(_ *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts.Key(), ts) + keyBz, err := ts.Key().Cid() + require.NoError(t, err) + + messageID := insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + insertEvent(t, si, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: randomIDAddr(t, rng).Bytes(), + reverted: true, + }) + cs.SetTipsetByHeightAndKey(epoch+1, fakeTipSet(t, rng, epoch+1, ts.Key().Cids()).Key(), fakeTipSet(t, rng, epoch+1, ts.Key().Cids())) + }, + epoch: 50, + errorContains: "index corruption: reverted events found for an executed tipset", + }, + { + name: "message count mismatch", + setupFunc: func(_ *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts.Key(), ts) + keyBz, err := ts.Key().Cid() + require.NoError(t, err) + + // Insert two messages in the index + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 1, + }) + + // Setup dummy event loader + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return []executedMessage{{msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng))}}, nil + }) + + // Set up the next tipset for event execution + nextTs := fakeTipSet(t, rng, epoch+1, ts.Key().Cids()) + cs.SetTipsetByHeightAndKey(epoch+1, nextTs.Key(), nextTs) + }, + epoch: 50, + errorContains: "failed to verify indexed data at height 50: message count mismatch for height 50: chainstore has 1, index has 2", + }, + { + name: "event count mismatch", + setupFunc: func(_ *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts.Key(), ts) + keyBz, err := ts.Key().Cid() + require.NoError(t, err) + + // Insert one message in the index + messageID := insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + // Insert two events for the message + insertEvent(t, si, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: randomIDAddr(t, rng).Bytes(), + reverted: false, + }) + insertEvent(t, si, event{ + messageID: messageID, + eventIndex: 1, + emitterAddr: randomIDAddr(t, rng).Bytes(), + reverted: false, + }) + + // Setup dummy event loader to return only one event + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return []executedMessage{ + { + msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng)), + evs: []types.Event{*fakeEvent(1, []kv{{k: "test", v: []byte("value")}}, nil)}, + }, + }, nil + }) + + // Set up the next tipset for event execution + nextTs := fakeTipSet(t, rng, epoch+1, ts.Key().Cids()) + cs.SetTipsetByHeightAndKey(epoch+1, nextTs.Key(), nextTs) + }, + epoch: 50, + errorContains: "failed to verify indexed data at height 50: event count mismatch for height 50: chainstore has 1, index has 2", + }, + { + name: "event entries count mismatch", + setupFunc: func(_ *testing.T, si *SqliteIndexer, cs *dummyChainStore) { + epoch := abi.ChainEpoch(50) + ts := fakeTipSet(t, rng, epoch, []cid.Cid{}) + cs.SetTipsetByHeightAndKey(epoch, ts.Key(), ts) + keyBz, err := ts.Key().Cid() + require.NoError(t, err) + + // Insert one message in the index + messageID := insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: keyBz.Bytes(), + height: uint64(epoch), + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + // Insert one event with two entries for the message + eventID := insertEvent(t, si, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: randomIDAddr(t, rng).Bytes(), + reverted: false, + }) + insertEventEntry(t, si, eventEntry{ + eventID: eventID, + indexed: true, + flags: []byte{0x01}, + key: "key1", + codec: 1, + value: []byte("value1"), + }) + insertEventEntry(t, si, eventEntry{ + eventID: eventID, + indexed: true, + flags: []byte{0x00}, + key: "key2", + codec: 2, + value: []byte("value2"), + }) + + // Setup dummy event loader to return one event with only one entry + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return []executedMessage{ + { + msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng)), + evs: []types.Event{*fakeEvent(1, []kv{{k: "key1", v: []byte("value1")}}, nil)}, + }, + }, nil + }) + + // Set up the next tipset for event execution + nextTs := fakeTipSet(t, rng, epoch+1, ts.Key().Cids()) + cs.SetTipsetByHeightAndKey(epoch+1, nextTs.Key(), nextTs) + }, + epoch: 50, + errorContains: "failed to verify indexed data at height 50: event entries count mismatch for height 50: chainstore has 1, index has 2", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + _ = si.Start() + + tt.setupFunc(t, si, cs) + + _, err := si.ChainValidateIndex(ctx, tt.epoch, false) + require.Error(t, err) + require.Contains(t, err.Error(), tt.errorContains) + }) + } +} diff --git a/chain/index/ddls_test.go b/chain/index/ddls_test.go new file mode 100644 index 00000000000..69b09f975c8 --- /dev/null +++ b/chain/index/ddls_test.go @@ -0,0 +1,708 @@ +package index + +import ( + "database/sql" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestHasRevertedEventsInTipsetStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // running on empty DB should return false + verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), false) + + // Insert tipset with a reverted event + ts := tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + } + messageID := insertTipsetMessage(t, s, ts) + + insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: []byte("test_emitter_addr"), + reverted: true, + }) + + // Verify `hasRevertedEventsInTipset` returns true + verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), true) + + // change event to non-reverted + updateEventsToNonReverted(t, s, []byte("test_tipset_key")) + + // Verify `hasRevertedEventsInTipset` returns false + verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), false) +} + +func TestGetNonRevertedTipsetCountStmts(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // running on empty DB should return 0 + verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 0) + + // Insert non-reverted tipset + messageID := insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + }) + + // Insert event + eventID1 := insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: []byte("test_emitter_addr"), + reverted: false, + }) + eventID2 := insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 1, + emitterAddr: []byte("test_emitter_addr"), + reverted: false, + }) + + // Insert event entry + insertEventEntry(t, s, eventEntry{ + eventID: eventID1, + indexed: true, + flags: []byte("test_flags"), + key: "test_key", + codec: 1, + value: []byte("test_value"), + }) + insertEventEntry(t, s, eventEntry{ + eventID: eventID2, + indexed: true, + flags: []byte("test_flags2"), + key: "test_key2", + codec: 2, + value: []byte("test_value2"), + }) + + // verify 2 event entries + verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 2) + + // Verify event count + verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 2) + + // verify message count is 1 + verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 1) + + // mark tipset as reverted + revertTipset(t, s, []byte("test_tipset_key")) + + // Verify `getNonRevertedTipsetEventEntriesCountStmt` returns 0 + verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 0) + + // verify event count is 0 + verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 0) + + // verify message count is 0 + verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 0) +} + +func TestUpdateTipsetToNonRevertedStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // insert a reverted tipset + ts := tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: true, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + } + + // Insert tipset + messageId := insertTipsetMessage(t, s, ts) + + res, err := s.stmts.updateTipsetToNonRevertedStmt.Exec([]byte("test_tipset_key")) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + // verify the tipset is not reverted + ts.reverted = false + verifyTipsetMessage(t, s, messageId, ts) +} + +func TestHasNullRoundAtHeightStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // running on empty DB should return true + verifyHasNullRoundAtHeightStmt(t, s, 1, true) + verifyHasNullRoundAtHeightStmt(t, s, 0, true) + + // insert tipset + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + }) + + // verify not a null round + verifyHasNullRoundAtHeightStmt(t, s, 1, false) +} + +func TestHasTipsetStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // running on empty DB should return false + verifyHasTipsetStmt(t, s, []byte("test_tipset_key"), false) + + // insert tipset + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + }) + + // verify tipset exists + verifyHasTipsetStmt(t, s, []byte("test_tipset_key"), true) + + // verify non-existent tipset + verifyHasTipsetStmt(t, s, []byte("non_existent_tipset_key"), false) +} + +func TestUpdateEventsToRevertedStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Insert a non-reverted tipset + messageID := insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + }) + + // Insert non-reverted events + insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: []byte("test_emitter_addr"), + reverted: false, + }) + insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 1, + emitterAddr: []byte("test_emitter_addr"), + reverted: false, + }) + + // Verify events are not reverted + var count int + err = s.db.QueryRow("SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id = ?", messageID).Scan(&count) + require.NoError(t, err) + require.Equal(t, 2, count) + + // Execute updateEventsToRevertedStmt + _, err = s.stmts.updateEventsToRevertedStmt.Exec([]byte("test_tipset_key")) + require.NoError(t, err) + + // Verify events are now reverted + err = s.db.QueryRow("SELECT COUNT(*) FROM event WHERE reverted = 1 AND message_id = ?", messageID).Scan(&count) + require.NoError(t, err) + require.Equal(t, 2, count) + + // Verify no non-reverted events remain + err = s.db.QueryRow("SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id = ?", messageID).Scan(&count) + require.NoError(t, err) + require.Equal(t, 0, count) +} + +func TestCountTipsetsAtHeightStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Test empty DB + verifyCountTipsetsAtHeightStmt(t, s, 1, 0, 0) + + // Test 0,1 case + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_1"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid_1"), + messageIndex: 0, + }) + verifyCountTipsetsAtHeightStmt(t, s, 1, 0, 1) + + // Test 0,2 case + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_2"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid_2"), + messageIndex: 0, + }) + verifyCountTipsetsAtHeightStmt(t, s, 1, 0, 2) + + // Test 1,2 case + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_3"), + height: 1, + reverted: true, + messageCid: []byte("test_message_cid_3"), + messageIndex: 0, + }) + verifyCountTipsetsAtHeightStmt(t, s, 1, 1, 2) + + // Test 2,2 case + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_4"), + height: 1, + reverted: true, + messageCid: []byte("test_message_cid_4"), + messageIndex: 0, + }) + verifyCountTipsetsAtHeightStmt(t, s, 1, 2, 2) +} + +func TestNonRevertedTipsetAtHeightStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Test empty DB + var et []byte + err = s.stmts.getNonRevertedTipsetAtHeightStmt.QueryRow(10).Scan(&et) + require.Equal(t, sql.ErrNoRows, err) + + // Insert non-reverted tipset + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_1"), + height: 10, + reverted: false, + messageCid: []byte("test_message_cid_1"), + messageIndex: 0, + }) + + // Insert reverted tipset at same height + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_2"), + height: 10, + reverted: true, + messageCid: []byte("test_message_cid_2"), + messageIndex: 0, + }) + + // Verify getNonRevertedTipsetAtHeightStmt returns the non-reverted tipset + var tipsetKeyCid []byte + err = s.stmts.getNonRevertedTipsetAtHeightStmt.QueryRow(10).Scan(&tipsetKeyCid) + require.NoError(t, err) + require.Equal(t, []byte("test_tipset_key_1"), tipsetKeyCid) + + // Insert another non-reverted tipset at a different height + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_3"), + height: 20, + reverted: false, + messageCid: []byte("test_message_cid_3"), + messageIndex: 0, + }) + + // Verify getNonRevertedTipsetAtHeightStmt returns the correct tipset for the new height + err = s.stmts.getNonRevertedTipsetAtHeightStmt.QueryRow(20).Scan(&tipsetKeyCid) + require.NoError(t, err) + require.Equal(t, []byte("test_tipset_key_3"), tipsetKeyCid) + + // Test with a height that has no tipset + err = s.stmts.getNonRevertedTipsetAtHeightStmt.QueryRow(30).Scan(&tipsetKeyCid) + require.Equal(t, sql.ErrNoRows, err) + + // Revert all tipsets at height 10 + _, err = s.db.Exec("UPDATE tipset_message SET reverted = 1 WHERE height = 10") + require.NoError(t, err) + + // Verify getNonRevertedTipsetAtHeightStmt returns no rows for the reverted height + err = s.stmts.getNonRevertedTipsetAtHeightStmt.QueryRow(10).Scan(&tipsetKeyCid) + require.Equal(t, sql.ErrNoRows, err) +} + +func TestMinNonRevertedHeightStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Test empty DB + var minHeight sql.NullInt64 + err = s.stmts.getMinNonRevertedHeightStmt.QueryRow().Scan(&minHeight) + require.NoError(t, err) + require.False(t, minHeight.Valid) + + // Insert non-reverted tipsets + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_1"), + height: 10, + reverted: false, + messageCid: []byte("test_message_cid_1"), + messageIndex: 0, + }) + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_2"), + height: 20, + reverted: false, + messageCid: []byte("test_message_cid_2"), + messageIndex: 0, + }) + + // Verify minimum non-reverted height + verifyMinNonRevertedHeightStmt(t, s, 10) + + // Insert reverted tipset with lower height + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key_4"), + height: 5, + reverted: true, + messageCid: []byte("test_message_cid_4"), + messageIndex: 0, + }) + + // Verify minimum non-reverted height hasn't changed + verifyMinNonRevertedHeightStmt(t, s, 10) + + // Revert all tipsets + _, err = s.db.Exec("UPDATE tipset_message SET reverted = 1") + require.NoError(t, err) + + // Verify no minimum non-reverted height + err = s.stmts.getMinNonRevertedHeightStmt.QueryRow().Scan(&minHeight) + require.NoError(t, err) + require.False(t, minHeight.Valid) +} + +func verifyMinNonRevertedHeightStmt(t *testing.T, s *SqliteIndexer, expectedMinHeight int64) { + var minHeight sql.NullInt64 + err := s.stmts.getMinNonRevertedHeightStmt.QueryRow().Scan(&minHeight) + require.NoError(t, err) + require.True(t, minHeight.Valid) + require.Equal(t, expectedMinHeight, minHeight.Int64) +} + +func TestGetMsgIdForMsgCidAndTipsetStmt(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Insert a non-reverted tipset + tipsetKeyCid := []byte("test_tipset_key") + messageCid := []byte("test_message_cid") + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: tipsetKeyCid, + height: 1, + reverted: false, + messageCid: messageCid, + messageIndex: 0, + }) + + // Verify getMsgIdForMsgCidAndTipset returns the correct message ID + var messageID int64 + err = s.stmts.getMsgIdForMsgCidAndTipsetStmt.QueryRow(tipsetKeyCid, messageCid).Scan(&messageID) + require.NoError(t, err) + require.Equal(t, int64(1), messageID) + + // Test with non-existent message CID + nonExistentMessageCid := []byte("non_existent_message_cid") + err = s.stmts.getMsgIdForMsgCidAndTipsetStmt.QueryRow(tipsetKeyCid, nonExistentMessageCid).Scan(&messageID) + require.Equal(t, sql.ErrNoRows, err) + + // Test with non-existent tipset key + nonExistentTipsetKeyCid := []byte("non_existent_tipset_key") + err = s.stmts.getMsgIdForMsgCidAndTipsetStmt.QueryRow(nonExistentTipsetKeyCid, messageCid).Scan(&messageID) + require.Equal(t, sql.ErrNoRows, err) + + // Insert a reverted tipset + revertedTipsetKeyCid := []byte("reverted_tipset_key") + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: revertedTipsetKeyCid, + height: 2, + reverted: true, + messageCid: messageCid, + messageIndex: 0, + }) + + // Verify getMsgIdForMsgCidAndTipset doesn't return the message ID for a reverted tipset + err = s.stmts.getMsgIdForMsgCidAndTipsetStmt.QueryRow(revertedTipsetKeyCid, messageCid).Scan(&messageID) + require.Equal(t, sql.ErrNoRows, err) +} + +func TestForeignKeyCascadeDelete(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + // Insert a tipset + messageID := insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + }) + + // Insert an event for the tipset + eventID := insertEvent(t, s, event{ + messageID: messageID, + eventIndex: 0, + emitterAddr: []byte("test_emitter_addr"), + reverted: false, + }) + + // Insert an event entry for the event + insertEventEntry(t, s, eventEntry{ + eventID: eventID, + indexed: true, + flags: []byte("test_flags"), + key: "test_key", + codec: 1, + value: []byte("test_value"), + }) + + // Delete the tipset + res, err := s.db.Exec("DELETE FROM tipset_message WHERE tipset_key_cid = ?", []byte("test_tipset_key")) + require.NoError(t, err) + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + // verify event is deleted + verifyEventAbsent(t, s, eventID) + verifyEventEntryAbsent(t, s, eventID) +} + +func TestInsertTipsetMessage(t *testing.T) { + s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) + require.NoError(t, err) + + ts := tipsetMessage{ + tipsetKeyCid: []byte("test_tipset_key"), + height: 1, + reverted: false, + messageCid: []byte("test_message_cid"), + messageIndex: 0, + } + + // Insert a tipset + messageID := insertTipsetMessage(t, s, ts) + + // revert the tipset + revertTipset(t, s, []byte("test_tipset_key")) + ts.reverted = true + verifyTipsetMessage(t, s, messageID, ts) + + // inserting with the same (tipset, message) should overwrite the reverted flag + res, err := s.stmts.insertTipsetMessageStmt.Exec(ts.tipsetKeyCid, ts.height, true, ts.messageCid, ts.messageIndex) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + ts.reverted = false + verifyTipsetMessage(t, s, messageID, ts) +} + +type tipsetMessage struct { + tipsetKeyCid []byte + height uint64 + reverted bool + messageCid []byte + messageIndex int64 +} + +type event struct { + eventIndex uint64 + emitterAddr []byte + reverted bool + messageID int64 +} + +type eventEntry struct { + eventID int64 + indexed bool + flags []byte + key string + codec int + value []byte +} + +func updateEventsToNonReverted(t *testing.T, s *SqliteIndexer, tsKeyCid []byte) { + res, err := s.stmts.updateEventsToNonRevertedStmt.Exec(tsKeyCid) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + // read all events for this tipset and verify they are not reverted using a COUNT query + var count int + err = s.db.QueryRow("SELECT COUNT(*) FROM event e JOIN tipset_message tm ON e.message_id = tm.message_id WHERE tm.tipset_key_cid = ? AND e.reverted = 1", tsKeyCid).Scan(&count) + require.NoError(t, err) + require.Equal(t, 0, count, "Expected no reverted events for this tipset") +} + +func revertTipset(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte) { + res, err := s.stmts.updateTipsetToRevertedStmt.Exec(tipsetKeyCid) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + var reverted bool + err = s.db.QueryRow("SELECT reverted FROM tipset_message WHERE tipset_key_cid = ?", tipsetKeyCid).Scan(&reverted) + require.NoError(t, err) + require.True(t, reverted) +} + +func verifyTipsetMessage(t *testing.T, s *SqliteIndexer, messageID int64, expectedTipsetMessage tipsetMessage) { + var tipsetKeyCid []byte + var height uint64 + var reverted bool + var messageCid []byte + var messageIndex int64 + err := s.db.QueryRow("SELECT tipset_key_cid, height, reverted, message_cid, message_index FROM tipset_message WHERE message_id = ?", messageID).Scan(&tipsetKeyCid, &height, &reverted, &messageCid, &messageIndex) + require.NoError(t, err) + require.Equal(t, expectedTipsetMessage.tipsetKeyCid, tipsetKeyCid) + require.Equal(t, expectedTipsetMessage.height, height) + require.Equal(t, expectedTipsetMessage.reverted, reverted) + require.Equal(t, expectedTipsetMessage.messageCid, messageCid) + require.Equal(t, expectedTipsetMessage.messageIndex, messageIndex) +} + +func verifyEventEntryAbsent(t *testing.T, s *SqliteIndexer, eventID int64) { + err := s.db.QueryRow("SELECT event_id FROM event_entry WHERE event_id = ?", eventID).Scan(&eventID) + require.Equal(t, sql.ErrNoRows, err) +} + +func verifyEventAbsent(t *testing.T, s *SqliteIndexer, eventID int64) { + var eventIndex uint64 + err := s.db.QueryRow("SELECT event_index FROM event WHERE event_id = ?", eventID).Scan(&eventIndex) + require.Equal(t, sql.ErrNoRows, err) +} + +func verifyEvent(t *testing.T, s *SqliteIndexer, eventID int64, expectedEvent event) { + var eventIndex uint64 + var emitterAddr []byte + var reverted bool + var messageID int64 + err := s.db.QueryRow("SELECT event_index, emitter_addr, reverted, message_id FROM event WHERE event_id = ?", eventID).Scan(&eventIndex, &emitterAddr, &reverted, &messageID) + require.NoError(t, err) + require.Equal(t, expectedEvent.eventIndex, eventIndex) + require.Equal(t, expectedEvent.emitterAddr, emitterAddr) + require.Equal(t, expectedEvent.reverted, reverted) + require.Equal(t, expectedEvent.messageID, messageID) +} + +func verifyCountTipsetsAtHeightStmt(t *testing.T, s *SqliteIndexer, height uint64, expectedRevertedCount, expectedNonRevertedCount int) { + var revertedCount, nonRevertedCount int + err := s.stmts.countTipsetsAtHeightStmt.QueryRow(height).Scan(&revertedCount, &nonRevertedCount) + require.NoError(t, err) + require.Equal(t, expectedRevertedCount, revertedCount) + require.Equal(t, expectedNonRevertedCount, nonRevertedCount) +} + +func verifyHasTipsetStmt(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte, expectedHas bool) { + var has bool + err := s.stmts.hasTipsetStmt.QueryRow(tipsetKeyCid).Scan(&has) + require.NoError(t, err) + require.Equal(t, expectedHas, has) +} + +func verifyHasRevertedEventsInTipsetStmt(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte, expectedHas bool) { + var hasRevertedEventsInTipset bool + err := s.stmts.hasRevertedEventsInTipsetStmt.QueryRow(tipsetKeyCid).Scan(&hasRevertedEventsInTipset) + require.NoError(t, err) + require.Equal(t, expectedHas, hasRevertedEventsInTipset) +} + +func verifyHasNullRoundAtHeightStmt(t *testing.T, s *SqliteIndexer, height uint64, expectedHasNullRound bool) { + var hasNullRound bool + err := s.stmts.hasNullRoundAtHeightStmt.QueryRow(height).Scan(&hasNullRound) + require.NoError(t, err) + require.Equal(t, expectedHasNullRound, hasNullRound) +} + +func verifyNonRevertedMessageCount(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte, expectedCount int) { + var count int + err := s.stmts.getNonRevertedTipsetMessageCountStmt.QueryRow(tipsetKeyCid).Scan(&count) + require.NoError(t, err) + require.Equal(t, expectedCount, count) +} + +func verifyNonRevertedEventCount(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte, expectedCount int) { + var count int + err := s.stmts.getNonRevertedTipsetEventCountStmt.QueryRow(tipsetKeyCid).Scan(&count) + require.NoError(t, err) + require.Equal(t, expectedCount, count) +} + +func verifyNonRevertedEventEntriesCount(t *testing.T, s *SqliteIndexer, tipsetKeyCid []byte, expectedCount int) { + var count int + err := s.stmts.getNonRevertedTipsetEventEntriesCountStmt.QueryRow(tipsetKeyCid).Scan(&count) + require.NoError(t, err) + require.Equal(t, expectedCount, count) +} + +func insertTipsetMessage(t *testing.T, s *SqliteIndexer, ts tipsetMessage) int64 { + res, err := s.stmts.insertTipsetMessageStmt.Exec(ts.tipsetKeyCid, ts.height, ts.reverted, ts.messageCid, ts.messageIndex) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + messageID, err := res.LastInsertId() + require.NoError(t, err) + require.NotEqual(t, int64(0), messageID) + + // read back the message to verify it was inserted correctly + verifyTipsetMessage(t, s, messageID, ts) + + return messageID +} + +func insertEvent(t *testing.T, s *SqliteIndexer, e event) int64 { + res, err := s.stmts.insertEventStmt.Exec(e.messageID, e.eventIndex, e.emitterAddr, e.reverted) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) + + eventID, err := res.LastInsertId() + require.NoError(t, err) + require.NotEqual(t, int64(0), eventID) + + verifyEvent(t, s, eventID, e) + + return eventID +} + +func insertEventEntry(t *testing.T, s *SqliteIndexer, ee eventEntry) { + res, err := s.stmts.insertEventEntryStmt.Exec(ee.eventID, ee.indexed, ee.flags, ee.key, ee.codec, ee.value) + require.NoError(t, err) + + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) +} diff --git a/chain/index/events.go b/chain/index/events.go index d3badeeeff8..31259bcf7d4 100644 --- a/chain/index/events.go +++ b/chain/index/events.go @@ -33,6 +33,9 @@ func (si *SqliteIndexer) indexEvents(ctx context.Context, tx *sql.Tx, msgTs *typ if si.idToRobustAddrFunc == nil { return xerrors.Errorf("indexer can not index events without an address resolver") } + if si.eventLoaderFunc == nil { + return xerrors.Errorf("indexer can not index events without an event loader") + } // check if we have an event indexed for any message in the `msgTs` tipset -> if so, there's nothig to do here // this makes event inserts idempotent @@ -59,7 +62,7 @@ func (si *SqliteIndexer) indexEvents(ctx context.Context, tx *sql.Tx, msgTs *typ return nil } - ems, err := si.loadExecutedMessages(ctx, msgTs, executionTs) + ems, err := si.eventLoaderFunc(ctx, si.cs, msgTs, executionTs) if err != nil { return xerrors.Errorf("failed to load executed messages: %w", err) } @@ -124,13 +127,20 @@ func (si *SqliteIndexer) indexEvents(ctx context.Context, tx *sql.Tx, msgTs *typ return nil } -func (si *SqliteIndexer) loadExecutedMessages(ctx context.Context, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { - msgs, err := si.cs.MessagesForTipset(ctx, msgTs) +func MakeLoadExecutedMessages(recomputeTipSetStateFunc recomputeTipSetStateFunc) func(ctx context.Context, + cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return loadExecutedMessages(ctx, cs, recomputeTipSetStateFunc, msgTs, rctTs) + } +} + +func loadExecutedMessages(ctx context.Context, cs ChainStore, recomputeTipSetStateFunc recomputeTipSetStateFunc, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + msgs, err := cs.MessagesForTipset(ctx, msgTs) if err != nil { return nil, xerrors.Errorf("failed to get messages for tipset: %w", err) } - st := si.cs.ActorStore(ctx) + st := cs.ActorStore(ctx) receiptsArr, err := blockadt.AsArray(st, rctTs.Blocks()[0].ParentMessageReceipts) if err != nil { @@ -163,12 +173,12 @@ func (si *SqliteIndexer) loadExecutedMessages(ctx context.Context, msgTs, rctTs eventsArr, err := amt4.LoadAMT(ctx, st, *rct.EventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth)) if err != nil { - if si.recomputeTipSetStateFunc == nil { + if recomputeTipSetStateFunc == nil { return nil, xerrors.Errorf("failed to load events amt for message %s: %w", ems[i].msg.Cid(), err) } log.Warnf("failed to load events amt for message %s: %s; recomputing tipset state to regenerate events", ems[i].msg.Cid(), err) - if err := si.recomputeTipSetStateFunc(ctx, msgTs); err != nil { + if err := recomputeTipSetStateFunc(ctx, msgTs); err != nil { return nil, xerrors.Errorf("failed to recompute missing events; failed to recompute tipset state: %w", err) } @@ -253,6 +263,9 @@ func (si *SqliteIndexer) getTipsetKeyCidByHeight(ctx context.Context, height abi if err != nil { return nil, xerrors.Errorf("failed to get tipset by height: %w", err) } + if ts == nil { + return nil, xerrors.Errorf("tipset is nil for height: %d", height) + } if ts.Height() != height { // this means that this is a null round diff --git a/chain/index/events_test.go b/chain/index/events_test.go new file mode 100644 index 00000000000..d165efe74a0 --- /dev/null +++ b/chain/index/events_test.go @@ -0,0 +1,238 @@ +package index + +import ( + "context" + "database/sql" + "errors" + pseudo "math/rand" + "testing" + "time" + + "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/chain/types" +) + +func TestGetEventsForFilterNoEvents(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + + headHeight := abi.ChainEpoch(60) + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + + // Create a fake tipset at height 1 + fakeTipSet1 := fakeTipSet(t, rng, 1, nil) + + // Set the dummy chainstore to return this tipset for height 1 + cs.SetTipsetByHeightAndKey(1, fakeTipSet1.Key(), fakeTipSet1) // empty DB + + // tipset is not indexed + f := &EventFilter{ + MinHeight: 1, + MaxHeight: 1, + } + ces, err := si.GetEventsForFilter(ctx, f, false) + require.True(t, errors.Is(err, ErrNotFound)) + require.Equal(t, 0, len(ces)) + + tsCid, err := fakeTipSet1.Key().Cid() + require.NoError(t, err) + f = &EventFilter{ + TipsetCid: tsCid, + } + + ces, err = si.GetEventsForFilter(ctx, f, false) + require.True(t, errors.Is(err, ErrNotFound)) + require.Equal(t, 0, len(ces)) + + // tipset is indexed but has no events + err = withTx(ctx, si.db, func(tx *sql.Tx) error { + return si.indexTipset(ctx, tx, fakeTipSet1) + }) + require.NoError(t, err) + + ces, err = si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 0, len(ces)) + + f = &EventFilter{ + TipsetCid: tsCid, + } + ces, err = si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 0, len(ces)) + + // search for a range that is absent + f = &EventFilter{ + MinHeight: 100, + MaxHeight: 200, + } + ces, err = si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 0, len(ces)) +} + +func TestGetEventsForFilterWithEvents(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(60) + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + + ev1 := fakeEvent( + abi.ActorID(1), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr1")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) + + ev2 := fakeEvent( + abi.ActorID(2), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr2")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) + + events := []types.Event{*ev1, *ev2} + + fm := fakeMessage(address.TestAddress, address.TestAddress) + em1 := executedMessage{ + msg: fm, + evs: events, + } + + si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + idAddr, err := address.NewIDAddress(uint64(emitter)) + if err != nil { + return address.Undef, false + } + + return idAddr, true + }) + + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return []executedMessage{em1}, nil + }) + + // Create a fake tipset at height 1 + fakeTipSet1 := fakeTipSet(t, rng, 1, nil) + fakeTipSet2 := fakeTipSet(t, rng, 2, nil) + + // Set the dummy chainstore to return this tipset for height 1 + cs.SetTipsetByHeightAndKey(1, fakeTipSet1.Key(), fakeTipSet1) // empty DB + cs.SetTipsetByHeightAndKey(2, fakeTipSet2.Key(), fakeTipSet2) // empty DB + + cs.SetMessagesForTipset(fakeTipSet1, []types.ChainMsg{fm}) + + // index tipset and events + require.NoError(t, si.Apply(ctx, fakeTipSet1, fakeTipSet2)) + + // fetch it based on height -> works + f := &EventFilter{ + MinHeight: 1, + MaxHeight: 1, + } + ces, err := si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 2, len(ces)) + + // fetch it based on cid -> works + tsCid1, err := fakeTipSet1.Key().Cid() + require.NoError(t, err) + + tsCid2, err := fakeTipSet2.Key().Cid() + require.NoError(t, err) + + f = &EventFilter{ + TipsetCid: tsCid1, + } + ces, err = si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 2, len(ces)) + + require.Equal(t, ev1.Entries, ces[0].Entries) + require.Equal(t, ev2.Entries, ces[1].Entries) + + // mark fakeTipSet2 as reverted so events for fakeTipSet1 are reverted + require.NoError(t, si.Revert(ctx, fakeTipSet2, fakeTipSet1)) + + var reverted bool + err = si.db.QueryRow("SELECT reverted FROM tipset_message WHERE tipset_key_cid = ?", tsCid2.Bytes()).Scan(&reverted) + require.NoError(t, err) + require.True(t, reverted) + + var reverted2 bool + err = si.db.QueryRow("SELECT reverted FROM tipset_message WHERE tipset_key_cid = ?", tsCid1.Bytes()).Scan(&reverted2) + require.NoError(t, err) + require.False(t, reverted2) + + // fetching events fails if excludeReverted is true + f = &EventFilter{ + TipsetCid: tsCid1, + } + ces, err = si.GetEventsForFilter(ctx, f, true) + require.NoError(t, err) + require.Equal(t, 0, len(ces)) + + // works if excludeReverted is false + ces, err = si.GetEventsForFilter(ctx, f, false) + require.NoError(t, err) + require.Equal(t, 2, len(ces)) +} + +func fakeMessage(to, from address.Address) *types.Message { + return &types.Message{ + To: to, + From: from, + Nonce: 197, + Method: 1, + Params: []byte("some random bytes"), + GasLimit: 126723, + GasPremium: types.NewInt(4), + GasFeeCap: types.NewInt(120), + } +} + +func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event { + ev := &types.Event{ + Emitter: emitter, + } + + for _, in := range indexed { + ev.Entries = append(ev.Entries, types.EventEntry{ + Flags: 0x01, + Key: in.k, + Codec: cid.Raw, + Value: in.v, + }) + } + + for _, in := range unindexed { + ev.Entries = append(ev.Entries, types.EventEntry{ + Flags: 0x00, + Key: in.k, + Codec: cid.Raw, + Value: in.v, + }) + } + + return ev +} + +type kv struct { + k string + v []byte +} diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go new file mode 100644 index 00000000000..2be23240c91 --- /dev/null +++ b/chain/index/gc_test.go @@ -0,0 +1,67 @@ +package index + +import ( + "context" + pseudo "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestGC(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + + // head at height 60 + // insert tipsets at heigh 1,10,50. + // retention epochs is 20 + si, _, _ := setupWithHeadIndexed(t, 60, rng) + si.gcRetentionEpochs = 20 + defer func() { _ = si.Close() }() + + tsCid1 := randomCid(t, rng) + tsCid10 := randomCid(t, rng) + tsCid50 := randomCid(t, rng) + + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: tsCid1.Bytes(), + height: 1, + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: tsCid10.Bytes(), + height: 10, + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: tsCid50.Bytes(), + height: 50, + reverted: false, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + si.gc(ctx) + + // tipset at height 1 and 10 should be removed + var count int + err := si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 1").Scan(&count) + require.NoError(t, err) + require.Equal(t, 0, count) + + err = si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 10").Scan(&count) + require.NoError(t, err) + require.Equal(t, 0, count) + + // tipset at height 50 should not be removed + err = si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 50").Scan(&count) + require.NoError(t, err) + require.Equal(t, 1, count) +} diff --git a/chain/index/helpers.go b/chain/index/helpers.go index 6c5294a5ba7..07bf970569f 100644 --- a/chain/index/helpers.go +++ b/chain/index/helpers.go @@ -3,6 +3,7 @@ package index import ( "context" "database/sql" + "errors" "os" ipld "github.com/ipfs/go-ipld-format" @@ -80,6 +81,9 @@ func PopulateFromSnapshot(ctx context.Context, path string, cs ChainStore) error } func toTipsetKeyCidBytes(ts *types.TipSet) ([]byte, error) { + if ts == nil { + return nil, errors.New("failed to get tipset key cid: tipset is nil") + } tsKeyCid, err := ts.Key().Cid() if err != nil { return nil, xerrors.Errorf("failed to get tipset key cid: %w", err) diff --git a/chain/index/indexer.go b/chain/index/indexer.go index 3607ce1126e..d537ab18fdd 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -22,6 +22,7 @@ var _ Indexer = (*SqliteIndexer)(nil) // IdToRobustAddrFunc is a function type that resolves an actor ID to a robust address type IdToRobustAddrFunc func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) +type eventLoaderFunc func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) type recomputeTipSetStateFunc func(ctx context.Context, ts *types.TipSet) error type preparedStatements struct { @@ -63,8 +64,8 @@ type SqliteIndexer struct { db *sql.DB cs ChainStore - idToRobustAddrFunc IdToRobustAddrFunc - recomputeTipSetStateFunc recomputeTipSetStateFunc + idToRobustAddrFunc IdToRobustAddrFunc + eventLoaderFunc eventLoaderFunc stmts *preparedStatements @@ -144,8 +145,8 @@ func (si *SqliteIndexer) SetIdToRobustAddrFunc(idToRobustAddrFunc IdToRobustAddr si.idToRobustAddrFunc = idToRobustAddrFunc } -func (si *SqliteIndexer) SetRecomputeTipSetStateFunc(recomputeTipSetStateFunc recomputeTipSetStateFunc) { - si.recomputeTipSetStateFunc = recomputeTipSetStateFunc +func (si *SqliteIndexer) SetEventLoaderFunc(eventLoaderFunc eventLoaderFunc) { + si.eventLoaderFunc = eventLoaderFunc } func (si *SqliteIndexer) Close() error { diff --git a/chain/index/indexer_test.go b/chain/index/indexer_test.go new file mode 100644 index 00000000000..4a752772a09 --- /dev/null +++ b/chain/index/indexer_test.go @@ -0,0 +1,54 @@ +package index + +import ( + "context" + "database/sql" + pseudo "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestRestoreTipsetIfExists(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + si, _, _ := setupWithHeadIndexed(t, 10, rng) + + tsKeyCid := randomCid(t, rng) + tsKeyCidBytes := tsKeyCid.Bytes() + + err := withTx(ctx, si.db, func(tx *sql.Tx) error { + // tipset does not exist + exists, err := si.restoreTipsetIfExists(ctx, tx, tsKeyCidBytes) + require.NoError(t, err) + require.False(t, exists) + + // insert reverted tipset + _, err = tx.Stmt(si.stmts.insertTipsetMessageStmt).Exec(tsKeyCidBytes, 1, 1, randomCid(t, rng).Bytes(), 0) + require.NoError(t, err) + + // tipset exists and is NOT reverted + exists, err = si.restoreTipsetIfExists(ctx, tx, tsKeyCidBytes) + require.NoError(t, err) + require.True(t, exists) + + // Verify that the tipset is not reverted + var reverted bool + err = tx.QueryRow("SELECT reverted FROM tipset_message WHERE tipset_key_cid = ?", tsKeyCidBytes).Scan(&reverted) + require.NoError(t, err) + require.False(t, reverted, "Tipset should not be reverted") + + return nil + }) + require.NoError(t, err) + + exists, err := si.isTipsetIndexed(ctx, tsKeyCidBytes) + require.NoError(t, err) + require.True(t, exists) + + fc := randomCid(t, rng) + exists, err = si.isTipsetIndexed(ctx, fc.Bytes()) + require.NoError(t, err) + require.False(t, exists) +} diff --git a/chain/index/interface.go b/chain/index/interface.go index 1dd84e7f5d1..76a3831a019 100644 --- a/chain/index/interface.go +++ b/chain/index/interface.go @@ -56,7 +56,8 @@ type Indexer interface { IndexEthTxHash(ctx context.Context, txHash ethtypes.EthHash, c cid.Cid) error SetIdToRobustAddrFunc(idToRobustAddrFunc IdToRobustAddrFunc) - SetRecomputeTipSetStateFunc(recomputeTipSetStateFunc recomputeTipSetStateFunc) + SetEventLoaderFunc(eventLoaderFunc eventLoaderFunc) + Apply(ctx context.Context, from, to *types.TipSet) error Revert(ctx context.Context, from, to *types.TipSet) error diff --git a/chain/index/read_test.go b/chain/index/read_test.go new file mode 100644 index 00000000000..c7a6797d0bf --- /dev/null +++ b/chain/index/read_test.go @@ -0,0 +1,303 @@ +package index + +import ( + "context" + "errors" + pseudo "math/rand" + "sync" + "testing" + "time" + + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/crypto" + + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" +) + +func TestGetCidFromHash(t *testing.T) { + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + ctx := context.Background() + + s, _, _ := setupWithHeadIndexed(t, 10, rng) + + ethTxHash := ethtypes.EthHash([32]byte{1}) + msgCid := randomCid(t, rng) + + // read from empty db -> ErrNotFound + c, err := s.GetCidFromHash(ctx, ethTxHash) + require.Error(t, err) + require.True(t, errors.Is(err, ErrNotFound)) + require.EqualValues(t, cid.Undef, c) + + // insert and read + insertEthTxHash(t, s, ethTxHash, msgCid) + c, err = s.GetCidFromHash(ctx, ethTxHash) + require.NoError(t, err) + require.EqualValues(t, msgCid, c) + + // look up some other hash -> fails + c, err = s.GetCidFromHash(ctx, ethtypes.EthHash([32]byte{2})) + require.Error(t, err) + require.True(t, errors.Is(err, ErrNotFound)) + require.EqualValues(t, cid.Undef, c) +} + +func TestGetMsgInfo(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + s, _, _ := setupWithHeadIndexed(t, 10, rng) + + msgCid := randomCid(t, rng) + + // read from empty db -> ErrNotFound + mi, err := s.GetMsgInfo(ctx, msgCid) + require.Error(t, err) + require.True(t, errors.Is(err, ErrNotFound)) + require.Nil(t, mi) + + msgCidBytes := msgCid.Bytes() + tsKeyCid := randomCid(t, rng) + // insert and read + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: tsKeyCid.Bytes(), + height: uint64(1), + reverted: false, + messageCid: msgCidBytes, + messageIndex: 1, + }) + mi, err = s.GetMsgInfo(ctx, msgCid) + require.NoError(t, err) + require.Equal(t, msgCid, mi.Message) + require.Equal(t, tsKeyCid, mi.TipSet) + require.Equal(t, abi.ChainEpoch(1), mi.Epoch) +} + +func setupWithHeadIndexed(t *testing.T, headHeight abi.ChainEpoch, rng *pseudo.Rand) (*SqliteIndexer, *types.TipSet, *dummyChainStore) { + head := fakeTipSet(t, rng, headHeight, []cid.Cid{}) + d := newDummyChainStore() + d.SetHeaviestTipSet(head) + + s, err := NewSqliteIndexer(":memory:", d, 0, false, 0) + require.NoError(t, err) + insertHead(t, s, head, headHeight) + + return s, head, d +} + +func insertHead(t *testing.T, s *SqliteIndexer, head *types.TipSet, height abi.ChainEpoch) { + headKeyBytes, err := toTipsetKeyCidBytes(head) + require.NoError(t, err) + + insertTipsetMessage(t, s, tipsetMessage{ + tipsetKeyCid: headKeyBytes, + height: uint64(height), + reverted: false, + messageCid: nil, + messageIndex: -1, + }) +} + +func insertEthTxHash(t *testing.T, s *SqliteIndexer, ethTxHash ethtypes.EthHash, messageCid cid.Cid) { + msgCidBytes := messageCid.Bytes() + + res, err := s.stmts.insertEthTxHashStmt.Exec(ethTxHash.String(), msgCidBytes) + require.NoError(t, err) + rowsAffected, err := res.RowsAffected() + require.NoError(t, err) + require.Equal(t, int64(1), rowsAffected) +} + +type dummyChainStore struct { + mu sync.RWMutex + + heightToTipSet map[abi.ChainEpoch]*types.TipSet + messagesForTipset map[*types.TipSet][]types.ChainMsg + keyToTipSet map[types.TipSetKey]*types.TipSet + + heaviestTipSet *types.TipSet + tipSetByCid func(ctx context.Context, tsKeyCid cid.Cid) (*types.TipSet, error) + messagesForBlock func(ctx context.Context, b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) + actorStore func(ctx context.Context) adt.Store +} + +func newDummyChainStore() *dummyChainStore { + return &dummyChainStore{ + heightToTipSet: make(map[abi.ChainEpoch]*types.TipSet), + messagesForTipset: make(map[*types.TipSet][]types.ChainMsg), + keyToTipSet: make(map[types.TipSetKey]*types.TipSet), + } +} + +func (d *dummyChainStore) MessagesForTipset(ctx context.Context, ts *types.TipSet) ([]types.ChainMsg, error) { + d.mu.RLock() + defer d.mu.RUnlock() + + msgs, ok := d.messagesForTipset[ts] + if !ok { + return nil, nil + } + return msgs, nil +} + +func (d *dummyChainStore) GetHeaviestTipSet() *types.TipSet { + d.mu.RLock() + defer d.mu.RUnlock() + return d.heaviestTipSet +} + +func (d *dummyChainStore) GetTipSetByCid(ctx context.Context, tsKeyCid cid.Cid) (*types.TipSet, error) { + d.mu.RLock() + defer d.mu.RUnlock() + if d.tipSetByCid != nil { + return d.tipSetByCid(ctx, tsKeyCid) + } + return nil, nil +} + +func (d *dummyChainStore) GetTipSetFromKey(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) { + d.mu.RLock() + defer d.mu.RUnlock() + + return d.keyToTipSet[tsk], nil +} + +func (d *dummyChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { + d.mu.RLock() + defer d.mu.RUnlock() + if d.messagesForBlock != nil { + return d.messagesForBlock(ctx, b) + } + return nil, nil, nil +} + +func (d *dummyChainStore) ActorStore(ctx context.Context) adt.Store { + d.mu.RLock() + defer d.mu.RUnlock() + if d.actorStore != nil { + return d.actorStore(ctx) + } + return nil +} + +func (d *dummyChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, _ *types.TipSet, prev bool) (*types.TipSet, error) { + d.mu.RLock() + defer d.mu.RUnlock() + + ts, ok := d.heightToTipSet[h] + if !ok { + return nil, errors.New("tipset not found") + } + return ts, nil +} + +func (d *dummyChainStore) IsStoringEvents() bool { + return true +} + +// Setter methods to configure the mock + +func (d *dummyChainStore) SetMessagesForTipset(ts *types.TipSet, msgs []types.ChainMsg) { + d.mu.Lock() + defer d.mu.Unlock() + d.messagesForTipset[ts] = msgs +} + +func (d *dummyChainStore) SetHeaviestTipSet(ts *types.TipSet) { + d.mu.Lock() + defer d.mu.Unlock() + d.heaviestTipSet = ts +} + +func (d *dummyChainStore) SetTipSetByCid(f func(ctx context.Context, tsKeyCid cid.Cid) (*types.TipSet, error)) { + d.mu.Lock() + defer d.mu.Unlock() + d.tipSetByCid = f +} + +func (d *dummyChainStore) SetMessagesForBlock(f func(ctx context.Context, b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)) { + d.mu.Lock() + defer d.mu.Unlock() + d.messagesForBlock = f +} + +func (d *dummyChainStore) SetActorStore(f func(ctx context.Context) adt.Store) { + d.mu.Lock() + defer d.mu.Unlock() + d.actorStore = f +} + +func (d *dummyChainStore) SetTipsetByHeightAndKey(h abi.ChainEpoch, tsk types.TipSetKey, ts *types.TipSet) { + d.mu.Lock() + defer d.mu.Unlock() + + d.heightToTipSet[h] = ts + d.keyToTipSet[tsk] = ts +} + +func randomIDAddr(tb testing.TB, rng *pseudo.Rand) address.Address { + tb.Helper() + addr, err := address.NewIDAddress(uint64(rng.Int63())) + require.NoError(tb, err) + return addr +} + +func randomCid(tb testing.TB, rng *pseudo.Rand) cid.Cid { + tb.Helper() + cb := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY} + c, err := cb.Sum(randomBytes(10, rng)) + require.NoError(tb, err) + return c +} + +func randomBytes(n int, rng *pseudo.Rand) []byte { + buf := make([]byte, n) + rng.Read(buf) + return buf +} + +func fakeTipSet(tb testing.TB, rng *pseudo.Rand, h abi.ChainEpoch, parents []cid.Cid) *types.TipSet { + tb.Helper() + ts, err := types.NewTipSet([]*types.BlockHeader{ + { + Height: h, + Miner: randomIDAddr(tb, rng), + + Parents: parents, + + Ticket: &types.Ticket{VRFProof: []byte{byte(h % 2)}}, + + ParentStateRoot: randomCid(tb, rng), + Messages: randomCid(tb, rng), + ParentMessageReceipts: randomCid(tb, rng), + + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS}, + }, + { + Height: h, + Miner: randomIDAddr(tb, rng), + + Parents: parents, + + Ticket: &types.Ticket{VRFProof: []byte{byte((h + 1) % 2)}}, + + ParentStateRoot: randomCid(tb, rng), + Messages: randomCid(tb, rng), + ParentMessageReceipts: randomCid(tb, rng), + + BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS}, + BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS}, + }, + }) + + require.NoError(tb, err) + + return ts +} diff --git a/node/modules/chainindex.go b/node/modules/chainindex.go index 250d82873f8..59e2af3c119 100644 --- a/node/modules/chainindex.go +++ b/node/modules/chainindex.go @@ -35,9 +35,8 @@ func ChainIndexer(cfg config.ChainIndexerConfig) func(lc fx.Lifecycle, mctx help return nil, err } - // TODO Implement config driven auto-backfilling - chainIndexer, err := index.NewSqliteIndexer(filepath.Join(chainIndexPath, index.DefaultDbFilename), - cs, cfg.GCRetentionEpochs, cfg.ReconcileEmptyIndex, cfg.MaxReconcileTipsets) + dbPath := filepath.Join(chainIndexPath, index.DefaultDbFilename) + chainIndexer, err := index.NewSqliteIndexer(dbPath, cs, cfg.GCRetentionEpochs, cfg.ReconcileEmptyIndex, cfg.MaxReconcileTipsets) if err != nil { return nil, err } @@ -72,11 +71,13 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In return *actor.DelegatedAddress, true }) - indexer.SetRecomputeTipSetStateFunc(func(ctx context.Context, ts *types.TipSet) error { + eventLoaderFunc := index.MakeLoadExecutedMessages(func(ctx context.Context, ts *types.TipSet) error { _, _, err := sm.RecomputeTipSetState(ctx, ts) return err }) + indexer.SetEventLoaderFunc(eventLoaderFunc) + ch, err := mp.Updates(ctx) if err != nil { return err From 5e6ae08831ed25e84b9e9fc5ad177a5408c57637 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 4 Oct 2024 12:15:43 +0400 Subject: [PATCH 26/61] cleanup reverted tipsets to avoid db bloat --- chain/index/ddls.go | 1 + chain/index/gc.go | 36 ++++++++++++++++++++++++ chain/index/gc_test.go | 62 ++++++++++++++++++++++++++++++++++++++++++ chain/index/indexer.go | 1 + 4 files changed, 100 insertions(+) diff --git a/chain/index/ddls.go b/chain/index/ddls.go index 5acfb8b87be..813f87ee91f 100644 --- a/chain/index/ddls.go +++ b/chain/index/ddls.go @@ -85,5 +85,6 @@ func preparedStatementMapping(ps *preparedStatements) map[**sql.Stmt]string { &ps.getNonRevertedTipsetEventCountStmt: "SELECT COUNT(*) FROM event WHERE reverted = 0 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ? AND reverted = 0)", &ps.hasRevertedEventsInTipsetStmt: "SELECT EXISTS(SELECT 1 FROM event WHERE reverted = 1 AND message_id IN (SELECT message_id FROM tipset_message WHERE tipset_key_cid = ?))", &ps.getNonRevertedTipsetEventEntriesCountStmt: "SELECT COUNT(ee.event_id) AS entry_count FROM event_entry ee JOIN event e ON ee.event_id = e.event_id JOIN tipset_message tm ON e.message_id = tm.message_id WHERE tm.tipset_key_cid = ? AND tm.reverted = 0", + &ps.removeRevertedTipsetsBeforeHeightStmt: "DELETE FROM tipset_message WHERE reverted = 1 AND height < ?", } } diff --git a/chain/index/gc.go b/chain/index/gc.go index 727944e3142..a7957da8504 100644 --- a/chain/index/gc.go +++ b/chain/index/gc.go @@ -8,6 +8,7 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/policy" ) var ( @@ -20,6 +21,7 @@ func (si *SqliteIndexer) gcLoop() { // Initial cleanup before entering the loop si.gc(si.ctx) + si.cleanUpRevertedTipsets(si.ctx) cleanupTicker := time.NewTicker(cleanupInterval) defer cleanupTicker.Stop() @@ -32,12 +34,46 @@ func (si *SqliteIndexer) gcLoop() { select { case <-cleanupTicker.C: si.gc(si.ctx) + si.cleanUpRevertedTipsets(si.ctx) case <-si.ctx.Done(): return } } } +func (si *SqliteIndexer) cleanUpRevertedTipsets(ctx context.Context) { + si.writerLk.Lock() + defer si.writerLk.Unlock() + + log.Info("starting cleanup of reverted tipsets") + + head := si.cs.GetHeaviestTipSet() + if head == nil { + log.Warn("no head found, skipping reverted tipset cleanup") + return + } + + removalEpoch := head.Height() - (3 * policy.ChainFinality) + if removalEpoch <= 0 { + log.Info("no applicable reverted tipsets to remove; skipping reverted tipset cleanup") + return + } + + res, err := si.stmts.removeRevertedTipsetsBeforeHeightStmt.ExecContext(ctx, removalEpoch) + if err != nil { + log.Errorw("failed to remove reverted tipsets before height", "height", removalEpoch, "error", err) + return + } + + rows, err := res.RowsAffected() + if err != nil { + log.Errorw("failed to get rows affected for reverted tipsets cleanup", "error", err) + return + } + + log.Infof("removed %d reverted tipsets before epoch %d", rows, removalEpoch) +} + func (si *SqliteIndexer) gc(ctx context.Context) { si.writerLk.Lock() defer si.writerLk.Unlock() diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index 2be23240c91..709f5672268 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -7,8 +7,70 @@ import ( "time" "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/abi" ) +func TestCleanupRevertedTipsets(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + + tests := []struct { + name string + headHeight int64 + revertedHeight uint64 + expectRemoved bool + }{ + { + name: "reverted tipset within finality, should not be removed", + headHeight: 1000, + revertedHeight: 980, + expectRemoved: false, + }, + { + name: "reverted tipset outside finality, should be removed", + headHeight: 5000, + revertedHeight: 400, + expectRemoved: true, + }, + { + name: "not enough tipsets", + headHeight: 2000, + revertedHeight: 1, + expectRemoved: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + si, _, _ := setupWithHeadIndexed(t, abi.ChainEpoch(tt.headHeight), rng) + si.gcRetentionEpochs = 0 + defer func() { _ = si.Close() }() + + revertedTsCid := randomCid(t, rng) + insertTipsetMessage(t, si, tipsetMessage{ + tipsetKeyCid: revertedTsCid.Bytes(), + height: tt.revertedHeight, + reverted: true, + messageCid: randomCid(t, rng).Bytes(), + messageIndex: 0, + }) + + si.cleanUpRevertedTipsets(ctx) + + var count int + err := si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = ?", tt.revertedHeight).Scan(&count) + require.NoError(t, err) + + if tt.expectRemoved { + require.Equal(t, 0, count, "expected reverted tipset to be removed") + } else { + require.Equal(t, 1, count, "expected reverted tipset to not be removed") + } + }) + } +} + func TestGC(t *testing.T) { ctx := context.Background() rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) diff --git a/chain/index/indexer.go b/chain/index/indexer.go index d537ab18fdd..e464b1764c5 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -54,6 +54,7 @@ type preparedStatements struct { getNonRevertedTipsetEventCountStmt *sql.Stmt getNonRevertedTipsetEventEntriesCountStmt *sql.Stmt hasRevertedEventsInTipsetStmt *sql.Stmt + removeRevertedTipsetsBeforeHeightStmt *sql.Stmt } type SqliteIndexer struct { From 9511c469501811fbd3db744d9e79391a0a1b8e0e Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 4 Oct 2024 12:29:07 +0400 Subject: [PATCH 27/61] fix logging --- chain/index/gc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/index/gc.go b/chain/index/gc.go index a7957da8504..aee64528fe8 100644 --- a/chain/index/gc.go +++ b/chain/index/gc.go @@ -71,7 +71,7 @@ func (si *SqliteIndexer) cleanUpRevertedTipsets(ctx context.Context) { return } - log.Infof("removed %d reverted tipsets before epoch %d", rows, removalEpoch) + log.Infof("removed %d reverted entries before epoch %d", rows, removalEpoch) } func (si *SqliteIndexer) gc(ctx context.Context) { @@ -106,7 +106,7 @@ func (si *SqliteIndexer) gc(ctx context.Context) { return } - log.Infof("gc'd %d tipsets before epoch %d", rows, removalEpoch) + log.Infof("gc'd %d entries before epoch %d", rows, removalEpoch) // ------------------------------------------------------------------------------------------------- // Also GC eth hashes From 2194dcb782e2c3da96487d09280b25ec72622a7b Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 4 Oct 2024 15:09:51 +0400 Subject: [PATCH 28/61] test for filter by address --- chain/index/events_test.go | 120 +++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/chain/index/events_test.go b/chain/index/events_test.go index d165efe74a0..bfab3410978 100644 --- a/chain/index/events_test.go +++ b/chain/index/events_test.go @@ -193,6 +193,126 @@ func TestGetEventsForFilterWithEvents(t *testing.T) { require.Equal(t, 2, len(ces)) } +func TestGetEventsFilterByAddress(t *testing.T) { + ctx := context.Background() + rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(60) + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() + + addr1, err := address.NewIDAddress(1) + require.NoError(t, err) + addr2, err := address.NewIDAddress(2) + require.NoError(t, err) + addr3, err := address.NewIDAddress(3) + require.NoError(t, err) + + ev1 := fakeEvent( + abi.ActorID(1), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr1")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) + + ev2 := fakeEvent( + abi.ActorID(2), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr2")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) + + events := []types.Event{*ev1, *ev2} + + fm := fakeMessage(address.TestAddress, address.TestAddress) + em1 := executedMessage{ + msg: fm, + evs: events, + } + + si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + idAddr, err := address.NewIDAddress(uint64(emitter)) + if err != nil { + return address.Undef, false + } + return idAddr, true + }) + + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + return []executedMessage{em1}, nil + }) + + // Create a fake tipset at height 1 + fakeTipSet1 := fakeTipSet(t, rng, 1, nil) + fakeTipSet2 := fakeTipSet(t, rng, 2, nil) + + // Set the dummy chainstore to return this tipset for height 1 + cs.SetTipsetByHeightAndKey(1, fakeTipSet1.Key(), fakeTipSet1) // empty DB + cs.SetTipsetByHeightAndKey(2, fakeTipSet2.Key(), fakeTipSet2) // empty DB + + cs.SetMessagesForTipset(fakeTipSet1, []types.ChainMsg{fm}) + + require.NoError(t, si.Apply(ctx, fakeTipSet1, fakeTipSet2)) + + testCases := []struct { + name string + f *EventFilter + expectedCount int + }{ + { + name: "matching single address", + f: &EventFilter{ + Addresses: []address.Address{addr1}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 1, + }, + { + name: "matching multiple addresses", + f: &EventFilter{ + Addresses: []address.Address{addr1, addr2}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 2, + }, + { + name: "no matching address", + f: &EventFilter{ + Addresses: []address.Address{addr3}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 0, + }, + { + name: "empty address list", + f: &EventFilter{ + Addresses: []address.Address{}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 2, // should return all events + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ces, err := si.GetEventsForFilter(ctx, tc.f, false) + require.NoError(t, err) + require.Equal(t, tc.expectedCount, len(ces)) + }) + } +} + func fakeMessage(to, from address.Address) *types.Message { return &types.Message{ To: to, From 62f59d34cb5b4dcbd24d9aa61711fa06523a6984 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 12:57:27 +0400 Subject: [PATCH 29/61] test gc cascade delete --- chain/index/gc_test.go | 108 +++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 30 deletions(-) diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index 709f5672268..eebc44f6625 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -8,7 +8,9 @@ import ( "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/types" ) func TestCleanupRevertedTipsets(t *testing.T) { @@ -74,55 +76,101 @@ func TestCleanupRevertedTipsets(t *testing.T) { func TestGC(t *testing.T) { ctx := context.Background() rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + headHeight := abi.ChainEpoch(60) + si, _, cs := setupWithHeadIndexed(t, headHeight, rng) + defer func() { _ = si.Close() }() - // head at height 60 - // insert tipsets at heigh 1,10,50. - // retention epochs is 20 - si, _, _ := setupWithHeadIndexed(t, 60, rng) si.gcRetentionEpochs = 20 - defer func() { _ = si.Close() }() - tsCid1 := randomCid(t, rng) - tsCid10 := randomCid(t, rng) - tsCid50 := randomCid(t, rng) + ev1 := fakeEvent( + abi.ActorID(1), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr1")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) - insertTipsetMessage(t, si, tipsetMessage{ - tipsetKeyCid: tsCid1.Bytes(), - height: 1, - reverted: false, - messageCid: randomCid(t, rng).Bytes(), - messageIndex: 0, - }) + ev2 := fakeEvent( + abi.ActorID(2), + []kv{ + {k: "type", v: []byte("approval")}, + {k: "signer", v: []byte("addr2")}, + }, + []kv{ + {k: "amount", v: []byte("2988181")}, + }, + ) + + events := []types.Event{*ev1, *ev2} + + fm := fakeMessage(address.TestAddress, address.TestAddress) + em1 := executedMessage{ + msg: fm, + evs: events, + } - insertTipsetMessage(t, si, tipsetMessage{ - tipsetKeyCid: tsCid10.Bytes(), - height: 10, - reverted: false, - messageCid: randomCid(t, rng).Bytes(), - messageIndex: 0, + si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + idAddr, err := address.NewIDAddress(uint64(emitter)) + if err != nil { + return address.Undef, false + } + + return idAddr, true }) - insertTipsetMessage(t, si, tipsetMessage{ - tipsetKeyCid: tsCid50.Bytes(), - height: 50, - reverted: false, - messageCid: randomCid(t, rng).Bytes(), - messageIndex: 0, + si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + if msgTs.Height() == 1 { + return []executedMessage{em1}, nil + } + return nil, nil }) + // Create a fake tipset at height 1 + fakeTipSet1 := fakeTipSet(t, rng, 1, nil) + fakeTipSet2 := fakeTipSet(t, rng, 10, nil) + fakeTipSet3 := fakeTipSet(t, rng, 50, nil) + + // Set the dummy chainstore to return this tipset for height 1 + cs.SetTipsetByHeightAndKey(1, fakeTipSet1.Key(), fakeTipSet1) // empty DB + cs.SetTipsetByHeightAndKey(10, fakeTipSet2.Key(), fakeTipSet2) // empty DB + cs.SetTipsetByHeightAndKey(50, fakeTipSet3.Key(), fakeTipSet3) // empty DB + + cs.SetMessagesForTipset(fakeTipSet1, []types.ChainMsg{fm}) + + // index tipset and events + require.NoError(t, si.Apply(ctx, fakeTipSet1, fakeTipSet2)) + require.NoError(t, si.Apply(ctx, fakeTipSet2, fakeTipSet3)) + + // getLogs works for height 1 + filter := &EventFilter{ + MinHeight: 1, + MaxHeight: 1, + } + ces, err := si.GetEventsForFilter(ctx, filter, false) + require.NoError(t, err) + require.Len(t, ces, 2) + si.gc(ctx) - // tipset at height 1 and 10 should be removed + // getLogs does not work for height 1 + _, err = si.GetEventsForFilter(ctx, filter, false) + require.Error(t, err) + + // Verify that the tipset at height 1 is removed var count int - err := si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 1").Scan(&count) + err = si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 1").Scan(&count) require.NoError(t, err) require.Equal(t, 0, count) + // Verify that the tipset at height 10 is not removed err = si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 10").Scan(&count) require.NoError(t, err) require.Equal(t, 0, count) - // tipset at height 50 should not be removed + // Verify that the tipset at height 50 is not removed err = si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = 50").Scan(&count) require.NoError(t, err) require.Equal(t, 1, count) From 688ab72d15ec4e1f94a79c19cc13e7acd98765de Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 15:07:43 +0400 Subject: [PATCH 30/61] fix db locked error during backfilling --- chain/index/api.go | 3 +++ cmd/lotus-shed/chain_index.go | 4 ++-- lib/sqlite/sqlite.go | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 72c1aaa8e15..4832e06a694 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -121,6 +121,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } indexedData, err := getAndVerifyIndexedData() + var backfill bool if err != nil { if !backfill { return nil, xerrors.Errorf("failed to verify indexed data at height %d: %w", expectedTs.Height(), err) @@ -135,6 +136,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if err != nil { return nil, xerrors.Errorf("failed to verify indexed data at height %d after backfill: %w", expectedTs.Height(), err) } + backfill = true } return &types.IndexValidation{ @@ -143,6 +145,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), IndexedEventEntriesCount: uint64(indexedData.nonRevertedEventEntriesCount), + Backfilled: backfill, }, nil } diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 0aab0431002..37daedeb9fc 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -135,8 +135,8 @@ like cron. if (fromEpoch-epoch+1)%2880 == 0 || epoch == toEpoch { progress := float64(fromEpoch-epoch+1) / float64(totalEpochs) * 100 elapsed := time.Since(startTime) - _, _ = fmt.Fprintf(cctx.App.Writer, "%s -------- Chain index validation progress: %.2f%%; Time elapsed: %s Minutes\n", - currentTimeString(), progress, elapsed.Round(time.Minute)) + _, _ = fmt.Fprintf(cctx.App.Writer, "%s -------- Chain index validation progress: %.2f%%; Time elapsed: %s\n", + currentTimeString(), progress, elapsed) } indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) diff --git a/lib/sqlite/sqlite.go b/lib/sqlite/sqlite.go index 96d3b5fa9ba..d9050c0924f 100644 --- a/lib/sqlite/sqlite.go +++ b/lib/sqlite/sqlite.go @@ -28,6 +28,7 @@ var pragmas = []string{ "PRAGMA journal_mode = WAL", "PRAGMA journal_size_limit = 0", // always reset journal and wal files "PRAGMA foreign_keys = ON", + "PRAGMA busy_timeout = 1500", } const metaTableDdl = `CREATE TABLE IF NOT EXISTS _meta ( From 9a64de7625fb4307942478296fc5ccc209a35308 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 15:11:37 +0400 Subject: [PATCH 31/61] fix var name --- chain/index/api.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 4832e06a694..fd25c35c741 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -121,7 +121,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } indexedData, err := getAndVerifyIndexedData() - var backfill bool + var bf bool if err != nil { if !backfill { return nil, xerrors.Errorf("failed to verify indexed data at height %d: %w", expectedTs.Height(), err) @@ -136,7 +136,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if err != nil { return nil, xerrors.Errorf("failed to verify indexed data at height %d after backfill: %w", expectedTs.Height(), err) } - backfill = true + bf = true } return &types.IndexValidation{ @@ -145,7 +145,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), IndexedEventEntriesCount: uint64(indexedData.nonRevertedEventEntriesCount), - Backfilled: backfill, + Backfilled: bf, }, nil } From 1d7af842b4a79a659ea0b7c36c26a78a937ce40b Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 16:20:23 +0400 Subject: [PATCH 32/61] increase db locked timeout --- lib/sqlite/sqlite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sqlite/sqlite.go b/lib/sqlite/sqlite.go index d9050c0924f..5e5aacc1e3b 100644 --- a/lib/sqlite/sqlite.go +++ b/lib/sqlite/sqlite.go @@ -28,7 +28,7 @@ var pragmas = []string{ "PRAGMA journal_mode = WAL", "PRAGMA journal_size_limit = 0", // always reset journal and wal files "PRAGMA foreign_keys = ON", - "PRAGMA busy_timeout = 1500", + "PRAGMA busy_timeout = 5000", } const metaTableDdl = `CREATE TABLE IF NOT EXISTS _meta ( From d4606e7c286cd27a9b3b9b6dfe93305b3bde656f Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 16:31:34 +0400 Subject: [PATCH 33/61] fix db locked issue --- chain/index/api.go | 33 +++++++++++++++++++++++---------- chain/index/gc_test.go | 1 + 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index fd25c35c741..0f5e6032f1a 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -4,6 +4,8 @@ import ( "context" "database/sql" "errors" + "strings" + "time" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -284,20 +286,31 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti return nil, xerrors.Errorf("failed to get next tipset at height %d: %w", ts.Height(), err) } - err = withTx(ctx, si.db, func(tx *sql.Tx) error { - if err := si.indexTipsetWithParentEvents(ctx, tx, ts, executionTs); err != nil { - return xerrors.Errorf("error indexing (ts, executionTs): %w", err) - } + backfillFunc := func() error { + return withTx(ctx, si.db, func(tx *sql.Tx) error { + if err := si.indexTipsetWithParentEvents(ctx, tx, ts, executionTs); err != nil { + return xerrors.Errorf("error indexing (ts, executionTs): %w", err) + } - if err := si.indexTipsetWithParentEvents(ctx, tx, parentTs, ts); err != nil { - return xerrors.Errorf("error indexing (parentTs, ts): %w", err) - } + if err := si.indexTipsetWithParentEvents(ctx, tx, parentTs, ts); err != nil { + return xerrors.Errorf("error indexing (parentTs, ts): %w", err) + } - return nil - }) + return nil + }) + } + err = backfillFunc() + if err != nil && strings.Contains(err.Error(), "database is locked") { + log.Warnf("backfill of height %d failed due to database lock, retrying in 100ms", ts.Height()) + time.Sleep(100 * time.Millisecond) + err = backfillFunc() + if err == nil { + log.Infof("backfill of height %d succeeded after retry", ts.Height()) + } + } if err != nil { - return nil, xerrors.Errorf("failed to backfill tipset a: %w", err) + return nil, xerrors.Errorf("failed to backfill tipset: %w", err) } indexedData, err := si.getIndexedTipSetData(ctx, ts) diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index eebc44f6625..5ad4e75541f 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -10,6 +10,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/types" ) From 5f541b9841b51fc20ec729326231e850bd2292fc Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 7 Oct 2024 16:32:26 +0400 Subject: [PATCH 34/61] reduce db lock timeout --- lib/sqlite/sqlite.go | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/sqlite/sqlite.go b/lib/sqlite/sqlite.go index 5e5aacc1e3b..96d3b5fa9ba 100644 --- a/lib/sqlite/sqlite.go +++ b/lib/sqlite/sqlite.go @@ -28,7 +28,6 @@ var pragmas = []string{ "PRAGMA journal_mode = WAL", "PRAGMA journal_size_limit = 0", // always reset journal and wal files "PRAGMA foreign_keys = ON", - "PRAGMA busy_timeout = 5000", } const metaTableDdl = `CREATE TABLE IF NOT EXISTS _meta ( From c2238029c3b422c8d03cade39877239d2e40aba8 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 8 Oct 2024 19:02:35 +0400 Subject: [PATCH 35/61] no lock in gc --- chain/index/gc.go | 39 --------------------------- chain/index/gc_test.go | 60 ------------------------------------------ 2 files changed, 99 deletions(-) diff --git a/chain/index/gc.go b/chain/index/gc.go index aee64528fe8..5a7377e7263 100644 --- a/chain/index/gc.go +++ b/chain/index/gc.go @@ -8,7 +8,6 @@ import ( logging "github.com/ipfs/go-log/v2" "github.com/filecoin-project/lotus/chain/actors/builtin" - "github.com/filecoin-project/lotus/chain/actors/policy" ) var ( @@ -21,7 +20,6 @@ func (si *SqliteIndexer) gcLoop() { // Initial cleanup before entering the loop si.gc(si.ctx) - si.cleanUpRevertedTipsets(si.ctx) cleanupTicker := time.NewTicker(cleanupInterval) defer cleanupTicker.Stop() @@ -34,50 +32,13 @@ func (si *SqliteIndexer) gcLoop() { select { case <-cleanupTicker.C: si.gc(si.ctx) - si.cleanUpRevertedTipsets(si.ctx) case <-si.ctx.Done(): return } } } -func (si *SqliteIndexer) cleanUpRevertedTipsets(ctx context.Context) { - si.writerLk.Lock() - defer si.writerLk.Unlock() - - log.Info("starting cleanup of reverted tipsets") - - head := si.cs.GetHeaviestTipSet() - if head == nil { - log.Warn("no head found, skipping reverted tipset cleanup") - return - } - - removalEpoch := head.Height() - (3 * policy.ChainFinality) - if removalEpoch <= 0 { - log.Info("no applicable reverted tipsets to remove; skipping reverted tipset cleanup") - return - } - - res, err := si.stmts.removeRevertedTipsetsBeforeHeightStmt.ExecContext(ctx, removalEpoch) - if err != nil { - log.Errorw("failed to remove reverted tipsets before height", "height", removalEpoch, "error", err) - return - } - - rows, err := res.RowsAffected() - if err != nil { - log.Errorw("failed to get rows affected for reverted tipsets cleanup", "error", err) - return - } - - log.Infof("removed %d reverted entries before epoch %d", rows, removalEpoch) -} - func (si *SqliteIndexer) gc(ctx context.Context) { - si.writerLk.Lock() - defer si.writerLk.Unlock() - if si.gcRetentionEpochs <= 0 { log.Info("gc retention epochs is not set, skipping gc") return diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index 5ad4e75541f..4099bd9b5e9 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -14,66 +14,6 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func TestCleanupRevertedTipsets(t *testing.T) { - ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) - - tests := []struct { - name string - headHeight int64 - revertedHeight uint64 - expectRemoved bool - }{ - { - name: "reverted tipset within finality, should not be removed", - headHeight: 1000, - revertedHeight: 980, - expectRemoved: false, - }, - { - name: "reverted tipset outside finality, should be removed", - headHeight: 5000, - revertedHeight: 400, - expectRemoved: true, - }, - { - name: "not enough tipsets", - headHeight: 2000, - revertedHeight: 1, - expectRemoved: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - si, _, _ := setupWithHeadIndexed(t, abi.ChainEpoch(tt.headHeight), rng) - si.gcRetentionEpochs = 0 - defer func() { _ = si.Close() }() - - revertedTsCid := randomCid(t, rng) - insertTipsetMessage(t, si, tipsetMessage{ - tipsetKeyCid: revertedTsCid.Bytes(), - height: tt.revertedHeight, - reverted: true, - messageCid: randomCid(t, rng).Bytes(), - messageIndex: 0, - }) - - si.cleanUpRevertedTipsets(ctx) - - var count int - err := si.db.QueryRow("SELECT COUNT(*) FROM tipset_message WHERE height = ?", tt.revertedHeight).Scan(&count) - require.NoError(t, err) - - if tt.expectRemoved { - require.Equal(t, 0, count, "expected reverted tipset to be removed") - } else { - require.Equal(t, 1, count, "expected reverted tipset to not be removed") - } - }) - } -} - func TestGC(t *testing.T) { ctx := context.Background() rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) From fcbb3e59c04384b6f71323f8bd5354176522cd8d Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 8 Oct 2024 19:41:19 +0400 Subject: [PATCH 36/61] reconcile does not need lock --- chain/index/reconcile.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/chain/index/reconcile.go b/chain/index/reconcile.go index 7341a75a764..72a1e6ecaa6 100644 --- a/chain/index/reconcile.go +++ b/chain/index/reconcile.go @@ -27,9 +27,6 @@ import ( // This function is crucial for maintaining index integrity, especially after chain reorgs. // It ensures that the index accurately reflects the current state of the blockchain. func (si *SqliteIndexer) ReconcileWithChain(ctx context.Context, head *types.TipSet) error { - si.writerLk.Lock() - defer si.writerLk.Unlock() - if !si.cs.IsStoringEvents() { log.Warn("chain indexer is not storing events during reconciliation; please ensure this is intentional") } From 47e421f1f3e16c08f3b51a9f4da256a6876357d8 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Tue, 8 Oct 2024 21:53:46 +0400 Subject: [PATCH 37/61] improved error handling --- chain/index/api.go | 32 ++++++------------- chain/index/helpers.go | 71 ++++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 0f5e6032f1a..3dacb72dab8 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -4,8 +4,6 @@ import ( "context" "database/sql" "errors" - "strings" - "time" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -28,28 +26,27 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return nil, errors.New("ChainValidateIndex called on closed indexer") } - // we need to take a write lock here so that back-filling does not race with real time chain indexing - si.writerLk.Lock() - defer si.writerLk.Unlock() - // this API only works for epoch < head because of deferred execution in Filecoin head := si.cs.GetHeaviestTipSet() if epoch >= head.Height() { return nil, xerrors.Errorf("cannot validate index at epoch %d, can only validate at an epoch less than chain head epoch %d", epoch, head.Height()) } - var isIndexEmpty bool - err := si.stmts.isIndexEmptyStmt.QueryRowContext(ctx).Scan(&isIndexEmpty) - if err != nil { - return nil, xerrors.Errorf("failed to check if index is empty: %w", err) - } - // fetch the tipset at the given epoch on the canonical chain expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, nil, true) if err != nil { return nil, xerrors.Errorf("failed to get tipset at height %d: %w", epoch, err) } + // we need to take a write lock here so that back-filling does not race with real time chain indexing + si.writerLk.Lock() + defer si.writerLk.Unlock() + + var isIndexEmpty bool + if err := si.stmts.isIndexEmptyStmt.QueryRowContext(ctx).Scan(&isIndexEmpty); err != nil { + return nil, xerrors.Errorf("failed to check if index is empty: %w", err) + } + // Canonical chain has a null round at the epoch -> return if index is empty otherwise validate that index also // has a null round at this epoch i.e. it does not have anything indexed at all for this epoch if expectedTs.Height() != epoch { @@ -300,16 +297,7 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti }) } - err = backfillFunc() - if err != nil && strings.Contains(err.Error(), "database is locked") { - log.Warnf("backfill of height %d failed due to database lock, retrying in 100ms", ts.Height()) - time.Sleep(100 * time.Millisecond) - err = backfillFunc() - if err == nil { - log.Infof("backfill of height %d succeeded after retry", ts.Height()) - } - } - if err != nil { + if err := backfillFunc(); err != nil { return nil, xerrors.Errorf("failed to backfill tipset: %w", err) } diff --git a/chain/index/helpers.go b/chain/index/helpers.go index 07bf970569f..57253d05ffd 100644 --- a/chain/index/helpers.go +++ b/chain/index/helpers.go @@ -5,6 +5,8 @@ import ( "database/sql" "errors" "os" + "strings" + "time" ipld "github.com/ipfs/go-ipld-format" "golang.org/x/xerrors" @@ -12,6 +14,9 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) +const maxRetries = 3 +const retryDelay = 150 * time.Millisecond + // PopulateFromSnapshot initializes and populates the chain index from a snapshot. // // This function creates a new Index at the specified path and populates @@ -91,29 +96,55 @@ func toTipsetKeyCidBytes(ts *types.TipSet) ([]byte, error) { return tsKeyCid.Bytes(), nil } -func withTx(ctx context.Context, db *sql.DB, fn func(*sql.Tx) error) (err error) { - var tx *sql.Tx - tx, err = db.BeginTx(ctx, nil) - if err != nil { - return xerrors.Errorf("failed to begin transaction: %w", err) - } +func withTx(ctx context.Context, db *sql.DB, fn func(*sql.Tx) error) error { + var err error + for i := 0; i < maxRetries; i++ { + if ctx.Err() != nil { + return ctx.Err() + } + var tx *sql.Tx + tx, err = db.BeginTx(ctx, nil) + if err != nil { + return xerrors.Errorf("failed to begin transaction: %w", err) + } - defer func() { - if p := recover(); p != nil { - // A panic occurred, rollback and repanic - _ = tx.Rollback() - panic(p) - } else if err != nil { - // Something went wrong, rollback - _ = tx.Rollback() - } else { - // All good, commit - err = tx.Commit() + defer func() { + if p := recover(); p != nil { + // A panic occurred, rollback and repanic + if tx != nil { + _ = tx.Rollback() + } + panic(p) + } + }() + + err = fn(tx) + if err == nil { + if commitErr := tx.Commit(); commitErr != nil { + return xerrors.Errorf("failed to commit transaction: %w", commitErr) + } + return nil } - }() - err = fn(tx) - return + _ = tx.Rollback() + + if !isRetryableError(err) { + return xerrors.Errorf("transaction failed: %w", err) + } + + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(retryDelay): + // Retry after delay + } + } + + return xerrors.Errorf("transaction failed after %d retries; last error: %w", maxRetries, err) +} + +func isRetryableError(err error) bool { + return err != nil && strings.Contains(err.Error(), "database is locked") } func isIndexedValue(b uint8) bool { From 33c1ca1831ca65695b0f268b319f0c5539d14109 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Tue, 8 Oct 2024 14:28:43 -0700 Subject: [PATCH 38/61] Update chain-indexing-overview-for-rpc-providers.md Doc updates based on @jennijuju feedack. --- ...ain-indexing-overview-for-rpc-providers.MD | 48 ++++++++++++------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index e7af402a37e..5d59e1a2be4 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -2,10 +2,9 @@ ## Introduction -This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the `ChainIndexer`. +This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the [`ChainIndexer`](chainindex-indexing#system). -**Note: If you are a Storage Provider or node operator who does not serve RPC requests, you can skip this document as the `ChainIndexer` is already disabled by default**. - +**Note: If you are a Storage Provider or node operator who does not serve RPC requests (i.e, if `Fevm.EnableEthRPC = false`), you can skip this document as the `ChainIndexer` is already disabled by default**. ## ChainIndexer Config ### Enablement @@ -66,23 +65,27 @@ DisableHistoricFilterAPI = false DatabasePath = "" ``` -## Migration Guide +## Upgrade Steps + +> **Note:** One can upgrade/downgrade between [pre-ChainIndexer](#previous-indexing-system) and [with-ChainIndexer](#chainindex-indexing-system) Lotus versions without conflict because they persist state to different directories and don't rely on each other. No backup is necessary (but extra backups don't hurt). -Migrating to the new `ChainIndexer` involves several steps to ensure a smooth transition: +Upgrading to the new `ChainIndexer` involves these steps: 1. **Stop the Lotus Node** - Stop your Lotus node before starting the upgrade and migration process. 2. **Update Configuration** - Modify your Lotus configuration to enable the `ChainIndexer` as described in the [`ChainIndexer Config` section above](#chainindexer-config). - 3. **Restart Lotus Node** - Restart your Lotus node with the new configuration. - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfilling` section below](#backfilling).** + - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfill` section below](#backfill).** + +> **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) state directory around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operation after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) state directory can be removed to reclaim disk space. -Note: The ChainIndexer will write state to `${LOTUS_HOME}/chainindex` rather than the [removed option](#removed-options) for `Events.DatabasePath` (which defaulted to `${LOTUS_HOME}/sqllite`). It's recommended to keep the legacy directory around until you've confirmed you don't need to [rollback](#rollback). ## Backfill -To index historical chain state (i.e., **"backfilling"**), you can use the following tools: +There is no migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindex-indexing-system) because the [pre-ChainIndexer indices](#previous-indexing-system) are not fully reliable. Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. + +> **Note:** The ChainIndex will consume ~10GB of storage per month of tipsets (e.g., ~86400 epochs). Ensure you have sufficient disk space before proceeding. ### `ChainValidateIndex` JSON RPC API @@ -90,12 +93,10 @@ Please refer to the [Lotus API documentation](https://github.com/filecoin-projec The `ChainValidateIndex` JSON RPC API serves a dual purpose: it validates/diagnoses the integrity of the index at a specific epoch (i.e., it ensures consistency between indexed data and actual chain state), while also providing the option to backfill the `ChainIndexer` if it does not have data for the specified epoch. - The `ChainValidateIndex` RPC API is available for use once the Lotus daemon has started with `ChainIndexer` [enabled](#enablement). Here are some examples of how to use the `ChainValidateIndex` JSON RPC API for validating/ backfilling the index: - 1) Validating the index for an epoch that is a NULL round: ```bash @@ -191,12 +192,27 @@ The command validates the chain index entries for each epoch in the specified ra You can learn about how to use the tool with `lotus-shed chainindex validate-backfill -h`. -## Rollback +## Downgrade -In case you need to rollback to the previous indexing system (`EthTxIndex`, `MsgIndex`, and `EventIndex`), follow these steps: +In case you need to downgrade to the [previous indexing system](#previous indexing system), follow these steps: 1. Stop your Lotus node. -2. Build your Lotus binary for the rollback version which has the implementation of the old `EthTxIndex`, `MsgIndex`, and `EventIndex` Indices. -4. Ensure that you've set the correct config for the existing `EthTxIndex`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. +2. Build your Lotus binary for the rollback version which has the implementation of the old `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices. +4. Ensure that you've set the correct config for the existing `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. 5. Restart your Lotus node. -6. Backfill the `EthTxIndex`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the previous indexing system for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. \ No newline at end of file +6. Backfill the `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the [previous indexing system](#previous-indexing-system) for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. + +## Terminology +### Previous Indexing System +* This corresponds to the indexing system used in Lotus versions before v1.31.0. +* It has been replaced by the [ChainIndex](#chainindex-indexing-system). +* It was composed of three indexers using three separate databases: [`EthTxHashLookup`](https://github.com/filecoin-project/lotus/blob/master/chain/ethhashlookup/eth_transaction_hash_lookup.go), [`MsgIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/index/msgindex.go), and [`EventIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/events/filter/index.go). +* It persisted state to the [removed option](#removed-options) for `Events.DatabasePath`, which defaulted to `${LOTUS_HOME}/sqllite`. +* It had CLI backfill tooling: `lotus-shed index backfill-*` + +### ChainIndex Indexing System +* This corresponds to the indexing system used in Lotus versions v1.31.0 onwards. +* It replaced the [previous indexing system](#previous-indexing-system). +* It is composed of a single indexer, [`ChainIndexer`](https://github.com/filecoin-project/lotus/blob/master/chain/index/indexer.go), using a single database for transactions, messages, and events. +* It persists state to `${LOTUS_HOME}/chainindex`. +* It has this CLI backfill tooling: [`lotus-shed chainindex validate-backfill`](#lotus-shed-chainindex-validate-backfill-cli-tool) From 926852a538d50b40e8bdac552215aa3912526f90 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Tue, 8 Oct 2024 14:33:47 -0700 Subject: [PATCH 39/61] Update chain-indexing-overview-for-rpc-providers.MD Fixes after reviewing https://github.com/filecoin-project/lotus/pull/12450/commits/33c1ca1831ca65695b0f268b319f0c5539d14109 --- .../chain-indexing-overview-for-rpc-providers.MD | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 5d59e1a2be4..33a3e40787e 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -2,7 +2,7 @@ ## Introduction -This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the [`ChainIndexer`](chainindex-indexing#system). +This document is for RPC providers and node operators who serve RPC requests walking through the configuration changes, migration flow and operations/maintenance work needed to enable, backfill and maintain the [`ChainIndexer`](#chainindexer-indexing-system). **Note: If you are a Storage Provider or node operator who does not serve RPC requests (i.e, if `Fevm.EnableEthRPC = false`), you can skip this document as the `ChainIndexer` is already disabled by default**. @@ -67,7 +67,7 @@ DatabasePath = "" ## Upgrade Steps -> **Note:** One can upgrade/downgrade between [pre-ChainIndexer](#previous-indexing-system) and [with-ChainIndexer](#chainindex-indexing-system) Lotus versions without conflict because they persist state to different directories and don't rely on each other. No backup is necessary (but extra backups don't hurt). +> **Note:** One can upgrade/downgrade between [pre-ChainIndexer](#previous-indexing-system) and [with-ChainIndexer](#chainindexer-indexing-system) Lotus versions without conflict because they persist state to different directories and don't rely on each other. No backup is necessary (but extra backups don't hurt). Upgrading to the new `ChainIndexer` involves these steps: @@ -80,10 +80,10 @@ Upgrading to the new `ChainIndexer` involves these steps: - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfill` section below](#backfill).** -> **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) state directory around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operation after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) state directory can be removed to reclaim disk space. +> **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) state directory around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operations after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) state directory can be removed to reclaim disk space. ## Backfill -There is no migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindex-indexing-system) because the [pre-ChainIndexer indices](#previous-indexing-system) are not fully reliable. Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. +There is no migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindexer-indexing-system) because the [pre-ChainIndexer indices](#previous-indexing-system) are not fully reliable. Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. > **Note:** The ChainIndex will consume ~10GB of storage per month of tipsets (e.g., ~86400 epochs). Ensure you have sufficient disk space before proceeding. @@ -194,7 +194,7 @@ You can learn about how to use the tool with `lotus-shed chainindex validate-bac ## Downgrade -In case you need to downgrade to the [previous indexing system](#previous indexing system), follow these steps: +In case you need to downgrade to the [previous indexing system](#previous-indexing-system), follow these steps: 1. Stop your Lotus node. 2. Build your Lotus binary for the rollback version which has the implementation of the old `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices. @@ -205,14 +205,14 @@ In case you need to downgrade to the [previous indexing system](#previous indexi ## Terminology ### Previous Indexing System * This corresponds to the indexing system used in Lotus versions before v1.31.0. -* It has been replaced by the [ChainIndex](#chainindex-indexing-system). +* It has been replaced by the [ChainIndex](#chainindexer-indexing-system). * It was composed of three indexers using three separate databases: [`EthTxHashLookup`](https://github.com/filecoin-project/lotus/blob/master/chain/ethhashlookup/eth_transaction_hash_lookup.go), [`MsgIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/index/msgindex.go), and [`EventIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/events/filter/index.go). * It persisted state to the [removed option](#removed-options) for `Events.DatabasePath`, which defaulted to `${LOTUS_HOME}/sqllite`. * It had CLI backfill tooling: `lotus-shed index backfill-*` -### ChainIndex Indexing System +### ChainIndexer Indexing System * This corresponds to the indexing system used in Lotus versions v1.31.0 onwards. * It replaced the [previous indexing system](#previous-indexing-system). -* It is composed of a single indexer, [`ChainIndexer`](https://github.com/filecoin-project/lotus/blob/master/chain/index/indexer.go), using a single database for transactions, messages, and events. +* It is composed of a single indexer, [`ChainIndexer`](https://github.com/filecoin-project/lotus/blob/master/chain/index/indexer.go), using a [single database for transactions, messages, and events](https://github.com/filecoin-project/lotus/blob/master/chain/index/ddls.go). * It persists state to `${LOTUS_HOME}/chainindex`. * It has this CLI backfill tooling: [`lotus-shed chainindex validate-backfill`](#lotus-shed-chainindex-validate-backfill-cli-tool) From 23741cf6ed47dc6c00b97429202c2c660a8bd626 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Wed, 9 Oct 2024 10:49:28 +0400 Subject: [PATCH 40/61] better metrics for backfilling --- cmd/lotus-shed/chain_index.go | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 37daedeb9fc..ab88eb0a6d1 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -122,6 +122,11 @@ like cron. // Results Tracking logGood := cctx.Bool("log-good") + failedRPCs := 0 + successfulBackfills := 0 + successfulValidations := 0 + successfulNullRounds := 0 + startTime := time.Now() _, _ = fmt.Fprintf(cctx.App.Writer, "%s starting chainindex validation; from epoch: %d; to epoch: %d; backfill: %t; log-good: %t\n", currentTimeString(), fromEpoch, toEpoch, backfill, logGood) @@ -142,14 +147,22 @@ like cron. indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) if err != nil { _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✗ Epoch %d; failure: %s\n", currentTimeString(), epoch, err) + failedRPCs++ continue } + if indexValidateResp.Backfilled { + successfulBackfills++ + } else if indexValidateResp.IsNullRound { + successfulNullRounds++ + } else { + successfulValidations++ + } + if !logGood { continue } - // is it a null round ? if indexValidateResp.IsNullRound { _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✓ Epoch %d; null round\n", currentTimeString(), epoch) } else { @@ -162,6 +175,12 @@ like cron. } } + _, _ = fmt.Fprintf(cctx.App.Writer, "\n%s Chain index validation summary:\n", currentTimeString()) + _, _ = fmt.Fprintf(cctx.App.Writer, "Total failed RPC calls: %d\n", failedRPCs) + _, _ = fmt.Fprintf(cctx.App.Writer, "Total successful backfills: %d\n", successfulBackfills) + _, _ = fmt.Fprintf(cctx.App.Writer, "Total successful validations without backfilling: %d\n", successfulValidations) + _, _ = fmt.Fprintf(cctx.App.Writer, "Total successful Null round validations: %d\n", successfulNullRounds) + return nil }, } From 5eb4be4f0f5649b6145258cc6532011d0033b73c Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:15:44 -0700 Subject: [PATCH 41/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 33a3e40787e..2a58472767d 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -78,7 +78,7 @@ Upgrading to the new `ChainIndexer` involves these steps: 3. **Restart Lotus Node** - Restart your Lotus node with the new configuration. - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state). To perform backfilling, please see the [`Backfill` section below](#backfill).** + - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state prior to the upgrade). To perform backfilling, please see the [`Backfill` section below](#backfill).** > **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) state directory around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operations after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) state directory can be removed to reclaim disk space. From bc88f8cc3fc18c6505b1dae26bf1022e8ab6742c Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:16:32 -0700 Subject: [PATCH 42/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 2a58472767d..f8c2f271e94 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -80,7 +80,7 @@ Upgrading to the new `ChainIndexer` involves these steps: - The `ChainIndexer` will begin indexing **real-time chain state changes** immediately in the `${LOTUS_PATH}/chainindex` directory. - **However, it will not automatically index any historical chain state (i.e., any previously existing chain state prior to the upgrade). To perform backfilling, please see the [`Backfill` section below](#backfill).** -> **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) state directory around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operations after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) state directory can be removed to reclaim disk space. +> **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) indexing database directory (`${LOTUS_PATH}/sqlite`) around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operations after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) indexing database directory can be removed to reclaim disk space. ## Backfill There is no migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindexer-indexing-system) because the [pre-ChainIndexer indices](#previous-indexing-system) are not fully reliable. Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. From 097b90d79ea84c0363bf269ee6297731405ac606 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:32:10 -0700 Subject: [PATCH 43/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index f8c2f271e94..4ce72e11de9 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -83,7 +83,7 @@ Upgrading to the new `ChainIndexer` involves these steps: > **Note:** It's recommended to keep the [pre-ChainIndexer](#previous-indexing-system) indexing database directory (`${LOTUS_PATH}/sqlite`) around until you've confirmed you don't need to [downgrade](#downgrade). After sustained successful operations after the upgrade, the [pre-ChainIndexer](#previous-indexing-system) indexing database directory can be removed to reclaim disk space. ## Backfill -There is no migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindexer-indexing-system) because the [pre-ChainIndexer indices](#previous-indexing-system) are not fully reliable. Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. +There is no automated migration from [pre-ChainIndexer indices](#previous-indexing-system) to the [ChainIndex](#chainindexer-indexing-system). Instead one needs to index historical chain state (i.e., backfill) using one of the following tools. > **Note:** The ChainIndex will consume ~10GB of storage per month of tipsets (e.g., ~86400 epochs). Ensure you have sufficient disk space before proceeding. From 5170f228eb22eeedff2e0ffffd4e1bada10fcd94 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:38:27 -0700 Subject: [PATCH 44/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 ++ 1 file changed, 2 insertions(+) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 4ce72e11de9..87be138dac9 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -192,6 +192,8 @@ The command validates the chain index entries for each epoch in the specified ra You can learn about how to use the tool with `lotus-shed chainindex validate-backfill -h`. +Note: If you are using a non-standard Lotus repo directory then you can run the command with `lotus-shed -repo /path/to/lotus/repo chainindex validate-backfill ...`, or by setting the `LOTUS_PATH` environment variable. + ## Downgrade In case you need to downgrade to the [previous indexing system](#previous-indexing-system), follow these steps: From feefed997636410fb3e3146f7b47776ec6a52bac Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:38:49 -0700 Subject: [PATCH 45/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 87be138dac9..db57e1a923d 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -209,7 +209,7 @@ In case you need to downgrade to the [previous indexing system](#previous-indexi * This corresponds to the indexing system used in Lotus versions before v1.31.0. * It has been replaced by the [ChainIndex](#chainindexer-indexing-system). * It was composed of three indexers using three separate databases: [`EthTxHashLookup`](https://github.com/filecoin-project/lotus/blob/master/chain/ethhashlookup/eth_transaction_hash_lookup.go), [`MsgIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/index/msgindex.go), and [`EventIndex`](https://github.com/filecoin-project/lotus/blob/master/chain/events/filter/index.go). -* It persisted state to the [removed option](#removed-options) for `Events.DatabasePath`, which defaulted to `${LOTUS_HOME}/sqllite`. +* It persisted state to the [removed option](#removed-options) for `Events.DatabasePath`, which defaulted to `${LOTUS_PATH}/sqlite`. * It had CLI backfill tooling: `lotus-shed index backfill-*` ### ChainIndexer Indexing System From 2fb608f020ade85725c202ecfc82d4c3de3c0968 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:39:05 -0700 Subject: [PATCH 46/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index db57e1a923d..4757ec054aa 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -199,7 +199,7 @@ Note: If you are using a non-standard Lotus repo directory then you can run the In case you need to downgrade to the [previous indexing system](#previous-indexing-system), follow these steps: 1. Stop your Lotus node. -2. Build your Lotus binary for the rollback version which has the implementation of the old `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices. +2. Download or build a Lotus binary for the rollback version which has the implementation of the old `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices. 4. Ensure that you've set the correct config for the existing `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices in the `config.toml` file. 5. Restart your Lotus node. 6. Backfill the `EthTxHashLookup`, `MsgIndex`, and `EventIndex` indices using the `lotus-shed index backfill-*` CLI tooling available in the [previous indexing system](#previous-indexing-system) for the epoch range in [epochs between the upgrade to `ChainIndexer` and the rollback of `ChainIndexer`]. From 637e6a2e36b00d18a59aea6cf9e427b87fbbdf82 Mon Sep 17 00:00:00 2001 From: Steve Loeppky Date: Wed, 9 Oct 2024 14:58:45 -0700 Subject: [PATCH 47/61] Update chain/index/chain-indexing-overview-for-rpc-providers.MD Co-authored-by: Rod Vagg --- chain/index/chain-indexing-overview-for-rpc-providers.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/index/chain-indexing-overview-for-rpc-providers.MD b/chain/index/chain-indexing-overview-for-rpc-providers.MD index 4757ec054aa..89359dcd65c 100644 --- a/chain/index/chain-indexing-overview-for-rpc-providers.MD +++ b/chain/index/chain-indexing-overview-for-rpc-providers.MD @@ -9,7 +9,7 @@ This document is for RPC providers and node operators who serve RPC requests wal ## ChainIndexer Config ### Enablement -The following must be enabled on an RPC node before starting as they are disabled by default: +The following must be enabled on an Lotus node before starting as they are disabled by default: ```toml [ChainIndexer] From 6badc361c6cf5214ad8ddac8f274efb56b48b237 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Fri, 11 Oct 2024 13:18:24 +0400 Subject: [PATCH 48/61] tests for changes to event addressing --- chain/index/api_test.go | 4 +++ chain/index/ddls_test.go | 9 +++++- chain/index/events_test.go | 64 +++++++++++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/chain/index/api_test.go b/chain/index/api_test.go index 44ac9aae6a0..fa061d035e1 100644 --- a/chain/index/api_test.go +++ b/chain/index/api_test.go @@ -312,6 +312,7 @@ func TestIndexCorruption(t *testing.T) { insertEvent(t, si, event{ messageID: messageID, eventIndex: 0, + emitterId: 1, emitterAddr: randomIDAddr(t, rng).Bytes(), reverted: true, }) @@ -379,12 +380,14 @@ func TestIndexCorruption(t *testing.T) { insertEvent(t, si, event{ messageID: messageID, eventIndex: 0, + emitterId: 2, emitterAddr: randomIDAddr(t, rng).Bytes(), reverted: false, }) insertEvent(t, si, event{ messageID: messageID, eventIndex: 1, + emitterId: 3, emitterAddr: randomIDAddr(t, rng).Bytes(), reverted: false, }) @@ -428,6 +431,7 @@ func TestIndexCorruption(t *testing.T) { eventID := insertEvent(t, si, event{ messageID: messageID, eventIndex: 0, + emitterId: 4, emitterAddr: randomIDAddr(t, rng).Bytes(), reverted: false, }) diff --git a/chain/index/ddls_test.go b/chain/index/ddls_test.go index 69b09f975c8..004b3f0a254 100644 --- a/chain/index/ddls_test.go +++ b/chain/index/ddls_test.go @@ -27,6 +27,7 @@ func TestHasRevertedEventsInTipsetStmt(t *testing.T) { insertEvent(t, s, event{ messageID: messageID, eventIndex: 0, + emitterId: 1, emitterAddr: []byte("test_emitter_addr"), reverted: true, }) @@ -63,12 +64,14 @@ func TestGetNonRevertedTipsetCountStmts(t *testing.T) { eventID1 := insertEvent(t, s, event{ messageID: messageID, eventIndex: 0, + emitterId: 1, emitterAddr: []byte("test_emitter_addr"), reverted: false, }) eventID2 := insertEvent(t, s, event{ messageID: messageID, eventIndex: 1, + emitterId: 2, emitterAddr: []byte("test_emitter_addr"), reverted: false, }) @@ -202,12 +205,14 @@ func TestUpdateEventsToRevertedStmt(t *testing.T) { insertEvent(t, s, event{ messageID: messageID, eventIndex: 0, + emitterId: 1, emitterAddr: []byte("test_emitter_addr"), reverted: false, }) insertEvent(t, s, event{ messageID: messageID, eventIndex: 1, + emitterId: 2, emitterAddr: []byte("test_emitter_addr"), reverted: false, }) @@ -463,6 +468,7 @@ func TestForeignKeyCascadeDelete(t *testing.T) { eventID := insertEvent(t, s, event{ messageID: messageID, eventIndex: 0, + emitterId: 2, emitterAddr: []byte("test_emitter_addr"), reverted: false, }) @@ -531,6 +537,7 @@ type tipsetMessage struct { type event struct { eventIndex uint64 + emitterId uint64 emitterAddr []byte reverted bool messageID int64 @@ -682,7 +689,7 @@ func insertTipsetMessage(t *testing.T, s *SqliteIndexer, ts tipsetMessage) int64 } func insertEvent(t *testing.T, s *SqliteIndexer, e event) int64 { - res, err := s.stmts.insertEventStmt.Exec(e.messageID, e.eventIndex, e.emitterAddr, e.reverted) + res, err := s.stmts.insertEventStmt.Exec(e.messageID, e.eventIndex, e.emitterId, e.emitterAddr, e.reverted) require.NoError(t, err) rowsAffected, err := res.RowsAffected() diff --git a/chain/index/events_test.go b/chain/index/events_test.go index bfab3410978..32ec36672df 100644 --- a/chain/index/events_test.go +++ b/chain/index/events_test.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" pseudo "math/rand" + "sort" "testing" "time" @@ -207,6 +208,9 @@ func TestGetEventsFilterByAddress(t *testing.T) { addr3, err := address.NewIDAddress(3) require.NoError(t, err) + delegatedAddr1, err := address.NewFromString("f410fagkp3qx2f76maqot74jaiw3tzbxe76k76zrkl3xifk67isrnbn2sll3yua") + require.NoError(t, err) + ev1 := fakeEvent( abi.ActorID(1), []kv{ @@ -238,6 +242,9 @@ func TestGetEventsFilterByAddress(t *testing.T) { } si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + if emitter == abi.ActorID(1) { + return delegatedAddr1, true + } idAddr, err := address.NewIDAddress(uint64(emitter)) if err != nil { return address.Undef, false @@ -262,18 +269,40 @@ func TestGetEventsFilterByAddress(t *testing.T) { require.NoError(t, si.Apply(ctx, fakeTipSet1, fakeTipSet2)) testCases := []struct { - name string - f *EventFilter - expectedCount int + name string + f *EventFilter + expectedCount int + expectedAddresses []address.Address }{ { - name: "matching single address", + name: "matching single ID address (non-delegated)", + f: &EventFilter{ + Addresses: []address.Address{addr2}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 1, + expectedAddresses: []address.Address{addr2}, + }, + { + name: "matching single ID address", f: &EventFilter{ Addresses: []address.Address{addr1}, MinHeight: 1, MaxHeight: 1, }, - expectedCount: 1, + expectedCount: 1, + expectedAddresses: []address.Address{delegatedAddr1}, + }, + { + name: "matching single delegated address", + f: &EventFilter{ + Addresses: []address.Address{delegatedAddr1}, + MinHeight: 1, + MaxHeight: 1, + }, + expectedCount: 1, + expectedAddresses: []address.Address{delegatedAddr1}, }, { name: "matching multiple addresses", @@ -282,7 +311,8 @@ func TestGetEventsFilterByAddress(t *testing.T) { MinHeight: 1, MaxHeight: 1, }, - expectedCount: 2, + expectedCount: 2, + expectedAddresses: []address.Address{delegatedAddr1, addr2}, }, { name: "no matching address", @@ -291,7 +321,8 @@ func TestGetEventsFilterByAddress(t *testing.T) { MinHeight: 1, MaxHeight: 1, }, - expectedCount: 0, + expectedCount: 0, + expectedAddresses: []address.Address{}, }, { name: "empty address list", @@ -300,7 +331,8 @@ func TestGetEventsFilterByAddress(t *testing.T) { MinHeight: 1, MaxHeight: 1, }, - expectedCount: 2, // should return all events + expectedCount: 2, + expectedAddresses: []address.Address{delegatedAddr1, addr2}, }, } @@ -309,10 +341,26 @@ func TestGetEventsFilterByAddress(t *testing.T) { ces, err := si.GetEventsForFilter(ctx, tc.f, false) require.NoError(t, err) require.Equal(t, tc.expectedCount, len(ces)) + + actualAddresses := make([]address.Address, len(ces)) + for i, ce := range ces { + actualAddresses[i] = ce.EmitterAddr + } + + sortAddresses(tc.expectedAddresses) + sortAddresses(actualAddresses) + + require.Equal(t, tc.expectedAddresses, actualAddresses) }) } } +func sortAddresses(addrs []address.Address) { + sort.Slice(addrs, func(i, j int) bool { + return addrs[i].String() < addrs[j].String() + }) +} + func fakeMessage(to, from address.Address) *types.Message { return &types.Message{ To: to, From c0a647128ff7642f5fbaa1c5cb0471b7ce65206f Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 12:09:33 +0400 Subject: [PATCH 49/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- chain/index/api.go | 2 +- chain/index/api_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 3dacb72dab8..ed2e9634312 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -33,7 +33,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } // fetch the tipset at the given epoch on the canonical chain - expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, nil, true) + expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, head.Key(), true) if err != nil { return nil, xerrors.Errorf("failed to get tipset at height %d: %w", epoch, err) } diff --git a/chain/index/api_test.go b/chain/index/api_test.go index fa061d035e1..66c9d10016a 100644 --- a/chain/index/api_test.go +++ b/chain/index/api_test.go @@ -74,7 +74,7 @@ func TestValidateIsNullRound(t *testing.T) { if tt.expectError { require.Error(t, err) if tt.errorContains != "" { - require.Contains(t, err.Error(), tt.errorContains) + require.ErrorContains(t, err, tt.errorContains) } } else { require.NoError(t, err) @@ -144,7 +144,7 @@ func TestBackfillReturnsError(t *testing.T) { // Attempt to validate the missing epoch with backfill flag set to false _, err := si.ChainValidateIndex(ctx, missingEpoch, false) require.Error(t, err) - require.Contains(t, err.Error(), "missing tipset at height 50 in the chain index") + require.ErrorContains(t, err, "missing tipset at height 50 in the chain index") } func TestBackfillMissingEpoch(t *testing.T) { From a017e7189601f94bb0aee9c45202d20b145d137d Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 12:35:42 +0400 Subject: [PATCH 50/61] changes as per review -> round 1 --- chain/index/api.go | 31 ++++++++++++-------- chain/index/api_test.go | 56 ++++++++++++++++++++++--------------- chain/index/events.go | 4 +-- chain/index/events_test.go | 22 +++++++++------ chain/index/gc_test.go | 8 ++++-- chain/index/indexer.go | 14 ++++------ chain/index/indexer_test.go | 4 ++- chain/index/interface.go | 4 +-- chain/index/read_test.go | 8 ++++-- node/modules/chainindex.go | 8 ++---- 10 files changed, 95 insertions(+), 64 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index ed2e9634312..860226dfabd 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -33,7 +33,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } // fetch the tipset at the given epoch on the canonical chain - expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, head.Key(), true) + expectedTs, err := si.cs.GetTipsetByHeight(ctx, epoch, head, true) if err != nil { return nil, xerrors.Errorf("failed to get tipset at height %d: %w", epoch, err) } @@ -62,14 +62,19 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain // if the index is empty -> short-circuit and simply backfill if applicable if isIndexEmpty { - return si.backfillMissingTipset(ctx, expectedTs, backfill) + if !backfill { + return nil, makeBackfillRequiredErr(epoch) + } + return si.backfillMissingTipset(ctx, expectedTs) } - // see if the tipset at this epoch is already indexed or if we need to backfill revertedCount, nonRevertedCount, err := si.getTipsetCountsAtHeight(ctx, epoch) if err != nil { if err == sql.ErrNoRows { - return si.backfillMissingTipset(ctx, expectedTs, backfill) + if !backfill { + return nil, makeBackfillRequiredErr(epoch) + } + return si.backfillMissingTipset(ctx, expectedTs) } return nil, xerrors.Errorf("failed to get tipset counts at height %d: %w", epoch, err) } @@ -77,7 +82,10 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain switch { case revertedCount == 0 && nonRevertedCount == 0: // no tipsets at this epoch in the index, backfill - return si.backfillMissingTipset(ctx, expectedTs, backfill) + if !backfill { + return nil, makeBackfillRequiredErr(epoch) + } + return si.backfillMissingTipset(ctx, expectedTs) case revertedCount > 0 && nonRevertedCount == 0: return nil, xerrors.Errorf("index corruption: height %d only has reverted tipsets", epoch) @@ -127,7 +135,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain } log.Warnf("failed to verify indexed data at height %d; err:%s; backfilling once and validating again", expectedTs.Height(), err) - if _, err := si.backfillMissingTipset(ctx, expectedTs, backfill); err != nil { + if _, err := si.backfillMissingTipset(ctx, expectedTs); err != nil { return nil, xerrors.Errorf("failed to backfill missing tipset at height %d during validation; err: %w", expectedTs.Height(), err) } @@ -236,7 +244,7 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return xerrors.Errorf("index corruption: reverted events found for an executed tipset %s at height %d", tsKeyCid, ts.Height()) } - executedMsgs, err := si.eventLoaderFunc(ctx, si.cs, ts, executionTs) + executedMsgs, err := si.executedMessagesLoaderFunc(ctx, si.cs, ts, executionTs) if err != nil { return xerrors.Errorf("failed to load executed messages for height %d: %w", ts.Height(), err) } @@ -268,10 +276,7 @@ func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet return nil } -func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.TipSet, backfill bool) (*types.IndexValidation, error) { - if !backfill { - return nil, xerrors.Errorf("missing tipset at height %d in the chain index, set backfill flag to true to fix", ts.Height()) - } +func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.TipSet) (*types.IndexValidation, error) { // backfill the tipset in the Index parentTs, err := si.cs.GetTipSetFromKey(ctx, ts.Parents()) if err != nil { @@ -328,3 +333,7 @@ func (si *SqliteIndexer) getNextTipset(ctx context.Context, ts *types.TipSet) (* return nextEpochTs, nil } + +func makeBackfillRequiredErr(height abi.ChainEpoch) error { + return xerrors.Errorf("missing tipset at height %d in the chain index, set backfill flag to true to fix", height) +} diff --git a/chain/index/api_test.go b/chain/index/api_test.go index 66c9d10016a..b239e5d8f1a 100644 --- a/chain/index/api_test.go +++ b/chain/index/api_test.go @@ -15,9 +15,11 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -func TestValidateIsNullRound(t *testing.T) { +func TestValidateIsNullRoundSimple(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) tests := []struct { @@ -63,7 +65,7 @@ func TestValidateIsNullRound(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { si, _, _ := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() + t.Cleanup(func() { _ = si.Close() }) if tt.setupFunc != nil { tt.setupFunc(si) @@ -88,12 +90,14 @@ func TestValidateIsNullRound(t *testing.T) { func TestFailureHeadHeight(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) si, head, _ := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() - _ = si.Start() + t.Cleanup(func() { _ = si.Close() }) + si.Start() _, err := si.ChainValidateIndex(ctx, head.Height(), false) require.Error(t, err) @@ -102,12 +106,14 @@ func TestFailureHeadHeight(t *testing.T) { func TestBackfillNullRound(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() - _ = si.Start() + t.Cleanup(func() { _ = si.Close() }) + si.Start() nullRoundEpoch := abi.ChainEpoch(50) nonNullRoundEpoch := abi.ChainEpoch(51) @@ -128,12 +134,14 @@ func TestBackfillNullRound(t *testing.T) { func TestBackfillReturnsError(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() - _ = si.Start() + t.Cleanup(func() { _ = si.Close() }) + si.Start() missingEpoch := abi.ChainEpoch(50) @@ -149,12 +157,14 @@ func TestBackfillReturnsError(t *testing.T) { func TestBackfillMissingEpoch(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() - _ = si.Start() + t.Cleanup(func() { _ = si.Close() }) + si.Start() // Initialize address resolver si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { @@ -186,7 +196,7 @@ func TestBackfillMissingEpoch(t *testing.T) { } cs.SetMessagesForTipset(missingTs, []types.ChainMsg{fakeMsg}) - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { if msgTs.Height() == missingTs.Height() { return []executedMessage{executedMsg}, nil } @@ -215,7 +225,9 @@ func TestBackfillMissingEpoch(t *testing.T) { func TestIndexCorruption(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(100) tests := []struct { @@ -347,7 +359,7 @@ func TestIndexCorruption(t *testing.T) { }) // Setup dummy event loader - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { return []executedMessage{{msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng))}}, nil }) @@ -393,7 +405,7 @@ func TestIndexCorruption(t *testing.T) { }) // Setup dummy event loader to return only one event - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { return []executedMessage{ { msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng)), @@ -453,7 +465,7 @@ func TestIndexCorruption(t *testing.T) { }) // Setup dummy event loader to return one event with only one entry - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { return []executedMessage{ { msg: fakeMessage(randomIDAddr(t, rng), randomIDAddr(t, rng)), @@ -474,8 +486,8 @@ func TestIndexCorruption(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() - _ = si.Start() + t.Cleanup(func() { _ = si.Close() }) + si.Start() tt.setupFunc(t, si, cs) diff --git a/chain/index/events.go b/chain/index/events.go index a0d59de7a79..0d29043bd62 100644 --- a/chain/index/events.go +++ b/chain/index/events.go @@ -33,7 +33,7 @@ func (si *SqliteIndexer) indexEvents(ctx context.Context, tx *sql.Tx, msgTs *typ if si.idToRobustAddrFunc == nil { return xerrors.Errorf("indexer can not index events without an address resolver") } - if si.eventLoaderFunc == nil { + if si.executedMessagesLoaderFunc == nil { return xerrors.Errorf("indexer can not index events without an event loader") } @@ -62,7 +62,7 @@ func (si *SqliteIndexer) indexEvents(ctx context.Context, tx *sql.Tx, msgTs *typ return nil } - ems, err := si.eventLoaderFunc(ctx, si.cs, msgTs, executionTs) + ems, err := si.executedMessagesLoaderFunc(ctx, si.cs, msgTs, executionTs) if err != nil { return xerrors.Errorf("failed to load executed messages: %w", err) } diff --git a/chain/index/events_test.go b/chain/index/events_test.go index 32ec36672df..2b809e0ea3b 100644 --- a/chain/index/events_test.go +++ b/chain/index/events_test.go @@ -20,11 +20,13 @@ import ( func TestGetEventsForFilterNoEvents(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(60) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() + t.Cleanup(func() { _ = si.Close() }) // Create a fake tipset at height 1 fakeTipSet1 := fakeTipSet(t, rng, 1, nil) @@ -80,10 +82,12 @@ func TestGetEventsForFilterNoEvents(t *testing.T) { func TestGetEventsForFilterWithEvents(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(60) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() + t.Cleanup(func() { _ = si.Close() }) ev1 := fakeEvent( abi.ActorID(1), @@ -124,7 +128,7 @@ func TestGetEventsForFilterWithEvents(t *testing.T) { return idAddr, true }) - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { return []executedMessage{em1}, nil }) @@ -196,10 +200,12 @@ func TestGetEventsForFilterWithEvents(t *testing.T) { func TestGetEventsFilterByAddress(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(60) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() + t.Cleanup(func() { _ = si.Close() }) addr1, err := address.NewIDAddress(1) require.NoError(t, err) @@ -252,7 +258,7 @@ func TestGetEventsFilterByAddress(t *testing.T) { return idAddr, true }) - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { return []executedMessage{em1}, nil }) diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index 4099bd9b5e9..c3ca7a57118 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -16,10 +16,12 @@ import ( func TestGC(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) headHeight := abi.ChainEpoch(60) si, _, cs := setupWithHeadIndexed(t, headHeight, rng) - defer func() { _ = si.Close() }() + t.Cleanup(func() { _ = si.Close() }) si.gcRetentionEpochs = 20 @@ -62,7 +64,7 @@ func TestGC(t *testing.T) { return idAddr, true }) - si.SetEventLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { + si.SetExecutedMessagesLoaderFunc(func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) { if msgTs.Height() == 1 { return []executedMessage{em1}, nil } diff --git a/chain/index/indexer.go b/chain/index/indexer.go index e464b1764c5..6aa2648fb53 100644 --- a/chain/index/indexer.go +++ b/chain/index/indexer.go @@ -22,7 +22,7 @@ var _ Indexer = (*SqliteIndexer)(nil) // IdToRobustAddrFunc is a function type that resolves an actor ID to a robust address type IdToRobustAddrFunc func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) -type eventLoaderFunc func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) +type emsLoaderFunc func(ctx context.Context, cs ChainStore, msgTs, rctTs *types.TipSet) ([]executedMessage, error) type recomputeTipSetStateFunc func(ctx context.Context, ts *types.TipSet) error type preparedStatements struct { @@ -65,8 +65,8 @@ type SqliteIndexer struct { db *sql.DB cs ChainStore - idToRobustAddrFunc IdToRobustAddrFunc - eventLoaderFunc eventLoaderFunc + idToRobustAddrFunc IdToRobustAddrFunc + executedMessagesLoaderFunc emsLoaderFunc stmts *preparedStatements @@ -133,21 +133,19 @@ func NewSqliteIndexer(path string, cs ChainStore, gcRetentionEpochs int64, recon return si, nil } -func (si *SqliteIndexer) Start() error { +func (si *SqliteIndexer) Start() { si.wg.Add(1) go si.gcLoop() si.started = true - - return nil } func (si *SqliteIndexer) SetIdToRobustAddrFunc(idToRobustAddrFunc IdToRobustAddrFunc) { si.idToRobustAddrFunc = idToRobustAddrFunc } -func (si *SqliteIndexer) SetEventLoaderFunc(eventLoaderFunc eventLoaderFunc) { - si.eventLoaderFunc = eventLoaderFunc +func (si *SqliteIndexer) SetExecutedMessagesLoaderFunc(eventLoaderFunc emsLoaderFunc) { + si.executedMessagesLoaderFunc = eventLoaderFunc } func (si *SqliteIndexer) Close() error { diff --git a/chain/index/indexer_test.go b/chain/index/indexer_test.go index 4a752772a09..bc4a7a70c4f 100644 --- a/chain/index/indexer_test.go +++ b/chain/index/indexer_test.go @@ -12,7 +12,9 @@ import ( func TestRestoreTipsetIfExists(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) si, _, _ := setupWithHeadIndexed(t, 10, rng) tsKeyCid := randomCid(t, rng) diff --git a/chain/index/interface.go b/chain/index/interface.go index 76a3831a019..4c4b80fefcf 100644 --- a/chain/index/interface.go +++ b/chain/index/interface.go @@ -50,13 +50,13 @@ type EventFilter struct { } type Indexer interface { - Start() error + Start() ReconcileWithChain(ctx context.Context, currHead *types.TipSet) error IndexSignedMessage(ctx context.Context, msg *types.SignedMessage) error IndexEthTxHash(ctx context.Context, txHash ethtypes.EthHash, c cid.Cid) error SetIdToRobustAddrFunc(idToRobustAddrFunc IdToRobustAddrFunc) - SetEventLoaderFunc(eventLoaderFunc eventLoaderFunc) + SetExecutedMessagesLoaderFunc(f emsLoaderFunc) Apply(ctx context.Context, from, to *types.TipSet) error Revert(ctx context.Context, from, to *types.TipSet) error diff --git a/chain/index/read_test.go b/chain/index/read_test.go index c7a6797d0bf..5557a3bd06a 100644 --- a/chain/index/read_test.go +++ b/chain/index/read_test.go @@ -22,7 +22,9 @@ import ( ) func TestGetCidFromHash(t *testing.T) { - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) ctx := context.Background() s, _, _ := setupWithHeadIndexed(t, 10, rng) @@ -51,7 +53,9 @@ func TestGetCidFromHash(t *testing.T) { func TestGetMsgInfo(t *testing.T) { ctx := context.Background() - rng := pseudo.New(pseudo.NewSource(time.Now().UnixNano())) + seed := time.Now().UnixNano() + t.Logf("seed: %d", seed) + rng := pseudo.New(pseudo.NewSource(seed)) s, _, _ := setupWithHeadIndexed(t, 10, rng) msgCid := randomCid(t, rng) diff --git a/node/modules/chainindex.go b/node/modules/chainindex.go index 59e2af3c119..11a0fa15589 100644 --- a/node/modules/chainindex.go +++ b/node/modules/chainindex.go @@ -71,12 +71,12 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In return *actor.DelegatedAddress, true }) - eventLoaderFunc := index.MakeLoadExecutedMessages(func(ctx context.Context, ts *types.TipSet) error { + executedMessagesLoaderFunc := index.MakeLoadExecutedMessages(func(ctx context.Context, ts *types.TipSet) error { _, _, err := sm.RecomputeTipSetState(ctx, ts) return err }) - indexer.SetEventLoaderFunc(eventLoaderFunc) + indexer.SetExecutedMessagesLoaderFunc(executedMessagesLoaderFunc) ch, err := mp.Updates(ctx) if err != nil { @@ -102,9 +102,7 @@ func InitChainIndexer(lc fx.Lifecycle, mctx helpers.MetricsCtx, indexer index.In } unlockObserver() - if err := indexer.Start(); err != nil { - return err - } + indexer.Start() return nil }, From 1645f76bef3d92e60b664454555453979a31a6f6 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 12:38:41 +0400 Subject: [PATCH 51/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- chain/types/index.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chain/types/index.go b/chain/types/index.go index c322ae971c0..4c5fb1cc6ed 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -5,7 +5,7 @@ type IndexValidation struct { // TipSetKey is the key of the canonical tipset for this epoch. TipSetKey TipSetKey // Height is the epoch height at which the validation is performed. - Height uint64 + Height abi.ChainEpoch // IndexedMessagesCount is the number of indexed messages for the canonical tipset at this epoch. IndexedMessagesCount uint64 // IndexedEventsCount is the number of indexed events for the canonical tipset at this epoch. From 00a4ea27c4bb5a870e2f9511d7ff25288e6db8ea Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 12:44:02 +0400 Subject: [PATCH 52/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- cmd/lotus-shed/chain_index.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index ab88eb0a6d1..2c177b58f02 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -140,7 +140,7 @@ like cron. if (fromEpoch-epoch+1)%2880 == 0 || epoch == toEpoch { progress := float64(fromEpoch-epoch+1) / float64(totalEpochs) * 100 elapsed := time.Since(startTime) - _, _ = fmt.Fprintf(cctx.App.Writer, "%s -------- Chain index validation progress: %.2f%%; Time elapsed: %s\n", + _, _ = fmt.Fprintf(cctx.App.ErrWriter, "%s -------- Chain index validation progress: %.2f%%; Time elapsed: %s\n", currentTimeString(), progress, elapsed) } From 584b5c586aa3816f7310d451f0169a430ba7982f Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 13:06:31 +0400 Subject: [PATCH 53/61] log tipset key cid --- chain/types/index.go | 4 ++++ cmd/lotus-shed/chain_index.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/chain/types/index.go b/chain/types/index.go index 4c5fb1cc6ed..93c44ad2e43 100644 --- a/chain/types/index.go +++ b/chain/types/index.go @@ -1,5 +1,9 @@ package types +import ( + "github.com/filecoin-project/go-state-types/abi" +) + // IndexValidation contains detailed information about the validation status of a specific chain epoch. type IndexValidation struct { // TipSetKey is the key of the canonical tipset for this epoch. diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 2c177b58f02..49d487559e2 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -1,15 +1,19 @@ package main import ( + "api" + "context" "encoding/json" "fmt" "time" + "github.com/ipfs/go-cid" "github.com/urfave/cli/v2" "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -146,7 +150,11 @@ like cron. indexValidateResp, err := api.ChainValidateIndex(ctx, abi.ChainEpoch(epoch), backfill) if err != nil { - _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✗ Epoch %d; failure: %s\n", currentTimeString(), epoch, err) + tsKeyCid, err := tipsetKeyCid(ctx, abi.ChainEpoch(epoch), api) + if err != nil { + return fmt.Errorf("failed to get tipset key cid for epoch %d: %w", epoch, err) + } + _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✗ Epoch %d (%s); failure: %s\n", currentTimeString(), epoch, tsKeyCid, err) failedRPCs++ continue } @@ -164,7 +172,12 @@ like cron. } if indexValidateResp.IsNullRound { - _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✓ Epoch %d; null round\n", currentTimeString(), epoch) + tsKeyCid, err := tipsetKeyCid(ctx, abi.ChainEpoch(epoch), api) + if err != nil { + return fmt.Errorf("failed to get tipset key cid for epoch %d: %w", epoch, err) + } + _, _ = fmt.Fprintf(cctx.App.Writer, "%s ✓ Epoch %d (%s); null round\n", currentTimeString(), epoch, + tsKeyCid) } else { jsonData, err := json.Marshal(indexValidateResp) if err != nil { @@ -185,6 +198,18 @@ like cron. }, } +func tipsetKeyCid(ctx context.Context, epoch abi.ChainEpoch, a api.FullNode) (cid.Cid, error) { + ts, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(epoch), types.EmptyTSK) + if err != nil { + return cid.Undef, fmt.Errorf("failed to get tipset for epoch %d: %w", epoch, err) + } + tsKeyCid, err := ts.Key().Cid() + if err != nil { + return cid.Undef, fmt.Errorf("failed to get tipset key cid for epoch %d: %w", epoch, err) + } + return tsKeyCid, nil +} + func currentTimeString() string { currentTime := time.Now().Format("2006-01-02 15:04:05.000") return currentTime From c5329b1d0e45655328579d6045000331f65f113a Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 13:08:39 +0400 Subject: [PATCH 54/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- node/impl/full/chain_index.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/node/impl/full/chain_index.go b/node/impl/full/chain_index.go index 282b9bc4ea8..09c7a1ce3d3 100644 --- a/node/impl/full/chain_index.go +++ b/node/impl/full/chain_index.go @@ -39,9 +39,7 @@ func (ch *ChainIndexHandler) ChainValidateIndex(ctx context.Context, epoch abi.C var _ ChainIndexerAPI = (*ChainIndexHandler)(nil) -func NewChainIndexHandler( - indexer index.Indexer, -) *ChainIndexHandler { +func NewChainIndexHandler(indexer index.Indexer) *ChainIndexHandler { return &ChainIndexHandler{ indexer: indexer, } From 00612c89718bc4bda75cb506683581971f701275 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 13:16:32 +0400 Subject: [PATCH 55/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- api/api_full.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/api_full.go b/api/api_full.go index 0fd287fa866..0d1c22a93a5 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -65,8 +65,10 @@ type FullNode interface { // MethodGroup: ChainIndexer // The ChainIndexer method group contains methods for interacting with the chain indexer. + + // ChainValidateIndex validates and optionally backfills the chain index at a specific epoch. // - // The `ChainValidateIndex` API serves multiple purposes: + // It can be used to: // // 1. Validates the chain index at a specific epoch: // - Ensures consistency between indexed data and actual chain state From 185ed0f2a0cdb884d240510d67df701ae77dbca3 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 13:20:27 +0400 Subject: [PATCH 56/61] fix docs --- api/api_full.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 0d1c22a93a5..9b71728cd19 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -66,23 +66,22 @@ type FullNode interface { // MethodGroup: ChainIndexer // The ChainIndexer method group contains methods for interacting with the chain indexer. - // ChainValidateIndex validates and optionally backfills the chain index at a specific epoch. + // ChainValidateIndex validates the integrity of and optionally backfills + // the chain index at a specific epoch. // // It can be used to: // - // 1. Validates the chain index at a specific epoch: + // 1. Validate the chain index at a specific epoch: // - Ensures consistency between indexed data and actual chain state // - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.) // - // 2. Optionally backfills missing data: + // 2. Optionally backfill missing data: // - Backfills data if the index is missing information for the specified epoch // - Backfilling only occurs when the `backfill` parameter is set to `true` // - // 3. Detects "holes" in the index: + // 3. Detect "holes" in the index: // - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data // - // ChainValidateIndex validates the integrity of the chain index at a specified epoch and also optionally backfills missing data. - // // Parameters: // - epoch: The specific chain epoch for which to validate/backfill the index. // - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the From 4f26511a7caf93451020aabee0353ed5c1e04963 Mon Sep 17 00:00:00 2001 From: Aarsh Shah Date: Mon, 14 Oct 2024 13:27:02 +0400 Subject: [PATCH 57/61] Apply suggestions from code review Co-authored-by: Rod Vagg --- chain/index/api.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/chain/index/api.go b/chain/index/api.go index 860226dfabd..9b0f8bd8d30 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -221,7 +221,13 @@ func (si *SqliteIndexer) getIndexedTipSetData(ctx context.Context, ts *types.Tip // verifyIndexedData verifies that the indexed data for a tipset is correct // by comparing the number of messages and events in the chainstore to the number of messages and events indexed. -// NOTE: Events are loaded from the executed messages of the tipset at the next epoch (ts.Height() + 1). +// +// Notes: +// +// - Events are loaded from the executed messages of the tipset at the next epoch (ts.Height() + 1). +// - This is not a comprehensive verification because we only compare counts, assuming that a match +// means that the entries are correct. A future iteration may compare message and event details to +// confirm that they are what is expected. func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet, indexedData *indexedTipSetData) (err error) { tsKeyCid, err := ts.Key().Cid() if err != nil { From cafec26fd4aa19e6517c8c8bfc4c2944c5696f96 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 13:34:23 +0400 Subject: [PATCH 58/61] fix tests --- chain/index/api.go | 8 ++++---- cmd/lotus-shed/chain_index.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/chain/index/api.go b/chain/index/api.go index 860226dfabd..91e4b5e2958 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -52,7 +52,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain if expectedTs.Height() != epoch { if isIndexEmpty { return &types.IndexValidation{ - Height: uint64(epoch), + Height: epoch, IsNullRound: true, }, nil } @@ -148,7 +148,7 @@ func (si *SqliteIndexer) ChainValidateIndex(ctx context.Context, epoch abi.Chain return &types.IndexValidation{ TipSetKey: expectedTs.Key(), - Height: uint64(expectedTs.Height()), + Height: expectedTs.Height(), IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), IndexedEventEntriesCount: uint64(indexedData.nonRevertedEventEntriesCount), @@ -168,7 +168,7 @@ func (si *SqliteIndexer) validateIsNullRound(ctx context.Context, epoch abi.Chai } return &types.IndexValidation{ - Height: uint64(epoch), + Height: epoch, IsNullRound: true, }, nil } @@ -313,7 +313,7 @@ func (si *SqliteIndexer) backfillMissingTipset(ctx context.Context, ts *types.Ti return &types.IndexValidation{ TipSetKey: ts.Key(), - Height: uint64(ts.Height()), + Height: ts.Height(), Backfilled: true, IndexedMessagesCount: uint64(indexedData.nonRevertedMessageCount), IndexedEventsCount: uint64(indexedData.nonRevertedEventCount), diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 49d487559e2..2b29be33618 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -1,7 +1,6 @@ package main import ( - "api" "context" "encoding/json" "fmt" @@ -13,6 +12,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) @@ -199,7 +199,7 @@ like cron. } func tipsetKeyCid(ctx context.Context, epoch abi.ChainEpoch, a api.FullNode) (cid.Cid, error) { - ts, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(epoch), types.EmptyTSK) + ts, err := a.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(epoch), types.EmptyTSK) if err != nil { return cid.Undef, fmt.Errorf("failed to get tipset for epoch %d: %w", epoch, err) } From 8701f5542e8b846d04c0ba180d5a91d1f6e9b53b Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 13:37:05 +0400 Subject: [PATCH 59/61] fix tests --- chain/index/api_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chain/index/api_test.go b/chain/index/api_test.go index b239e5d8f1a..01f1b24c448 100644 --- a/chain/index/api_test.go +++ b/chain/index/api_test.go @@ -82,7 +82,7 @@ func TestValidateIsNullRoundSimple(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) require.Equal(t, tt.expectedResult, res.IsNullRound) - require.Equal(t, uint64(tt.epoch), res.Height) + require.Equal(t, tt.epoch, res.Height) } }) } @@ -208,7 +208,7 @@ func TestBackfillMissingEpoch(t *testing.T) { require.NoError(t, err) require.NotNil(t, result) require.True(t, result.Backfilled) - require.Equal(t, uint64(missingEpoch), result.Height) + require.EqualValues(t, missingEpoch, result.Height) require.Equal(t, uint64(1), result.IndexedMessagesCount) require.Equal(t, uint64(1), result.IndexedEventsCount) require.Equal(t, uint64(2), result.IndexedEventEntriesCount) From 77a0b60331ab0aae1807f8ad276e82f97dc6e896 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 14:14:11 +0400 Subject: [PATCH 60/61] make jen --- build/openrpc/full.json | 4 +- chain/index/api.go | 8 +- chain/index/ddls_test.go | 106 +++++++++++++------- cmd/lotus-shed/chain_index.go | 2 +- documentation/en/api-v1-unstable-methods.md | 30 +++++- 5 files changed, 102 insertions(+), 48 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 54ecd4c7efd..eeb1028116c 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -2012,7 +2012,7 @@ { "name": "Filecoin.ChainValidateIndex", "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", - "summary": "There are not yet any comments for this method.", + "summary": "ChainValidateIndex validates the integrity of and optionally backfills\nthe chain index at a specific epoch.\n\nIt can be used to:\n\n1. Validate the chain index at a specific epoch:\n - Ensures consistency between indexed data and actual chain state\n - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.)\n\n2. Optionally backfill missing data:\n - Backfills data if the index is missing information for the specified epoch\n - Backfilling only occurs when the `backfill` parameter is set to `true`\n\n3. Detect \"holes\" in the index:\n - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data\n\nParameters:\n - epoch: The specific chain epoch for which to validate/backfill the index.\n - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the\n specified epoch.\n\nReturns:\n - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill.\n - error: An error object if the validation/backfill fails. The error message will contain details about the index\n corruption if the call fails because of an incosistency between indexed data and the actual chain state.\n Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false.\n", "paramStructure": "by-position", "params": [ { @@ -2063,7 +2063,7 @@ "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" } ], - "Height": 42, + "Height": 10101, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, "IndexedEventEntriesCount": 42, diff --git a/chain/index/api.go b/chain/index/api.go index 307a47de1bc..aca6a3303b6 100644 --- a/chain/index/api.go +++ b/chain/index/api.go @@ -224,10 +224,10 @@ func (si *SqliteIndexer) getIndexedTipSetData(ctx context.Context, ts *types.Tip // // Notes: // -// - Events are loaded from the executed messages of the tipset at the next epoch (ts.Height() + 1). -// - This is not a comprehensive verification because we only compare counts, assuming that a match -// means that the entries are correct. A future iteration may compare message and event details to -// confirm that they are what is expected. +// - Events are loaded from the executed messages of the tipset at the next epoch (ts.Height() + 1). +// - This is not a comprehensive verification because we only compare counts, assuming that a match +// means that the entries are correct. A future iteration may compare message and event details to +// confirm that they are what is expected. func (si *SqliteIndexer) verifyIndexedData(ctx context.Context, ts *types.TipSet, indexedData *indexedTipSetData) (err error) { tsKeyCid, err := ts.Key().Cid() if err != nil { diff --git a/chain/index/ddls_test.go b/chain/index/ddls_test.go index 004b3f0a254..baae0c88062 100644 --- a/chain/index/ddls_test.go +++ b/chain/index/ddls_test.go @@ -7,39 +7,67 @@ import ( "github.com/stretchr/testify/require" ) +const ( + tipsetKeyCid1 = "test_tipset_key" + tipsetKeyCid2 = "test_tipset_key_2" + messageCid1 = "test_message_cid" + messageCid2 = "test_message_cid_2" + emitterAddr1 = "test_emitter_addr" +) + func TestHasRevertedEventsInTipsetStmt(t *testing.T) { s, err := NewSqliteIndexer(":memory:", nil, 0, false, 0) require.NoError(t, err) // running on empty DB should return false - verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), false) + verifyHasRevertedEventsInTipsetStmt(t, s, []byte(tipsetKeyCid1), false) // Insert tipset with a reverted event ts := tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, } messageID := insertTipsetMessage(t, s, ts) + // this event will be un-reverted later insertEvent(t, s, event{ messageID: messageID, eventIndex: 0, emitterId: 1, - emitterAddr: []byte("test_emitter_addr"), + emitterAddr: []byte(emitterAddr1), + reverted: true, + }) + + // this event should not be un-reverted + ts = tipsetMessage{ + tipsetKeyCid: []byte(tipsetKeyCid2), + height: 1, + reverted: false, + messageCid: []byte(messageCid2), + messageIndex: 0, + } + messageID2 := insertTipsetMessage(t, s, ts) + insertEvent(t, s, event{ + messageID: messageID2, + eventIndex: 0, + emitterId: 2, + emitterAddr: []byte(emitterAddr1), reverted: true, }) // Verify `hasRevertedEventsInTipset` returns true - verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), true) + verifyHasRevertedEventsInTipsetStmt(t, s, []byte(tipsetKeyCid1), true) + verifyHasRevertedEventsInTipsetStmt(t, s, []byte(tipsetKeyCid2), true) // change event to non-reverted - updateEventsToNonReverted(t, s, []byte("test_tipset_key")) + updateEventsToNonReverted(t, s, []byte(tipsetKeyCid1)) // Verify `hasRevertedEventsInTipset` returns false - verifyHasRevertedEventsInTipsetStmt(t, s, []byte("test_tipset_key"), false) + verifyHasRevertedEventsInTipsetStmt(t, s, []byte(tipsetKeyCid1), false) + verifyHasRevertedEventsInTipsetStmt(t, s, []byte(tipsetKeyCid2), true) } func TestGetNonRevertedTipsetCountStmts(t *testing.T) { @@ -47,16 +75,16 @@ func TestGetNonRevertedTipsetCountStmts(t *testing.T) { require.NoError(t, err) // running on empty DB should return 0 - verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 0) - verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 0) - verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedEventEntriesCount(t, s, []byte(tipsetKeyCid1), 0) + verifyNonRevertedEventCount(t, s, []byte(tipsetKeyCid1), 0) + verifyNonRevertedMessageCount(t, s, []byte(tipsetKeyCid1), 0) // Insert non-reverted tipset messageID := insertTipsetMessage(t, s, tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, }) @@ -65,14 +93,14 @@ func TestGetNonRevertedTipsetCountStmts(t *testing.T) { messageID: messageID, eventIndex: 0, emitterId: 1, - emitterAddr: []byte("test_emitter_addr"), + emitterAddr: []byte(emitterAddr1), reverted: false, }) eventID2 := insertEvent(t, s, event{ messageID: messageID, eventIndex: 1, emitterId: 2, - emitterAddr: []byte("test_emitter_addr"), + emitterAddr: []byte(emitterAddr1), reverted: false, }) @@ -95,25 +123,25 @@ func TestGetNonRevertedTipsetCountStmts(t *testing.T) { }) // verify 2 event entries - verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 2) + verifyNonRevertedEventEntriesCount(t, s, []byte(tipsetKeyCid1), 2) // Verify event count - verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 2) + verifyNonRevertedEventCount(t, s, []byte(tipsetKeyCid1), 2) // verify message count is 1 - verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 1) + verifyNonRevertedMessageCount(t, s, []byte(tipsetKeyCid1), 1) // mark tipset as reverted - revertTipset(t, s, []byte("test_tipset_key")) + revertTipset(t, s, []byte(tipsetKeyCid1)) // Verify `getNonRevertedTipsetEventEntriesCountStmt` returns 0 - verifyNonRevertedEventEntriesCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedEventEntriesCount(t, s, []byte(tipsetKeyCid1), 0) // verify event count is 0 - verifyNonRevertedEventCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedEventCount(t, s, []byte(tipsetKeyCid1), 0) // verify message count is 0 - verifyNonRevertedMessageCount(t, s, []byte("test_tipset_key"), 0) + verifyNonRevertedMessageCount(t, s, []byte(tipsetKeyCid1), 0) } func TestUpdateTipsetToNonRevertedStmt(t *testing.T) { @@ -122,17 +150,17 @@ func TestUpdateTipsetToNonRevertedStmt(t *testing.T) { // insert a reverted tipset ts := tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: true, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, } // Insert tipset messageId := insertTipsetMessage(t, s, ts) - res, err := s.stmts.updateTipsetToNonRevertedStmt.Exec([]byte("test_tipset_key")) + res, err := s.stmts.updateTipsetToNonRevertedStmt.Exec([]byte(tipsetKeyCid1)) require.NoError(t, err) rowsAffected, err := res.RowsAffected() @@ -154,10 +182,10 @@ func TestHasNullRoundAtHeightStmt(t *testing.T) { // insert tipset insertTipsetMessage(t, s, tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, }) @@ -170,19 +198,19 @@ func TestHasTipsetStmt(t *testing.T) { require.NoError(t, err) // running on empty DB should return false - verifyHasTipsetStmt(t, s, []byte("test_tipset_key"), false) + verifyHasTipsetStmt(t, s, []byte(tipsetKeyCid1), false) // insert tipset insertTipsetMessage(t, s, tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, }) // verify tipset exists - verifyHasTipsetStmt(t, s, []byte("test_tipset_key"), true) + verifyHasTipsetStmt(t, s, []byte(tipsetKeyCid1), true) // verify non-existent tipset verifyHasTipsetStmt(t, s, []byte("non_existent_tipset_key"), false) @@ -194,10 +222,10 @@ func TestUpdateEventsToRevertedStmt(t *testing.T) { // Insert a non-reverted tipset messageID := insertTipsetMessage(t, s, tipsetMessage{ - tipsetKeyCid: []byte("test_tipset_key"), + tipsetKeyCid: []byte(tipsetKeyCid1), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, }) @@ -206,14 +234,14 @@ func TestUpdateEventsToRevertedStmt(t *testing.T) { messageID: messageID, eventIndex: 0, emitterId: 1, - emitterAddr: []byte("test_emitter_addr"), + emitterAddr: []byte(emitterAddr1), reverted: false, }) insertEvent(t, s, event{ messageID: messageID, eventIndex: 1, emitterId: 2, - emitterAddr: []byte("test_emitter_addr"), + emitterAddr: []byte(emitterAddr1), reverted: false, }) @@ -224,7 +252,7 @@ func TestUpdateEventsToRevertedStmt(t *testing.T) { require.Equal(t, 2, count) // Execute updateEventsToRevertedStmt - _, err = s.stmts.updateEventsToRevertedStmt.Exec([]byte("test_tipset_key")) + _, err = s.stmts.updateEventsToRevertedStmt.Exec([]byte(tipsetKeyCid1)) require.NoError(t, err) // Verify events are now reverted @@ -410,8 +438,8 @@ func TestGetMsgIdForMsgCidAndTipsetStmt(t *testing.T) { require.NoError(t, err) // Insert a non-reverted tipset - tipsetKeyCid := []byte("test_tipset_key") - messageCid := []byte("test_message_cid") + tipsetKeyCid := []byte(tipsetKeyCid1) + messageCid := []byte(messageCid1) insertTipsetMessage(t, s, tipsetMessage{ tipsetKeyCid: tipsetKeyCid, height: 1, @@ -460,7 +488,7 @@ func TestForeignKeyCascadeDelete(t *testing.T) { tipsetKeyCid: []byte("test_tipset_key"), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, }) @@ -503,7 +531,7 @@ func TestInsertTipsetMessage(t *testing.T) { tipsetKeyCid: []byte("test_tipset_key"), height: 1, reverted: false, - messageCid: []byte("test_message_cid"), + messageCid: []byte(messageCid1), messageIndex: 0, } diff --git a/cmd/lotus-shed/chain_index.go b/cmd/lotus-shed/chain_index.go index 2b29be33618..701df62d596 100644 --- a/cmd/lotus-shed/chain_index.go +++ b/cmd/lotus-shed/chain_index.go @@ -199,7 +199,7 @@ like cron. } func tipsetKeyCid(ctx context.Context, epoch abi.ChainEpoch, a api.FullNode) (cid.Cid, error) { - ts, err := a.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(epoch), types.EmptyTSK) + ts, err := a.ChainGetTipSetByHeight(ctx, epoch, types.EmptyTSK) if err != nil { return cid.Undef, fmt.Errorf("failed to get tipset for epoch %d: %w", epoch, err) } diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 44ab77152e2..016499fdb01 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -1240,7 +1240,33 @@ Inputs: Response: `"0"` ### ChainValidateIndex -There are not yet any comments for this method. +ChainValidateIndex validates the integrity of and optionally backfills +the chain index at a specific epoch. + +It can be used to: + +1. Validate the chain index at a specific epoch: + - Ensures consistency between indexed data and actual chain state + - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.) + +2. Optionally backfill missing data: + - Backfills data if the index is missing information for the specified epoch + - Backfilling only occurs when the `backfill` parameter is set to `true` + +3. Detect "holes" in the index: + - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data + +Parameters: + - epoch: The specific chain epoch for which to validate/backfill the index. + - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the + specified epoch. + +Returns: + - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill. + - error: An error object if the validation/backfill fails. The error message will contain details about the index + corruption if the call fails because of an incosistency between indexed data and the actual chain state. + Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false. + Perms: write @@ -1263,7 +1289,7 @@ Response: "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" } ], - "Height": 42, + "Height": 10101, "IndexedMessagesCount": 42, "IndexedEventsCount": 42, "IndexedEventEntriesCount": 42, From 9cd86faafd5f9653e73a965e25b7124961e61be5 Mon Sep 17 00:00:00 2001 From: aarshkshah1992 Date: Mon, 14 Oct 2024 20:59:22 +0400 Subject: [PATCH 61/61] fix conflicts --- build/openrpc/full.json | 570 ++++++++++++--------- build/openrpc/gateway.json | 204 ++++---- build/openrpc/miner.json | 176 +++---- build/openrpc/worker.json | 74 +-- chain/index/api_test.go | 2 +- chain/index/events_test.go | 4 +- chain/index/gc_test.go | 2 +- chain/index/interface.go | 1 - documentation/en/default-lotus-config.toml | 2 +- 9 files changed, 569 insertions(+), 466 deletions(-) diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 863576e0f96..6c7581c27a2 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -37,7 +37,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1344" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1346" } }, { @@ -60,7 +60,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1355" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1357" } }, { @@ -103,7 +103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1366" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1368" } }, { @@ -214,7 +214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1388" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1390" } }, { @@ -454,7 +454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1399" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1401" } }, { @@ -685,7 +685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1410" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1412" } }, { @@ -784,7 +784,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1421" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1423" } }, { @@ -816,7 +816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1432" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1434" } }, { @@ -922,7 +922,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1443" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1445" } }, { @@ -1019,7 +1019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1454" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1456" } }, { @@ -1078,7 +1078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1465" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1467" } }, { @@ -1171,7 +1171,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1476" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1478" } }, { @@ -1255,7 +1255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1487" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1489" } }, { @@ -1355,7 +1355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1498" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1500" } }, { @@ -1411,7 +1411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1509" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1511" } }, { @@ -1484,7 +1484,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1520" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1522" } }, { @@ -1557,7 +1557,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1531" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1533" } }, { @@ -1604,7 +1604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1542" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1544" } }, { @@ -1636,7 +1636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1553" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1555" } }, { @@ -1691,7 +1691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1564" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1566" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1586" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1588" } }, { @@ -1780,7 +1780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1597" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1599" } }, { @@ -1827,7 +1827,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1608" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1610" } }, { @@ -1874,7 +1874,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1619" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1621" } }, { @@ -1954,7 +1954,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1630" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1632" } }, { @@ -2006,7 +2006,111 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1641" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1643" + } + }, + { + "name": "Filecoin.ChainValidateIndex", + "description": "```go\nfunc (s *FullNodeStruct) ChainValidateIndex(p0 context.Context, p1 abi.ChainEpoch, p2 bool) (*types.IndexValidation, error) {\n\tif s.Internal.ChainValidateIndex == nil {\n\t\treturn nil, ErrNotSupported\n\t}\n\treturn s.Internal.ChainValidateIndex(p0, p1, p2)\n}\n```", + "summary": "ChainValidateIndex validates the integrity of and optionally backfills\nthe chain index at a specific epoch.\n\nIt can be used to:\n\n1. Validate the chain index at a specific epoch:\n - Ensures consistency between indexed data and actual chain state\n - Reports any errors found during validation (i.e. the indexed data does not match the actual chain state, missing data, etc.)\n\n2. Optionally backfill missing data:\n - Backfills data if the index is missing information for the specified epoch\n - Backfilling only occurs when the `backfill` parameter is set to `true`\n\n3. Detect \"holes\" in the index:\n - If `backfill` is `false` and the index lacks data for the specified epoch, the API returns an error indicating missing data\n\nParameters:\n - epoch: The specific chain epoch for which to validate/backfill the index.\n - backfill: A boolean flag indicating whether to attempt backfilling of missing data if the index does not have data for the\n specified epoch.\n\nReturns:\n - *types.IndexValidation: A pointer to an IndexValidation struct containing the results of the validation/backfill.\n - error: An error object if the validation/backfill fails. The error message will contain details about the index\n corruption if the call fails because of an incosistency between indexed data and the actual chain state.\n Note: The API returns an error if the index does not have data for the specified epoch and backfill is set to false.\n", + "paramStructure": "by-position", + "params": [ + { + "name": "p1", + "description": "abi.ChainEpoch", + "summary": "", + "schema": { + "title": "number", + "description": "Number is a number", + "examples": [ + 10101 + ], + "type": [ + "number" + ] + }, + "required": true, + "deprecated": false + }, + { + "name": "p2", + "description": "bool", + "summary": "", + "schema": { + "examples": [ + true + ], + "type": [ + "boolean" + ] + }, + "required": true, + "deprecated": false + } + ], + "result": { + "name": "*types.IndexValidation", + "description": "*types.IndexValidation", + "summary": "", + "schema": { + "examples": [ + { + "TipSetKey": [ + { + "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4" + }, + { + "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve" + } + ], + "Height": 10101, + "IndexedMessagesCount": 42, + "IndexedEventsCount": 42, + "IndexedEventEntriesCount": 42, + "Backfilled": true, + "IsNullRound": true + } + ], + "additionalProperties": false, + "properties": { + "Backfilled": { + "type": "boolean" + }, + "Height": { + "title": "number", + "type": "number" + }, + "IndexedEventEntriesCount": { + "title": "number", + "type": "number" + }, + "IndexedEventsCount": { + "title": "number", + "type": "number" + }, + "IndexedMessagesCount": { + "title": "number", + "type": "number" + }, + "IsNullRound": { + "type": "boolean" + }, + "TipSetKey": { + "additionalProperties": false, + "type": "object" + } + }, + "type": [ + "object" + ] + }, + "required": true, + "deprecated": false + }, + "deprecated": false, + "externalDocs": { + "description": "Github remote link", + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1654" } }, { @@ -2045,7 +2149,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1652" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1665" } }, { @@ -2092,7 +2196,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1663" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1676" } }, { @@ -2147,7 +2251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1674" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1687" } }, { @@ -2176,7 +2280,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1685" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1698" } }, { @@ -2313,7 +2417,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1696" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1709" } }, { @@ -2342,7 +2446,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1707" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1720" } }, { @@ -2396,7 +2500,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1718" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1731" } }, { @@ -2487,7 +2591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1729" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1742" } }, { @@ -2515,7 +2619,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1740" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1753" } }, { @@ -2605,7 +2709,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1751" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1764" } }, { @@ -2861,7 +2965,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1762" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1775" } }, { @@ -3106,7 +3210,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1773" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1786" } }, { @@ -3382,7 +3486,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1784" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1797" } }, { @@ -3675,7 +3779,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1795" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1808" } }, { @@ -3731,7 +3835,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1806" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1819" } }, { @@ -3778,7 +3882,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1817" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1830" } }, { @@ -3876,7 +3980,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1828" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1841" } }, { @@ -3942,7 +4046,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1839" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1852" } }, { @@ -4008,7 +4112,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1850" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1863" } }, { @@ -4117,7 +4221,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1861" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1874" } }, { @@ -4175,7 +4279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1872" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1885" } }, { @@ -4297,7 +4401,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1883" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1896" } }, { @@ -4506,7 +4610,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1894" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1907" } }, { @@ -4706,7 +4810,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1905" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1918" } }, { @@ -4898,7 +5002,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1916" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1929" } }, { @@ -5107,7 +5211,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1927" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1940" } }, { @@ -5198,7 +5302,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1938" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1951" } }, { @@ -5256,7 +5360,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1949" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1962" } }, { @@ -5514,7 +5618,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1960" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1973" } }, { @@ -5789,7 +5893,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1971" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1984" } }, { @@ -5817,7 +5921,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1982" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1995" } }, { @@ -5855,7 +5959,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1993" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2006" } }, { @@ -5963,7 +6067,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2004" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2017" } }, { @@ -6001,7 +6105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2015" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2028" } }, { @@ -6030,7 +6134,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2026" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2039" } }, { @@ -6093,7 +6197,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2037" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2050" } }, { @@ -6156,7 +6260,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2048" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2061" } }, { @@ -6219,7 +6323,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2059" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2072" } }, { @@ -6264,7 +6368,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2070" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2083" } }, { @@ -6386,7 +6490,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2081" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2094" } }, { @@ -6562,7 +6666,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2092" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2105" } }, { @@ -6717,7 +6821,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2103" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2116" } }, { @@ -6839,7 +6943,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2114" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2127" } }, { @@ -6893,7 +6997,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2125" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2138" } }, { @@ -6947,7 +7051,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2136" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2149" } }, { @@ -7132,7 +7236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2147" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2160" } }, { @@ -7215,7 +7319,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2158" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2171" } }, { @@ -7298,7 +7402,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2169" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2182" } }, { @@ -7465,7 +7569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2180" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2193" } }, { @@ -7670,7 +7774,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2191" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2204" } }, { @@ -7764,7 +7868,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2202" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2215" } }, { @@ -7810,7 +7914,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2213" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2226" } }, { @@ -7837,7 +7941,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2224" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2237" } }, { @@ -7916,7 +8020,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2235" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2248" } }, { @@ -7979,7 +8083,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2246" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2259" } }, { @@ -8122,7 +8226,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2257" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2270" } }, { @@ -8249,7 +8353,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2268" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2281" } }, { @@ -8351,7 +8455,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2279" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2292" } }, { @@ -8574,7 +8678,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2290" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2303" } }, { @@ -8757,7 +8861,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2301" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2314" } }, { @@ -8837,7 +8941,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2312" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2325" } }, { @@ -8882,7 +8986,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2323" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2336" } }, { @@ -8938,7 +9042,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2334" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2347" } }, { @@ -9018,7 +9122,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2345" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2358" } }, { @@ -9098,7 +9202,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2356" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2369" } }, { @@ -9583,7 +9687,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2367" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2380" } }, { @@ -9777,7 +9881,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2378" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2391" } }, { @@ -9932,7 +10036,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2389" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2402" } }, { @@ -10181,7 +10285,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2400" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2413" } }, { @@ -10336,7 +10440,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2411" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2424" } }, { @@ -10513,7 +10617,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2422" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2435" } }, { @@ -10611,7 +10715,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2433" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2446" } }, { @@ -10776,7 +10880,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2444" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2457" } }, { @@ -10815,7 +10919,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2455" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2468" } }, { @@ -10880,7 +10984,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2466" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2479" } }, { @@ -10926,7 +11030,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2477" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2490" } }, { @@ -11076,7 +11180,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2488" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2501" } }, { @@ -11213,7 +11317,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2499" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2512" } }, { @@ -11444,7 +11548,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2510" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2523" } }, { @@ -11581,7 +11685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2521" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2534" } }, { @@ -11746,7 +11850,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2532" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2545" } }, { @@ -11823,7 +11927,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2543" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2556" } }, { @@ -12018,7 +12122,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2565" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2578" } }, { @@ -12197,7 +12301,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2576" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2589" } }, { @@ -12359,7 +12463,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2587" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2600" } }, { @@ -12507,7 +12611,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2598" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2611" } }, { @@ -12735,7 +12839,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2609" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2622" } }, { @@ -12883,7 +12987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2620" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2633" } }, { @@ -13095,7 +13199,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2631" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2644" } }, { @@ -13301,7 +13405,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2642" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2655" } }, { @@ -13369,7 +13473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2653" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2666" } }, { @@ -13486,7 +13590,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2664" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2677" } }, { @@ -13577,7 +13681,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2675" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2688" } }, { @@ -13663,7 +13767,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2686" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2699" } }, { @@ -13858,7 +13962,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2697" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2710" } }, { @@ -14020,7 +14124,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2708" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2721" } }, { @@ -14216,7 +14320,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2719" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2732" } }, { @@ -14396,7 +14500,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2730" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2743" } }, { @@ -14559,7 +14663,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2741" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2754" } }, { @@ -14586,7 +14690,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2752" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2765" } }, { @@ -14613,7 +14717,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2763" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2776" } }, { @@ -14712,7 +14816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2774" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2787" } }, { @@ -14758,7 +14862,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2785" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2798" } }, { @@ -14858,7 +14962,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2796" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2809" } }, { @@ -14974,7 +15078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2807" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2820" } }, { @@ -15022,7 +15126,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2818" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2831" } }, { @@ -15114,7 +15218,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2829" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2842" } }, { @@ -15229,7 +15333,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2840" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2853" } }, { @@ -15277,7 +15381,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2851" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2864" } }, { @@ -15314,7 +15418,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2862" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2875" } }, { @@ -15586,7 +15690,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2873" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2886" } }, { @@ -15634,7 +15738,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2884" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2897" } }, { @@ -15692,7 +15796,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2895" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2908" } }, { @@ -15897,7 +16001,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2906" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2919" } }, { @@ -16100,7 +16204,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2917" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2930" } }, { @@ -16269,7 +16373,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2928" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2941" } }, { @@ -16473,7 +16577,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2939" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2952" } }, { @@ -16640,7 +16744,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2950" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2963" } }, { @@ -16847,7 +16951,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2961" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2974" } }, { @@ -16915,7 +17019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2972" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2985" } }, { @@ -16967,7 +17071,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2983" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2996" } }, { @@ -17016,7 +17120,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2994" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3007" } }, { @@ -17107,7 +17211,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3005" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3018" } }, { @@ -17613,7 +17717,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3016" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3029" } }, { @@ -17719,7 +17823,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3027" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3040" } }, { @@ -17771,7 +17875,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3038" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3051" } }, { @@ -18323,7 +18427,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3049" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3062" } }, { @@ -18437,7 +18541,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3060" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3073" } }, { @@ -18534,7 +18638,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3071" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3084" } }, { @@ -18634,7 +18738,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3082" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3095" } }, { @@ -18722,7 +18826,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3093" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3106" } }, { @@ -18822,7 +18926,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3104" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3117" } }, { @@ -18909,7 +19013,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3115" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3128" } }, { @@ -19000,7 +19104,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3126" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3139" } }, { @@ -19125,7 +19229,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3137" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3150" } }, { @@ -19234,7 +19338,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3148" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3161" } }, { @@ -19304,7 +19408,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3159" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3172" } }, { @@ -19407,7 +19511,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3170" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3183" } }, { @@ -19468,7 +19572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3181" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3194" } }, { @@ -19598,7 +19702,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3192" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3205" } }, { @@ -19705,7 +19809,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3203" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3216" } }, { @@ -19924,7 +20028,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3214" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3227" } }, { @@ -20001,7 +20105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3225" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3238" } }, { @@ -20078,7 +20182,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3236" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3249" } }, { @@ -20187,7 +20291,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3247" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3260" } }, { @@ -20296,7 +20400,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3258" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3271" } }, { @@ -20357,7 +20461,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3269" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3282" } }, { @@ -20467,7 +20571,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3280" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3293" } }, { @@ -20528,7 +20632,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3291" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3304" } }, { @@ -20596,7 +20700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3302" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3315" } }, { @@ -20664,7 +20768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3313" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3326" } }, { @@ -20745,7 +20849,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3324" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3337" } }, { @@ -20899,7 +21003,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3335" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3348" } }, { @@ -20971,7 +21075,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3346" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3359" } }, { @@ -21135,7 +21239,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3357" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3370" } }, { @@ -21300,7 +21404,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3368" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3381" } }, { @@ -21370,7 +21474,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3379" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3392" } }, { @@ -21438,7 +21542,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3390" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3403" } }, { @@ -21531,7 +21635,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3401" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3414" } }, { @@ -21602,7 +21706,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3412" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3425" } }, { @@ -21803,7 +21907,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3423" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3436" } }, { @@ -21935,7 +22039,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3434" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3447" } }, { @@ -22038,7 +22142,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3445" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3458" } }, { @@ -22175,7 +22279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3456" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3469" } }, { @@ -22286,7 +22390,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3467" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3480" } }, { @@ -22418,7 +22522,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3478" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3491" } }, { @@ -22549,7 +22653,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3489" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3502" } }, { @@ -22620,7 +22724,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3500" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3513" } }, { @@ -22704,7 +22808,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3511" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3524" } }, { @@ -22790,7 +22894,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3522" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3535" } }, { @@ -22973,7 +23077,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3533" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3546" } }, { @@ -23000,7 +23104,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3544" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3557" } }, { @@ -23053,7 +23157,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3555" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3568" } }, { @@ -23141,7 +23245,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3566" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3579" } }, { @@ -23592,7 +23696,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3577" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3590" } }, { @@ -23759,7 +23863,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3588" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3601" } }, { @@ -23857,7 +23961,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3599" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3612" } }, { @@ -24030,7 +24134,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3610" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3623" } }, { @@ -24128,7 +24232,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3621" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3634" } }, { @@ -24279,7 +24383,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3632" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3645" } }, { @@ -24364,7 +24468,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3643" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3656" } }, { @@ -24432,7 +24536,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3654" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3667" } }, { @@ -24484,7 +24588,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3665" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3678" } }, { @@ -24552,7 +24656,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3676" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3689" } }, { @@ -24713,7 +24817,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3687" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3700" } }, { @@ -24760,7 +24864,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3709" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3722" } }, { @@ -24807,7 +24911,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3720" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3733" } }, { @@ -24850,7 +24954,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3742" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3755" } }, { @@ -24946,7 +25050,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3753" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3766" } }, { @@ -25212,7 +25316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3764" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3777" } }, { @@ -25235,7 +25339,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3775" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3788" } }, { @@ -25278,7 +25382,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3786" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3799" } }, { @@ -25329,7 +25433,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3797" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3810" } }, { @@ -25374,7 +25478,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3808" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3821" } }, { @@ -25402,7 +25506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3819" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3832" } }, { @@ -25442,7 +25546,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3830" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3843" } }, { @@ -25501,7 +25605,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3841" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3854" } }, { @@ -25545,7 +25649,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3852" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3865" } }, { @@ -25604,7 +25708,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3863" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3876" } }, { @@ -25641,7 +25745,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3874" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3887" } }, { @@ -25685,7 +25789,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3885" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3898" } }, { @@ -25725,7 +25829,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3896" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3909" } }, { @@ -25800,7 +25904,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3907" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3920" } }, { @@ -26008,7 +26112,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3918" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3931" } }, { @@ -26052,7 +26156,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3929" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3942" } }, { @@ -26142,7 +26246,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3940" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3953" } }, { @@ -26169,7 +26273,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3951" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3964" } } ] diff --git a/build/openrpc/gateway.json b/build/openrpc/gateway.json index d505b5d2769..0fb1576a48a 100644 --- a/build/openrpc/gateway.json +++ b/build/openrpc/gateway.json @@ -242,7 +242,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3962" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3975" } }, { @@ -473,7 +473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3973" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3986" } }, { @@ -572,7 +572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3984" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3997" } }, { @@ -604,7 +604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3995" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4008" } }, { @@ -710,7 +710,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4006" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4019" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4017" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4030" } }, { @@ -887,7 +887,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4028" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4041" } }, { @@ -987,7 +987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4039" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4052" } }, { @@ -1043,7 +1043,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4050" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4063" } }, { @@ -1116,7 +1116,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4061" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4074" } }, { @@ -1189,7 +1189,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4072" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4085" } }, { @@ -1236,7 +1236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4083" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4096" } }, { @@ -1268,7 +1268,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4094" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4107" } }, { @@ -1305,7 +1305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4116" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4129" } }, { @@ -1352,7 +1352,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4127" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4140" } }, { @@ -1392,7 +1392,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4138" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4151" } }, { @@ -1439,7 +1439,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4149" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4162" } }, { @@ -1494,7 +1494,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4160" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4173" } }, { @@ -1523,7 +1523,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4171" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4184" } }, { @@ -1660,7 +1660,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4182" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4195" } }, { @@ -1689,7 +1689,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4193" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4206" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4204" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4217" } }, { @@ -1834,7 +1834,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4215" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4228" } }, { @@ -1862,7 +1862,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4226" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4239" } }, { @@ -1952,7 +1952,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4237" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4250" } }, { @@ -2208,7 +2208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4248" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4261" } }, { @@ -2453,7 +2453,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4259" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4272" } }, { @@ -2729,7 +2729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4270" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4283" } }, { @@ -3022,7 +3022,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4281" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4294" } }, { @@ -3078,7 +3078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4292" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4305" } }, { @@ -3125,7 +3125,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4303" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4316" } }, { @@ -3223,7 +3223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4314" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4327" } }, { @@ -3289,7 +3289,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4325" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4338" } }, { @@ -3355,7 +3355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4336" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4349" } }, { @@ -3464,7 +3464,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4347" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4360" } }, { @@ -3522,7 +3522,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4358" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4371" } }, { @@ -3644,7 +3644,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4369" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4382" } }, { @@ -3836,7 +3836,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4380" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4393" } }, { @@ -4045,7 +4045,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4391" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4404" } }, { @@ -4136,7 +4136,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4402" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4415" } }, { @@ -4194,7 +4194,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4413" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4426" } }, { @@ -4452,7 +4452,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4424" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4437" } }, { @@ -4727,7 +4727,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4435" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4448" } }, { @@ -4755,7 +4755,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4446" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4459" } }, { @@ -4793,7 +4793,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4457" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4470" } }, { @@ -4901,7 +4901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4468" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4481" } }, { @@ -4939,7 +4939,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4479" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4492" } }, { @@ -4968,7 +4968,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4490" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4503" } }, { @@ -5031,7 +5031,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4501" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4514" } }, { @@ -5094,7 +5094,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4512" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4525" } }, { @@ -5139,7 +5139,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4523" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4536" } }, { @@ -5261,7 +5261,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4534" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4547" } }, { @@ -5437,7 +5437,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4545" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4558" } }, { @@ -5592,7 +5592,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4556" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4569" } }, { @@ -5714,7 +5714,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4567" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4580" } }, { @@ -5768,7 +5768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4578" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4591" } }, { @@ -5822,7 +5822,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4589" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4602" } }, { @@ -5885,7 +5885,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4600" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4613" } }, { @@ -5987,7 +5987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4611" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4624" } }, { @@ -6210,7 +6210,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4622" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4635" } }, { @@ -6393,7 +6393,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4633" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4646" } }, { @@ -6587,7 +6587,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4644" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4657" } }, { @@ -6633,7 +6633,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4655" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4668" } }, { @@ -6783,7 +6783,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4666" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4679" } }, { @@ -6920,7 +6920,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4677" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4690" } }, { @@ -6988,7 +6988,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4688" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4701" } }, { @@ -7105,7 +7105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4699" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4712" } }, { @@ -7196,7 +7196,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4710" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4723" } }, { @@ -7282,7 +7282,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4721" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4734" } }, { @@ -7309,7 +7309,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4732" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4745" } }, { @@ -7336,7 +7336,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4743" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4756" } }, { @@ -7404,7 +7404,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4754" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4767" } }, { @@ -7910,7 +7910,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4765" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4778" } }, { @@ -8007,7 +8007,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4776" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4789" } }, { @@ -8107,7 +8107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4787" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4800" } }, { @@ -8207,7 +8207,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4798" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4811" } }, { @@ -8332,7 +8332,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4809" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4822" } }, { @@ -8441,7 +8441,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4820" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4833" } }, { @@ -8544,7 +8544,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4831" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4844" } }, { @@ -8674,7 +8674,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4842" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4855" } }, { @@ -8781,7 +8781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4853" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4866" } }, { @@ -8842,7 +8842,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4864" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4877" } }, { @@ -8910,7 +8910,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4875" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4888" } }, { @@ -8991,7 +8991,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4886" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4899" } }, { @@ -9155,7 +9155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4897" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4910" } }, { @@ -9248,7 +9248,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4908" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4921" } }, { @@ -9449,7 +9449,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4919" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4932" } }, { @@ -9560,7 +9560,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4930" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4943" } }, { @@ -9691,7 +9691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4941" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4954" } }, { @@ -9777,7 +9777,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4952" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4965" } }, { @@ -9804,7 +9804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4963" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4976" } }, { @@ -9857,7 +9857,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4974" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4987" } }, { @@ -9945,7 +9945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4985" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4998" } }, { @@ -10396,7 +10396,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4996" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5009" } }, { @@ -10563,7 +10563,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5007" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5020" } }, { @@ -10736,7 +10736,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5018" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5031" } }, { @@ -10804,7 +10804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5029" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5042" } }, { @@ -10872,7 +10872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5040" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5053" } }, { @@ -11033,7 +11033,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5051" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5064" } }, { @@ -11078,7 +11078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5073" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5086" } }, { @@ -11123,7 +11123,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5084" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5097" } }, { @@ -11150,7 +11150,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5095" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5108" } } ] diff --git a/build/openrpc/miner.json b/build/openrpc/miner.json index f8a701ccfea..1ac9768be0a 100644 --- a/build/openrpc/miner.json +++ b/build/openrpc/miner.json @@ -30,7 +30,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5381" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5394" } }, { @@ -109,7 +109,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5392" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5405" } }, { @@ -155,7 +155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5403" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5416" } }, { @@ -203,7 +203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5414" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5427" } }, { @@ -251,7 +251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5425" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5438" } }, { @@ -354,7 +354,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5436" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5449" } }, { @@ -428,7 +428,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5447" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5460" } }, { @@ -591,7 +591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5458" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5471" } }, { @@ -742,7 +742,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5469" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5482" } }, { @@ -781,7 +781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5480" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5493" } }, { @@ -913,7 +913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5491" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5504" } }, { @@ -945,7 +945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5502" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5515" } }, { @@ -986,7 +986,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5513" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5526" } }, { @@ -1054,7 +1054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5524" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5537" } }, { @@ -1185,7 +1185,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5535" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5548" } }, { @@ -1316,7 +1316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5546" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5559" } }, { @@ -1416,7 +1416,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5557" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5570" } }, { @@ -1516,7 +1516,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5568" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5581" } }, { @@ -1616,7 +1616,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5579" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5592" } }, { @@ -1716,7 +1716,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5590" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5603" } }, { @@ -1816,7 +1816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5601" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5614" } }, { @@ -1916,7 +1916,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5612" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5625" } }, { @@ -2040,7 +2040,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5623" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5636" } }, { @@ -2164,7 +2164,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5634" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5647" } }, { @@ -2279,7 +2279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5645" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5658" } }, { @@ -2379,7 +2379,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5656" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5669" } }, { @@ -2512,7 +2512,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5667" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5680" } }, { @@ -2636,7 +2636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5678" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5691" } }, { @@ -2760,7 +2760,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5689" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5702" } }, { @@ -2884,7 +2884,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5700" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5713" } }, { @@ -3017,7 +3017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5711" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5724" } }, { @@ -3117,7 +3117,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5722" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5735" } }, { @@ -3157,7 +3157,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5733" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5746" } }, { @@ -3229,7 +3229,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5744" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5757" } }, { @@ -3279,7 +3279,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5755" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5768" } }, { @@ -3323,7 +3323,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5766" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5779" } }, { @@ -3364,7 +3364,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5777" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5790" } }, { @@ -3608,7 +3608,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5788" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5801" } }, { @@ -3682,7 +3682,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5799" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5812" } }, { @@ -3732,7 +3732,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5810" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5823" } }, { @@ -3761,7 +3761,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5821" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5834" } }, { @@ -3790,7 +3790,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5832" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5845" } }, { @@ -3846,7 +3846,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5843" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5856" } }, { @@ -3869,7 +3869,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5854" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5867" } }, { @@ -3929,7 +3929,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5865" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5878" } }, { @@ -3968,7 +3968,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5876" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5889" } }, { @@ -4008,7 +4008,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5887" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5900" } }, { @@ -4081,7 +4081,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5898" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5911" } }, { @@ -4145,7 +4145,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5909" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5922" } }, { @@ -4208,7 +4208,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5920" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5933" } }, { @@ -4258,7 +4258,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5931" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5944" } }, { @@ -4817,7 +4817,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5942" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5955" } }, { @@ -4858,7 +4858,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5953" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5966" } }, { @@ -4899,7 +4899,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5964" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5977" } }, { @@ -4940,7 +4940,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5975" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5988" } }, { @@ -4981,7 +4981,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5986" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5999" } }, { @@ -5022,7 +5022,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5997" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6010" } }, { @@ -5053,7 +5053,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6008" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6021" } }, { @@ -5103,7 +5103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6019" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6032" } }, { @@ -5144,7 +5144,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6030" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6043" } }, { @@ -5183,7 +5183,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6041" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6054" } }, { @@ -5247,7 +5247,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6052" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6065" } }, { @@ -5305,7 +5305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6063" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6076" } }, { @@ -5752,7 +5752,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6074" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6087" } }, { @@ -5788,7 +5788,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6085" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6098" } }, { @@ -5931,7 +5931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6096" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6109" } }, { @@ -5987,7 +5987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6107" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6120" } }, { @@ -6026,7 +6026,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6118" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6131" } }, { @@ -6203,7 +6203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6129" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6142" } }, { @@ -6255,7 +6255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6140" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6153" } }, { @@ -6447,7 +6447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6151" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6164" } }, { @@ -6547,7 +6547,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6162" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6175" } }, { @@ -6601,7 +6601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6173" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6186" } }, { @@ -6640,7 +6640,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6184" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6197" } }, { @@ -6725,7 +6725,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6195" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6208" } }, { @@ -6919,7 +6919,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6206" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6219" } }, { @@ -7017,7 +7017,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6217" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6230" } }, { @@ -7149,7 +7149,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6228" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6241" } }, { @@ -7203,7 +7203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6239" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6252" } }, { @@ -7237,7 +7237,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6250" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6263" } }, { @@ -7324,7 +7324,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6261" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6274" } }, { @@ -7378,7 +7378,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6272" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6285" } }, { @@ -7478,7 +7478,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6283" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6296" } }, { @@ -7555,7 +7555,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6294" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6307" } }, { @@ -7646,7 +7646,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6305" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6318" } }, { @@ -7685,7 +7685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6316" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6329" } }, { @@ -7801,7 +7801,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6327" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6340" } }, { @@ -9901,7 +9901,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6338" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6351" } } ] diff --git a/build/openrpc/worker.json b/build/openrpc/worker.json index 14cec75ca21..77c70b69cb0 100644 --- a/build/openrpc/worker.json +++ b/build/openrpc/worker.json @@ -161,7 +161,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6426" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6439" } }, { @@ -252,7 +252,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6437" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6450" } }, { @@ -420,7 +420,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6448" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6461" } }, { @@ -447,7 +447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6459" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6472" } }, { @@ -597,7 +597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6470" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6483" } }, { @@ -700,7 +700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6481" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6494" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6492" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6505" } }, { @@ -925,7 +925,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6503" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6516" } }, { @@ -1135,7 +1135,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6514" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6527" } }, { @@ -1306,7 +1306,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6525" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6538" } }, { @@ -3350,7 +3350,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6536" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6549" } }, { @@ -3470,7 +3470,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6547" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6560" } }, { @@ -3531,7 +3531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6558" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6571" } }, { @@ -3569,7 +3569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6569" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6582" } }, { @@ -3729,7 +3729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6580" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6593" } }, { @@ -3913,7 +3913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6591" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6604" } }, { @@ -4054,7 +4054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6602" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6615" } }, { @@ -4107,7 +4107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6613" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6626" } }, { @@ -4250,7 +4250,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6624" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6637" } }, { @@ -4474,7 +4474,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6635" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6648" } }, { @@ -4601,7 +4601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6646" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6659" } }, { @@ -4768,7 +4768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6657" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6670" } }, { @@ -4895,7 +4895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6668" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6681" } }, { @@ -4933,7 +4933,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6679" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6692" } }, { @@ -4972,7 +4972,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6690" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6703" } }, { @@ -4995,7 +4995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6701" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6714" } }, { @@ -5034,7 +5034,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6712" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6725" } }, { @@ -5057,7 +5057,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6723" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6736" } }, { @@ -5096,7 +5096,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6734" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6747" } }, { @@ -5130,7 +5130,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6745" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6758" } }, { @@ -5184,7 +5184,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6756" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6769" } }, { @@ -5223,7 +5223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6767" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6780" } }, { @@ -5262,7 +5262,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6778" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6791" } }, { @@ -5297,7 +5297,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6789" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6802" } }, { @@ -5477,7 +5477,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6800" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6813" } }, { @@ -5506,7 +5506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6811" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6824" } }, { @@ -5529,7 +5529,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6822" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6835" } } ] diff --git a/chain/index/api_test.go b/chain/index/api_test.go index 01f1b24c448..65d317f9e92 100644 --- a/chain/index/api_test.go +++ b/chain/index/api_test.go @@ -167,7 +167,7 @@ func TestBackfillMissingEpoch(t *testing.T) { si.Start() // Initialize address resolver - si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + si.SetActorToDelegatedAddresFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { idAddr, err := address.NewIDAddress(uint64(emitter)) if err != nil { return address.Undef, false diff --git a/chain/index/events_test.go b/chain/index/events_test.go index 2b809e0ea3b..93bca3882df 100644 --- a/chain/index/events_test.go +++ b/chain/index/events_test.go @@ -119,7 +119,7 @@ func TestGetEventsForFilterWithEvents(t *testing.T) { evs: events, } - si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + si.SetActorToDelegatedAddresFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { idAddr, err := address.NewIDAddress(uint64(emitter)) if err != nil { return address.Undef, false @@ -247,7 +247,7 @@ func TestGetEventsFilterByAddress(t *testing.T) { evs: events, } - si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + si.SetActorToDelegatedAddresFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { if emitter == abi.ActorID(1) { return delegatedAddr1, true } diff --git a/chain/index/gc_test.go b/chain/index/gc_test.go index c3ca7a57118..31ae0f69640 100644 --- a/chain/index/gc_test.go +++ b/chain/index/gc_test.go @@ -55,7 +55,7 @@ func TestGC(t *testing.T) { evs: events, } - si.SetIdToRobustAddrFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { + si.SetActorToDelegatedAddresFunc(func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { idAddr, err := address.NewIDAddress(uint64(emitter)) if err != nil { return address.Undef, false diff --git a/chain/index/interface.go b/chain/index/interface.go index f538f245248..cbc5bb60830 100644 --- a/chain/index/interface.go +++ b/chain/index/interface.go @@ -56,7 +56,6 @@ type Indexer interface { IndexEthTxHash(ctx context.Context, txHash ethtypes.EthHash, c cid.Cid) error SetActorToDelegatedAddresFunc(idToRobustAddrFunc ActorToDelegatedAddressFunc) - SetRecomputeTipSetStateFunc(recomputeTipSetStateFunc recomputeTipSetStateFunc) SetExecutedMessagesLoaderFunc(f emsLoaderFunc) Apply(ctx context.Context, from, to *types.TipSet) error diff --git a/documentation/en/default-lotus-config.toml b/documentation/en/default-lotus-config.toml index 34906677bdc..a821f73a5bd 100644 --- a/documentation/en/default-lotus-config.toml +++ b/documentation/en/default-lotus-config.toml @@ -311,7 +311,7 @@ # The garbage collection (GC) process removes data older than this retention period. # Setting this to 0 disables GC, preserving all historical data indefinitely. # - # If set, the minimum value must be greater than a day's worth (i.e. "2880" epochs for mainnet). + # If set, the minimum value must be greater than builtin.EpochsInDay (i.e. "2880" epochs for mainnet). # This ensures a reasonable retention period for the indexed data. # # Default: 0 (GC disabled)