From 2edf7fd25bb2f10b29b143390ac96f88bac27e82 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Sat, 24 Jul 2021 03:02:00 +0200 Subject: [PATCH 01/38] Rewire itest's StartDeal to take the full API struct This allows one to use the harness for much more versatile deal conditions --- itests/batch_deal_test.go | 6 ++++- itests/deals_offline_test.go | 29 ++++++------------------ itests/deals_power_test.go | 4 +++- itests/deals_publish_test.go | 5 ++++- itests/kit/deals.go | 43 +++++++++++++++++++----------------- 5 files changed, 42 insertions(+), 45 deletions(-) diff --git a/itests/batch_deal_test.go b/itests/batch_deal_test.go index 3881c917a..01622486a 100644 --- a/itests/batch_deal_test.go +++ b/itests/batch_deal_test.go @@ -90,7 +90,11 @@ func TestBatchDealInput(t *testing.T) { res, _, _, err := kit.CreateImportFile(ctx, client, rseed, piece) require.NoError(t, err) - deal := dh.StartDeal(ctx, res.Root, false, dealStartEpoch) + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.DealStartEpoch = dealStartEpoch + + deal := dh.StartDeal(ctx, dp) dh.WaitDealSealed(ctx, deal, false, true, checkNoPadding) } diff --git a/itests/deals_offline_test.go b/itests/deals_offline_test.go index ceae46fdf..8e40fbcb7 100644 --- a/itests/deals_offline_test.go +++ b/itests/deals_offline_test.go @@ -9,8 +9,6 @@ import ( "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/itests/kit" "github.com/stretchr/testify/require" ) @@ -31,7 +29,7 @@ func TestOfflineDealFlow(t *testing.T) { dh := kit.NewDealHarness(t, client, miner, miner) // Create a random file and import on the client. - res, inFile := client.CreateImportFile(ctx, 1, 0) + res, inFile := client.CreateImportFile(ctx, 1, 200) // Get the piece size and commP rootCid := res.Root @@ -39,31 +37,18 @@ func TestOfflineDealFlow(t *testing.T) { require.NoError(t, err) t.Log("FILE CID:", rootCid) - // Create a storage deal with the miner - maddr, err := miner.ActorAddress(ctx) - require.NoError(t, err) - - addr, err := client.WalletDefaultAddress(ctx) - require.NoError(t, err) - - // Manual storage deal (offline deal) - dataRef := &storagemarket.DataRef{ + dp := dh.DefaultStartDealParams() + dp.DealStartEpoch = startEpoch + dp.FastRetrieval = fastRet + // Replace with params for manual storage deal (offline deal) + dp.Data = &storagemarket.DataRef{ TransferType: storagemarket.TTManual, Root: rootCid, PieceCid: &pieceInfo.PieceCID, PieceSize: pieceInfo.PieceSize.Unpadded(), } - proposalCid, err := client.ClientStartDeal(ctx, &api.StartDealParams{ - Data: dataRef, - Wallet: addr, - Miner: maddr, - EpochPrice: types.NewInt(1000000), - DealStartEpoch: startEpoch, - MinBlocksDuration: uint64(build.MinDealDuration), - FastRetrieval: fastRet, - }) - require.NoError(t, err) + proposalCid := dh.StartDeal(ctx, dp) // Wait for the deal to reach StorageDealCheckForAcceptance on the client cd, err := client.ClientGetDealInfo(ctx, *proposalCid) diff --git a/itests/deals_power_test.go b/itests/deals_power_test.go index 16ad8ae6a..0c29ad060 100644 --- a/itests/deals_power_test.go +++ b/itests/deals_power_test.go @@ -50,7 +50,9 @@ func TestFirstDealEnablesMining(t *testing.T) { }() // now perform the deal. - deal := dh.StartDeal(ctx, ref.Root, false, 0) + dp := dh.DefaultStartDealParams() + dp.Data.Root = ref.Root + deal := dh.StartDeal(ctx, dp) // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this time.Sleep(time.Second) diff --git a/itests/deals_publish_test.go b/itests/deals_publish_test.go index 10592d8b4..6cefde6b9 100644 --- a/itests/deals_publish_test.go +++ b/itests/deals_publish_test.go @@ -69,7 +69,10 @@ func TestPublishDealsBatching(t *testing.T) { upds, err := client.ClientGetDealUpdates(ctx) require.NoError(t, err) - dh.StartDeal(ctx, res.Root, false, startEpoch) + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.DealStartEpoch = startEpoch + dh.StartDeal(ctx, dp) // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this time.Sleep(time.Second) diff --git a/itests/kit/deals.go b/itests/kit/deals.go index 311db4b25..0832447f2 100644 --- a/itests/kit/deals.go +++ b/itests/kit/deals.go @@ -88,7 +88,11 @@ func (dh *DealHarness) MakeOnlineDeal(ctx context.Context, params MakeFullDealPa dh.t.Logf("deal-making continuing; current height is %d", ts.Height()) } - deal = dh.StartDeal(ctx, res.Root, params.FastRet, params.StartEpoch) + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.DealStartEpoch = params.StartEpoch + dp.FastRetrieval = params.FastRet + deal = dh.StartDeal(ctx, dp) // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this time.Sleep(time.Second) @@ -97,29 +101,28 @@ func (dh *DealHarness) MakeOnlineDeal(ctx context.Context, params MakeFullDealPa return deal, res, path } -// StartDeal starts a storage deal between the client and the miner. -func (dh *DealHarness) StartDeal(ctx context.Context, fcid cid.Cid, fastRet bool, startEpoch abi.ChainEpoch) *cid.Cid { - maddr, err := dh.main.ActorAddress(ctx) - require.NoError(dh.t, err) - - addr, err := dh.client.WalletDefaultAddress(ctx) - require.NoError(dh.t, err) - - deal, err := dh.client.ClientStartDeal(ctx, &api.StartDealParams{ - Data: &storagemarket.DataRef{ - TransferType: storagemarket.TTGraphsync, - Root: fcid, - }, - Wallet: addr, - Miner: maddr, +func (dh *DealHarness) DefaultStartDealParams() api.StartDealParams { + dp := api.StartDealParams{ + Data: &storagemarket.DataRef{TransferType: storagemarket.TTGraphsync}, EpochPrice: types.NewInt(1000000), - DealStartEpoch: startEpoch, MinBlocksDuration: uint64(build.MinDealDuration), - FastRetrieval: fastRet, - }) + } + + var err error + dp.Miner, err = dh.main.ActorAddress(context.Background()) require.NoError(dh.t, err) - return deal + dp.Wallet, err = dh.client.WalletDefaultAddress(context.Background()) + require.NoError(dh.t, err) + + return dp +} + +// StartDeal starts a storage deal between the client and the miner. +func (dh *DealHarness) StartDeal(ctx context.Context, dealParams api.StartDealParams) *cid.Cid { + dealProposalCid, err := dh.client.ClientStartDeal(ctx, &dealParams) + require.NoError(dh.t, err) + return dealProposalCid } // WaitDealSealed waits until the deal is sealed. From 8693df46562069051b027f034c172b1e0d284574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Sat, 24 Jul 2021 12:53:56 +0100 Subject: [PATCH 02/38] fix racy TestSimultanenousTransferLimit. --- itests/deals_concurrent_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/itests/deals_concurrent_test.go b/itests/deals_concurrent_test.go index 241c9071d..303a4e9c6 100644 --- a/itests/deals_concurrent_test.go +++ b/itests/deals_concurrent_test.go @@ -190,7 +190,21 @@ func TestSimultanenousTransferLimit(t *testing.T) { cancel() wg.Wait() - require.LessOrEqual(t, maxOngoing, graphsyncThrottle) + // The eventing systems across go-data-transfer and go-graphsync + // are racy, and that's why we can't enforce graphsyncThrottle exactly, + // without making this test racy. + // + // Essentially what could happen is that the graphsync layer starts the + // next transfer before the go-data-transfer FSM has the opportunity to + // move the previously completed transfer to the next stage, thus giving + // the appearance that more than graphsyncThrottle transfers are + // in progress. + // + // Concurrency (20) is x10 higher than graphsyncThrottle (2), so if all + // 20 transfers are not happening at once, we know the throttle is + // in effect. Thus we are a little bit lenient here to account for the + // above races and allow up to graphsyncThrottle*2. + require.LessOrEqual(t, maxOngoing, graphsyncThrottle*2) } runTest(t) From 8d873e3edcef690b40386e933dcb9e68e2510231 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Sat, 24 Jul 2021 04:06:02 +0200 Subject: [PATCH 03/38] Tests for online and offline dealpadding Also bump the times on several flaky tests that can not complete in time on a typical laptop ( and fail half the time on CircleCI ) --- .circleci/config.yml | 5 +++ go.mod | 1 + go.sum | 7 ++- itests/deals_concurrent_test.go | 10 ++--- itests/deals_offline_test.go | 35 +++++++++------ itests/deals_padding_test.go | 76 +++++++++++++++++++++++++++++++++ itests/deals_test.go | 4 +- 7 files changed, 115 insertions(+), 23 deletions(-) create mode 100644 itests/deals_padding_test.go diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c77c2128..4d24e25b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -820,6 +820,11 @@ workflows: suite: itest-deals_offline target: "./itests/deals_offline_test.go" + - test: + name: test-itest-deals_padding + suite: itest-deals_padding + target: "./itests/deals_padding_test.go" + - test: name: test-itest-deals_power suite: itest-deals_power diff --git a/go.mod b/go.mod index 1725754b4..c702c3a5c 100644 --- a/go.mod +++ b/go.mod @@ -35,6 +35,7 @@ require ( github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v1.7.0 github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a + github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 github.com/filecoin-project/go-fil-markets v1.6.0-rc1 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 diff --git a/go.sum b/go.sum index ee34abe5c..534aa8a6e 100644 --- a/go.sum +++ b/go.sum @@ -282,6 +282,8 @@ github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnman github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= +github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= +github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= github.com/filecoin-project/go-fil-markets v1.6.0-rc1 h1:kQtND2NXz/cfGkjq+f5MCtz2oZAQabQvQ/zu4fppIps= github.com/filecoin-project/go-fil-markets v1.6.0-rc1/go.mod h1:S/C9PcSLFp75NpaF5aUqutnhXVJk6hM2dhWPYNq2jCQ= @@ -817,6 +819,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -1217,8 +1221,9 @@ github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+ github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= diff --git a/itests/deals_concurrent_test.go b/itests/deals_concurrent_test.go index 241c9071d..3c2fbc918 100644 --- a/itests/deals_concurrent_test.go +++ b/itests/deals_concurrent_test.go @@ -39,7 +39,7 @@ func TestDealWithMarketAndMinerNode(t *testing.T) { // For these tests where the block time is artificially short, just use // a deal start epoch that is guaranteed to be far enough in the future // so that the deal starts sealing in time - startEpoch := abi.ChainEpoch(2 << 12) + startEpoch := abi.ChainEpoch(8 << 10) runTest := func(t *testing.T, n int, fastRetrieval bool, carExport bool) { api.RunningNodeType = api.NodeMiner // TODO(anteva): fix me @@ -81,8 +81,6 @@ func TestDealCyclesConcurrent(t *testing.T) { kit.QuietMiningLogs() - blockTime := 10 * time.Millisecond - // For these tests where the block time is artificially short, just use // a deal start epoch that is guaranteed to be far enough in the future // so that the deal starts sealing in time @@ -90,7 +88,7 @@ func TestDealCyclesConcurrent(t *testing.T) { runTest := func(t *testing.T, n int, fastRetrieval bool, carExport bool) { client, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs()) - ens.InterconnectAll().BeginMining(blockTime) + ens.InterconnectAll().BeginMining(250 * time.Millisecond) dh := kit.NewDealHarness(t, client, miner, miner) dh.RunConcurrentDeals(kit.RunConcurrentDealsOpts{ @@ -126,8 +124,6 @@ func TestSimultanenousTransferLimit(t *testing.T) { policy.SetPreCommitChallengeDelay(oldDelay) }) - blockTime := 10 * time.Millisecond - // For these tests where the block time is artificially short, just use // a deal start epoch that is guaranteed to be far enough in the future // so that the deal starts sealing in time @@ -142,7 +138,7 @@ func TestSimultanenousTransferLimit(t *testing.T) { node.ApplyIf(node.IsType(repo.StorageMiner), node.Override(new(dtypes.StagingGraphsync), modules.StagingGraphsync(graphsyncThrottle))), node.Override(new(dtypes.Graphsync), modules.Graphsync(graphsyncThrottle)), )) - ens.InterconnectAll().BeginMining(blockTime) + ens.InterconnectAll().BeginMining(250 * time.Millisecond) dh := kit.NewDealHarness(t, client, miner, miner) ctx, cancel := context.WithCancel(context.Background()) diff --git a/itests/deals_offline_test.go b/itests/deals_offline_test.go index 8e40fbcb7..003f12b11 100644 --- a/itests/deals_offline_test.go +++ b/itests/deals_offline_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + commcid "github.com/filecoin-project/go-fil-commcid" + commp "github.com/filecoin-project/go-fil-commp-hashhash" "github.com/filecoin-project/go-fil-markets/storagemarket" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" @@ -14,17 +16,11 @@ import ( ) func TestOfflineDealFlow(t *testing.T) { - blocktime := 10 * time.Millisecond - // For these tests where the block time is artificially short, just use - // a deal start epoch that is guaranteed to be far enough in the future - // so that the deal starts sealing in time - startEpoch := abi.ChainEpoch(2 << 12) - - runTest := func(t *testing.T, fastRet bool) { + runTest := func(t *testing.T, fastRet bool, upscale abi.PaddedPieceSize) { ctx := context.Background() - client, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs()) - ens.InterconnectAll().BeginMining(blocktime) + client, miner, ens := kit.EnsembleMinimal(t, kit.WithAllSubsystems()) // no mock proofs + ens.InterconnectAll().BeginMining(250 * time.Millisecond) dh := kit.NewDealHarness(t, client, miner, miner) @@ -37,8 +33,22 @@ func TestOfflineDealFlow(t *testing.T) { require.NoError(t, err) t.Log("FILE CID:", rootCid) + // test whether padding works as intended + if upscale > 0 { + newRawCp, err := commp.PadCommP( + pieceInfo.PieceCID.Hash()[len(pieceInfo.PieceCID.Hash())-32:], + uint64(pieceInfo.PieceSize), + uint64(upscale), + ) + require.NoError(t, err) + + pieceInfo.PieceSize = upscale + pieceInfo.PieceCID, err = commcid.DataCommitmentV1ToCID(newRawCp) + require.NoError(t, err) + } + dp := dh.DefaultStartDealParams() - dp.DealStartEpoch = startEpoch + dp.DealStartEpoch = abi.ChainEpoch(4 << 10) dp.FastRetrieval = fastRet // Replace with params for manual storage deal (offline deal) dp.Data = &storagemarket.DataRef{ @@ -81,6 +91,7 @@ func TestOfflineDealFlow(t *testing.T) { } - t.Run("stdretrieval", func(t *testing.T) { runTest(t, false) }) - t.Run("fastretrieval", func(t *testing.T) { runTest(t, true) }) + t.Run("stdretrieval", func(t *testing.T) { runTest(t, false, 0) }) + t.Run("fastretrieval", func(t *testing.T) { runTest(t, true, 0) }) + t.Run("fastretrieval", func(t *testing.T) { runTest(t, true, 1024) }) } diff --git a/itests/deals_padding_test.go b/itests/deals_padding_test.go new file mode 100644 index 000000000..cd15d30d7 --- /dev/null +++ b/itests/deals_padding_test.go @@ -0,0 +1,76 @@ +package itests + +import ( + "context" + "testing" + "time" + + commcid "github.com/filecoin-project/go-fil-commcid" + commp "github.com/filecoin-project/go-fil-commp-hashhash" + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/policy" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/stretchr/testify/require" +) + +func TestDealPadding(t *testing.T) { + + kit.QuietMiningLogs() + + var blockTime = 250 * time.Millisecond + startEpoch := abi.ChainEpoch(2 << 12) + policy.SetPreCommitChallengeDelay(2) + + client, miner, ens := kit.EnsembleMinimal(t, kit.ThroughRPC(), kit.WithAllSubsystems()) // no mock proofs. + ens.InterconnectAll().BeginMining(blockTime) + dh := kit.NewDealHarness(t, client, miner, miner) + + ctx := context.Background() + client.WaitTillChain(ctx, kit.BlockMinedBy(miner.ActorAddr)) + + // Create a random file, would originally be a 256-byte sector + res, inFile := client.CreateImportFile(ctx, 1, 200) + + // Get the piece size and commP + pieceInfo, err := client.ClientDealPieceCID(ctx, res.Root) + require.NoError(t, err) + t.Log("FILE CID:", res.Root) + + runTest := func(t *testing.T, upscale abi.PaddedPieceSize) { + // test whether padding works as intended + newRawCp, err := commp.PadCommP( + pieceInfo.PieceCID.Hash()[len(pieceInfo.PieceCID.Hash())-32:], + uint64(pieceInfo.PieceSize), + uint64(upscale), + ) + require.NoError(t, err) + + pcid, err := commcid.DataCommitmentV1ToCID(newRawCp) + require.NoError(t, err) + + dp := dh.DefaultStartDealParams() + dp.Data.Root = res.Root + dp.Data.PieceCid = &pcid + dp.Data.PieceSize = upscale.Unpadded() + dp.DealStartEpoch = startEpoch + proposalCid := dh.StartDeal(ctx, dp) + + // TODO: this sleep is only necessary because deals don't immediately get logged in the dealstore, we should fix this + time.Sleep(time.Second) + + di, err := client.ClientGetDealInfo(ctx, *proposalCid) + require.NoError(t, err) + require.True(t, di.PieceCID.Equals(pcid)) + + dh.WaitDealSealed(ctx, proposalCid, false, false, nil) + + // Retrieve the deal + outFile := dh.PerformRetrieval(ctx, proposalCid, res.Root, false) + + kit.AssertFilesEqual(t, inFile, outFile) + } + + t.Run("padQuarterSector", func(t *testing.T) { runTest(t, 512) }) + t.Run("padHalfSector", func(t *testing.T) { runTest(t, 1024) }) + t.Run("padFullSector", func(t *testing.T) { runTest(t, 2048) }) +} diff --git a/itests/deals_test.go b/itests/deals_test.go index f2e106f1f..a461586a1 100644 --- a/itests/deals_test.go +++ b/itests/deals_test.go @@ -21,10 +21,8 @@ func TestDealsWithSealingAndRPC(t *testing.T) { policy.SetPreCommitChallengeDelay(oldDelay) }) - var blockTime = 50 * time.Millisecond - client, miner, ens := kit.EnsembleMinimal(t, kit.ThroughRPC(), kit.WithAllSubsystems()) // no mock proofs. - ens.InterconnectAll().BeginMining(blockTime) + ens.InterconnectAll().BeginMining(250 * time.Millisecond) dh := kit.NewDealHarness(t, client, miner, miner) t.Run("stdretrieval", func(t *testing.T) { From 78f94c4c6bbda171ffa2bec6a49e91bc70c1cdb8 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Wed, 7 Apr 2021 15:14:14 -0700 Subject: [PATCH 04/38] This pulls in forgotten parts properly implementing PR#5988 ( previous testing focused exclusively on offline dealflow .cars ) Allows a workflow of: ~$ dd if=/dev/urandom bs=1M count=1 | ~/go-ipfs/cmd/ipfs/ipfs add --pin=false added QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 ~$ ~/go-ipfs/cmd/ipfs/ipfs dag export QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 > test_mib.car ~$ lotus client import --car ~/test_mib.car Import 2, Root QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 ~$ ~/go/bin/stream-commp -p $(( 256 * 1024 * 1024 )) < test_mib.car CommP: 54e4e75ddc3fffa8fd33d3ededc06e564603ac0fe62543ec6463d51b553be40b CommPCid: baga6ea4seaqfjzhhlxod775i7uz5h3pnybxfmrqdvqh6mjkd5rsghvi3ku56icy Raw bytes: 1049073 bytes Unpadded piece: 266338304 bytes Padded piece: 268435456 bytes CARv1 detected in stream: Blocks: 5 Roots: 1 1: QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 ~$ curl http://127.0.0.1:1234/rpc/v0 -X POST -H "Authorization: Bearer $(cat ~/.lotus/token)" -H "Content-Type: application/json" --data ' { "jsonrpc": "2.0", "id":1, "method": "Filecoin.ClientStartDeal", "params": [ { "Wallet":"t01004", "Miner":"t01005", "EpochPrice":"0", "MinBlocksDuration":518400, "Data": { "Root":{ "/":"QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2" }, "PieceCid":{ "/":"baga6ea4seaqfjzhhlxod775i7uz5h3pnybxfmrqdvqh6mjkd5rsghvi3ku56icy" }, "PieceSize": 266338304 } } ] } ' ~$ ~/go/bin/stream-commp -p $(( 128 * 1024 * 1024 )) < test_mib.car CommP: ed904105399ed346f6b03844abc14710a1748854c2781824d6bd1100e63b1807 CommPCid: baga6ea4seaqo3ecbau4z5u2g62ydqrflyfdrbilurbkme6ayetll2eia4y5rqby Raw bytes: 1049073 bytes Unpadded piece: 133169152 bytes Padded piece: 134217728 bytes CARv1 detected in stream: Blocks: 5 Roots: 1 1: QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2 ~$ curl http://127.0.0.1:1234/rpc/v0 -X POST -H "Authorization: Bearer $(cat ~/.lotus/token)" -H "Content-Type: application/json" --data ' { "jsonrpc": "2.0", "id":1, "method": "Filecoin.ClientStatelessDeal", "params": [ { "Wallet":"t01004", "Miner":"t01005", "EpochPrice":"0", "ProviderCollateral":"0", "MinBlocksDuration":518400, "Data": { "TransferType": "manual", "Root":{ "/":"QmcFLqjyh2kvixuuvxgNUoHy55Rb6N6uuSq4CNfvtPoTJ2" }, "PieceCid":{ "/":"baga6ea4seaqo3ecbau4z5u2g62ydqrflyfdrbilurbkme6ayetll2eia4y5rqby" }, "PieceSize": 133169152 } } ] } ' {"jsonrpc":"2.0","result":{"/":"bafyreianhjvev3w6q5lteap3h7tkxbe2jaobwlsi7vzbcoobjpicg3foqi"},"id":1} ~$ lotus-miner storage-deals import-data bafyreianhjvev3w6q5lteap3h7tkxbe2jaobwlsi7vzbcoobjpicg3foqi ~/test_mib.car --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index c702c3a5c..0ec123055 100644 --- a/go.mod +++ b/go.mod @@ -34,12 +34,12 @@ require ( github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 github.com/filecoin-project/go-data-transfer v1.7.0 - github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a + github.com/filecoin-project/go-fil-commcid v0.1.0 github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 - github.com/filecoin-project/go-fil-markets v1.6.0-rc1 + github.com/filecoin-project/go-fil-markets v1.6.0-rc1.0.20210723225932-46b52248a0f2 github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec github.com/filecoin-project/go-multistore v0.0.3 - github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 + github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 github.com/filecoin-project/go-state-types v0.1.1-0.20210722133031-ad9bfe54c124 github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe diff --git a/go.sum b/go.sum index 534aa8a6e..b6189685b 100644 --- a/go.sum +++ b/go.sum @@ -269,7 +269,6 @@ github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW github.com/filecoin-project/go-bitfield v0.2.4/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2 h1:av5fw6wmm58FYMgJeoB/lK9XXrgdugYiTqkdxjTy9k8= github.com/filecoin-project/go-cbor-util v0.0.0-20191219014500-08c40a1e63a2/go.mod h1:pqTiPHobNkOVM5thSRsHYjyQfq7O5QSCMhvuu9JoDlg= -github.com/filecoin-project/go-commp-utils v0.0.0-20201119054358-b88f7a96a434/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7 h1:U9Z+76pHCKBmtdxFV7JFZJj7OVm12I6dEKwtMVbq5p0= github.com/filecoin-project/go-commp-utils v0.1.1-0.20210427191551-70bf140d31c7/go.mod h1:6s95K91mCyHY51RPWECZieD3SGWTqIFLf1mPOes9l5U= github.com/filecoin-project/go-crypto v0.0.0-20191218222705-effae4ea9f03 h1:2pMXdBnCiXjfCYx/hLqFxccPoqsSveQFxVLvNxy9bus= @@ -280,13 +279,14 @@ github.com/filecoin-project/go-data-transfer v1.7.0/go.mod h1:GLRr5BmLEqsLwXfiRD github.com/filecoin-project/go-ds-versioning v0.1.0 h1:y/X6UksYTsK8TLCI7rttCKEvl8btmWxyFMEeeWGUxIQ= github.com/filecoin-project/go-ds-versioning v0.1.0/go.mod h1:mp16rb4i2QPmxBnmanUx8i/XANp+PFCCJWiAb+VW4/s= github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= -github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a h1:hyJ+pUm/4U4RdEZBlg6k8Ma4rDiuvqyGpoICXAxwsTg= github.com/filecoin-project/go-fil-commcid v0.0.0-20201016201715-d41df56b4f6a/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= +github.com/filecoin-project/go-fil-commcid v0.1.0 h1:3R4ds1A9r6cr8mvZBfMYxTS88OqLYEo6roi+GiIeOh8= +github.com/filecoin-project/go-fil-commcid v0.1.0/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0 h1:imrrpZWEHRnNqqv0tN7LXep5bFEVOVmQWHJvl2mgsGo= github.com/filecoin-project/go-fil-commp-hashhash v0.1.0/go.mod h1:73S8WSEWh9vr0fDJVnKADhfIv/d6dCbAGaAGWbdJEI8= github.com/filecoin-project/go-fil-markets v1.0.5-0.20201113164554-c5eba40d5335/go.mod h1:AJySOJC00JRWEZzRG2KsfUnqEf5ITXxeX09BE9N4f9c= -github.com/filecoin-project/go-fil-markets v1.6.0-rc1 h1:kQtND2NXz/cfGkjq+f5MCtz2oZAQabQvQ/zu4fppIps= -github.com/filecoin-project/go-fil-markets v1.6.0-rc1/go.mod h1:S/C9PcSLFp75NpaF5aUqutnhXVJk6hM2dhWPYNq2jCQ= +github.com/filecoin-project/go-fil-markets v1.6.0-rc1.0.20210723225932-46b52248a0f2 h1:L5KvfMqZMxST/T4Zu8khwX0K1farbB0w2957ckkbO8A= +github.com/filecoin-project/go-fil-markets v1.6.0-rc1.0.20210723225932-46b52248a0f2/go.mod h1:ZuFDagROUV6GfvBU//KReTQDw+EZci4rH7jMYTD10vs= github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0 h1:b3UDemBYN2HNfk3KOXNuxgTTxlWi3xVvbQP0IT38fvM= @@ -298,8 +298,9 @@ github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec h1:r github.com/filecoin-project/go-jsonrpc v0.1.4-0.20210217175800-45ea43ac2bec/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= github.com/filecoin-project/go-multistore v0.0.3/go.mod h1:kaNqCC4IhU4B1uyr7YWFHd23TL4KM32aChS0jNkyUvQ= -github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 h1:+/4aUeUoKr6AKfPE3mBhXA5spIV6UcKdTYDPNU2Tdmg= github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak= +github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1 h1:0BogtftbcgyBx4lP2JWM00ZK7/pXmgnrDqKp9aLTgVs= +github.com/filecoin-project/go-padreader v0.0.0-20210723183308-812a16dc01b1/go.mod h1:VYVPJqwpsfmtoHnAmPx6MUwmrK6HIcDqZJiuZhtmfLQ= github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498 h1:G10ezOvpH1CLXQ19EA9VWNwyL0mg536ujSayjV0yg0k= github.com/filecoin-project/go-paramfetch v0.0.2-0.20210614165157-25a6c7769498/go.mod h1:1FH85P8U+DUEmWk1Jkw3Bw7FrwTVUNHk/95PSPG+dts= github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= @@ -708,7 +709,6 @@ github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHn github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= -github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.3.0 h1:31Re/cPqFHpsRHgyVwjWADPoF0otB1WrjTy8ZFYwEZU= github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= github.com/ipfs/go-merkledag v0.0.3/go.mod h1:Oc5kIXLHokkE1hWGMBHw+oxehkAaTOqtEb7Zbh6BhLA= From 0c68bccbdae532275f217dd08317bdff5eb9d602 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 21 Jul 2021 13:13:47 +0300 Subject: [PATCH 05/38] add splitstore rollback lotus-shed command --- cmd/lotus-shed/main.go | 1 + cmd/lotus-shed/splitstore.go | 211 +++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 cmd/lotus-shed/splitstore.go diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index e06b63080..e16007e77 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -60,6 +60,7 @@ func main() { actorCmd, minerTypesCmd, minerMultisigsCmd, + splitstoreCmd, } app := &cli.App{ diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go new file mode 100644 index 000000000..57952fc66 --- /dev/null +++ b/cmd/lotus-shed/splitstore.go @@ -0,0 +1,211 @@ +package main + +import ( + "bufio" + "context" + "fmt" + "io" + "os" + "path/filepath" + + "github.com/dgraph-io/badger/v2" + "github.com/urfave/cli/v2" + "golang.org/x/sync/errgroup" + "golang.org/x/xerrors" + + "github.com/ipfs/go-datastore" + "github.com/ipfs/go-datastore/query" + logging "github.com/ipfs/go-log/v2" + + "github.com/filecoin-project/lotus/node/config" + "github.com/filecoin-project/lotus/node/repo" +) + +var splitstoreCmd = &cli.Command{ + Name: "splitstore", + Description: "splitstore utiities", + Subcommands: []*cli.Command{ + splitstoreRollbackCmd, + }, +} + +var splitstoreRollbackCmd = &cli.Command{ + Name: "rollback", + Description: "rollbacks a splitstore installation", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + logging.SetLogLevel("badger", "ERROR") // nolint:errcheck + + r, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return xerrors.Errorf("error opening fs repo: %w", err) + } + + exists, err := r.Exists() + if err != nil { + return err + } + if !exists { + return xerrors.Errorf("lotus repo doesn't exist") + } + + lr, err := r.Lock(repo.FullNode) + if err != nil { + return xerrors.Errorf("error locking repo: %w", err) + } + defer lr.Close() //nolint:errcheck + + cfg, err := lr.Config() + if err != nil { + return xerrors.Errorf("error getting config: %w", err) + } + + fncfg, ok := cfg.(*config.FullNode) + if !ok { + return xerrors.Errorf("wrong config type: %T", cfg) + } + + if !fncfg.Chainstore.EnableSplitstore { + return xerrors.Errorf("splitstore is not enabled") + } + + fmt.Println("copying hotstore to coldstore...") + err = copyHotstoreToColdstore(lr) + if err != nil { + return xerrors.Errorf("error copying hotstore to coldstore: %w", err) + } + + fmt.Println("deleting splistore directory...") + err = deleteSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error deleting splitstore directory: %w", err) + } + + fmt.Println("deleting splitstore keys from metadata datastore...") + err = deleteSplitstoreKeys(lr) + if err != nil { + return xerrors.Errorf("error deleting splitstore keys: %w", err) + } + + fmt.Println("disalbing splitsotre in config...") + err = lr.SetConfig(func(cfg interface{}) { + cfg.(*config.FullNode).Chainstore.EnableSplitstore = false + }) + if err != nil { + return xerrors.Errorf("error disabling splitstore in config: %w", err) + } + + fmt.Println("splitstore has been rolled back.") + return nil + }, +} + +func copyHotstoreToColdstore(lr repo.LockedRepo) error { + repoPath := lr.Path() + dataPath := filepath.Join(repoPath, "datastore") + coldPath := filepath.Join(dataPath, "chain") + hotPath := filepath.Join(dataPath, "splitstore", "hot.badger") + + coldOpts, err := repo.BadgerBlockstoreOptions(repo.UniversalBlockstore, coldPath, false) + if err != nil { + return xerrors.Errorf("error getting coldstore badger options: %w", err) + } + coldOpts.SyncWrites = false + + hotOpts, err := repo.BadgerBlockstoreOptions(repo.HotBlockstore, hotPath, true) + if err != nil { + return xerrors.Errorf("error getting hotstore badger options: %w", err) + } + + cold, err := badger.Open(coldOpts.Options) + if err != nil { + return xerrors.Errorf("error opening coldstore: %w", err) + } + defer cold.Close() //nolint + + hot, err := badger.Open(hotOpts.Options) + if err != nil { + return xerrors.Errorf("error opening hotstore: %w", err) + } + defer hot.Close() //nolint + + rd, wr := io.Pipe() + g := new(errgroup.Group) + + g.Go(func() error { + bwr := bufio.NewWriterSize(wr, 64<<20) + + _, err := hot.Backup(bwr, 0) + if err != nil { + wr.CloseWithError(err) + return err + } + + err = bwr.Flush() + if err != nil { + wr.CloseWithError(err) + return err + } + + return wr.Close() + }) + + g.Go(func() error { + err := cold.Load(rd, 1024) + if err != nil { + return err + } + + return cold.Sync() + }) + + return g.Wait() +} + +func deleteSplitstoreDir(lr repo.LockedRepo) error { + path, err := lr.SplitstorePath() + if err != nil { + return xerrors.Errorf("error getting splitstore path: %w", err) + } + + return os.RemoveAll(path) +} + +func deleteSplitstoreKeys(lr repo.LockedRepo) error { + ds, err := lr.Datastore(context.TODO(), "/metadata") + if err != nil { + return xerrors.Errorf("error opening datastore: %w", err) + } + if closer, ok := ds.(io.Closer); ok { + defer closer.Close() //nolint + } + + var keys []datastore.Key + res, err := ds.Query(query.Query{Prefix: "/splitstore"}) + if err != nil { + return xerrors.Errorf("error querying datastore for splitstore keys: %w", err) + } + + for r := range res.Next() { + if r.Error != nil { + return xerrors.Errorf("datastore query error: %w", r.Error) + } + + keys = append(keys, datastore.NewKey(r.Key)) + } + + for _, k := range keys { + fmt.Printf("deleting %s from datastore...", k) + err = ds.Delete(k) + if err != nil { + return xerrors.Errorf("error deleting key %s from datastore: %w", k, err) + } + } + + return nil +} From 92b9d8c895fe6d2ecad1351a6ed9d22c7a382596 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 21 Jul 2021 13:24:53 +0300 Subject: [PATCH 06/38] quiet linter --- cmd/lotus-shed/splitstore.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 57952fc66..380a5adca 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -142,13 +142,13 @@ func copyHotstoreToColdstore(lr repo.LockedRepo) error { _, err := hot.Backup(bwr, 0) if err != nil { - wr.CloseWithError(err) + _ = wr.CloseWithError(err) return err } err = bwr.Flush() if err != nil { - wr.CloseWithError(err) + _ = wr.CloseWithError(err) return err } From 36b209ca5c2e36a7a6975adb8bee3b15edd2a8d7 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 21 Jul 2021 14:08:57 +0300 Subject: [PATCH 07/38] compact and gc coldstore after copying --- cmd/lotus-shed/splitstore.go | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 380a5adca..ecc16617e 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -7,6 +7,7 @@ import ( "io" "os" "path/filepath" + "runtime" "github.com/dgraph-io/badger/v2" "github.com/urfave/cli/v2" @@ -164,7 +165,33 @@ func copyHotstoreToColdstore(lr repo.LockedRepo) error { return cold.Sync() }) - return g.Wait() + err = g.Wait() + if err != nil { + return err + } + + // compact + gc the coldstore + fmt.Println("compacting coldstore...") + nworkers := runtime.NumCPU() + if nworkers < 2 { + nworkers = 2 + } + + err = cold.Flatten(nworkers) + if err != nil { + return xerrors.Errorf("error compacting coldstore: %w", err) + } + + fmt.Println("garbage collecting coldstore...") + for err == nil { + err = cold.RunValueLogGC(0.0625) + } + + if err != badger.ErrNoRewrite { + return xerrors.Errorf("error garbage collecting coldstore: %w", err) + } + + return nil } func deleteSplitstoreDir(lr repo.LockedRepo) error { From e696a2c0cc8aa2344430406a1d13cba768db859b Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 21 Jul 2021 14:10:07 +0300 Subject: [PATCH 08/38] fix newline in progres message --- cmd/lotus-shed/splitstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index ecc16617e..a06ede09f 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -227,7 +227,7 @@ func deleteSplitstoreKeys(lr repo.LockedRepo) error { } for _, k := range keys { - fmt.Printf("deleting %s from datastore...", k) + fmt.Printf("deleting %s from datastore...\n", k) err = ds.Delete(k) if err != nil { return xerrors.Errorf("error deleting key %s from datastore: %w", k, err) From da66e7a878a750f4cce3a18b2a98fc5e5418a2d0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Wed, 21 Jul 2021 14:36:02 +0300 Subject: [PATCH 09/38] fix typo --- cmd/lotus-shed/splitstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index a06ede09f..b62c9d9b3 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -93,7 +93,7 @@ var splitstoreRollbackCmd = &cli.Command{ return xerrors.Errorf("error deleting splitstore keys: %w", err) } - fmt.Println("disalbing splitsotre in config...") + fmt.Println("disabling splitstore in config...") err = lr.SetConfig(func(cfg interface{}) { cfg.(*config.FullNode).Chainstore.EnableSplitstore = false }) From 33cdc90f13da081fa51daf61ce03d0d9b00b9f25 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 22 Jul 2021 20:53:03 +0300 Subject: [PATCH 10/38] fix typo Co-authored-by: raulk --- cmd/lotus-shed/splitstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index b62c9d9b3..39e5d1420 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -24,7 +24,7 @@ import ( var splitstoreCmd = &cli.Command{ Name: "splitstore", - Description: "splitstore utiities", + Description: "splitstore utilities", Subcommands: []*cli.Command{ splitstoreRollbackCmd, }, From 254c489164c6fcf86128595d2c570d6714a9e8be Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 22 Jul 2021 20:54:10 +0300 Subject: [PATCH 11/38] fix typo Co-authored-by: raulk --- cmd/lotus-shed/splitstore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 39e5d1420..31538a9eb 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -81,7 +81,7 @@ var splitstoreRollbackCmd = &cli.Command{ return xerrors.Errorf("error copying hotstore to coldstore: %w", err) } - fmt.Println("deleting splistore directory...") + fmt.Println("deleting splitstore directory...") err = deleteSplitstoreDir(lr) if err != nil { return xerrors.Errorf("error deleting splitstore directory: %w", err) From ce6f410f2a955d98a0444ba67d7bb2c57fb56944 Mon Sep 17 00:00:00 2001 From: vyzo Date: Thu, 22 Jul 2021 21:07:57 +0300 Subject: [PATCH 12/38] add options to control compaction/gc of the coldstore and config rewrite during rollback --- cmd/lotus-shed/splitstore.go | 60 +++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 31538a9eb..1716668c0 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -38,6 +38,14 @@ var splitstoreRollbackCmd = &cli.Command{ Name: "repo", Value: "~/.lotus", }, + &cli.BoolFlag{ + Name: "gc-coldstore", + Usage: "compact and garbage collect the coldstore after copying the hotstore", + }, + &cli.BoolFlag{ + Name: "rewrite-config", + Usage: "rewrite the lotus configuration to disable splitstore", + }, }, Action: func(cctx *cli.Context) error { logging.SetLogLevel("badger", "ERROR") // nolint:errcheck @@ -76,7 +84,7 @@ var splitstoreRollbackCmd = &cli.Command{ } fmt.Println("copying hotstore to coldstore...") - err = copyHotstoreToColdstore(lr) + err = copyHotstoreToColdstore(lr, cctx.Bool("gc-coldstore")) if err != nil { return xerrors.Errorf("error copying hotstore to coldstore: %w", err) } @@ -93,12 +101,14 @@ var splitstoreRollbackCmd = &cli.Command{ return xerrors.Errorf("error deleting splitstore keys: %w", err) } - fmt.Println("disabling splitstore in config...") - err = lr.SetConfig(func(cfg interface{}) { - cfg.(*config.FullNode).Chainstore.EnableSplitstore = false - }) - if err != nil { - return xerrors.Errorf("error disabling splitstore in config: %w", err) + if cctx.Bool("rewrite-config") { + fmt.Println("disabling splitstore in config...") + err = lr.SetConfig(func(cfg interface{}) { + cfg.(*config.FullNode).Chainstore.EnableSplitstore = false + }) + if err != nil { + return xerrors.Errorf("error disabling splitstore in config: %w", err) + } } fmt.Println("splitstore has been rolled back.") @@ -106,7 +116,7 @@ var splitstoreRollbackCmd = &cli.Command{ }, } -func copyHotstoreToColdstore(lr repo.LockedRepo) error { +func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error { repoPath := lr.Path() dataPath := filepath.Join(repoPath, "datastore") coldPath := filepath.Join(dataPath, "chain") @@ -170,25 +180,27 @@ func copyHotstoreToColdstore(lr repo.LockedRepo) error { return err } - // compact + gc the coldstore - fmt.Println("compacting coldstore...") - nworkers := runtime.NumCPU() - if nworkers < 2 { - nworkers = 2 - } + // compact + gc the coldstore if so requested + if gcColdstore { + fmt.Println("compacting coldstore...") + nworkers := runtime.NumCPU() + if nworkers < 2 { + nworkers = 2 + } - err = cold.Flatten(nworkers) - if err != nil { - return xerrors.Errorf("error compacting coldstore: %w", err) - } + err = cold.Flatten(nworkers) + if err != nil { + return xerrors.Errorf("error compacting coldstore: %w", err) + } - fmt.Println("garbage collecting coldstore...") - for err == nil { - err = cold.RunValueLogGC(0.0625) - } + fmt.Println("garbage collecting coldstore...") + for err == nil { + err = cold.RunValueLogGC(0.0625) + } - if err != badger.ErrNoRewrite { - return xerrors.Errorf("error garbage collecting coldstore: %w", err) + if err != badger.ErrNoRewrite { + return xerrors.Errorf("error garbage collecting coldstore: %w", err) + } } return nil From e317c831a82f54f942f428b2369618b0731c48b8 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 09:07:27 +0300 Subject: [PATCH 13/38] quiet excessive badger logs --- cmd/lotus-shed/splitstore.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 1716668c0..383419990 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -14,9 +14,10 @@ import ( "golang.org/x/sync/errgroup" "golang.org/x/xerrors" + "go.uber.org/zap" + "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" - logging "github.com/ipfs/go-log/v2" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/repo" @@ -48,8 +49,6 @@ var splitstoreRollbackCmd = &cli.Command{ }, }, Action: func(cctx *cli.Context) error { - logging.SetLogLevel("badger", "ERROR") // nolint:errcheck - r, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("error opening fs repo: %w", err) @@ -122,16 +121,23 @@ func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error { coldPath := filepath.Join(dataPath, "chain") hotPath := filepath.Join(dataPath, "splitstore", "hot.badger") + blog := &badgerLogger{ + SugaredLogger: log.Desugar().WithOptions(zap.AddCallerSkip(1)).Sugar(), + skip2: log.Desugar().WithOptions(zap.AddCallerSkip(2)).Sugar(), + } + coldOpts, err := repo.BadgerBlockstoreOptions(repo.UniversalBlockstore, coldPath, false) if err != nil { return xerrors.Errorf("error getting coldstore badger options: %w", err) } coldOpts.SyncWrites = false + coldOpts.Logger = blog hotOpts, err := repo.BadgerBlockstoreOptions(repo.HotBlockstore, hotPath, true) if err != nil { return xerrors.Errorf("error getting hotstore badger options: %w", err) } + hotOpts.Logger = blog cold, err := badger.Open(coldOpts.Options) if err != nil { @@ -248,3 +254,13 @@ func deleteSplitstoreKeys(lr repo.LockedRepo) error { return nil } + +// badger logging through go-log +type badgerLogger struct { + *zap.SugaredLogger + skip2 *zap.SugaredLogger +} + +func (b *badgerLogger) Warningf(format string, args ...interface{}) {} +func (b *badgerLogger) Infof(format string, args ...interface{}) {} +func (b *badgerLogger) Debugf(format string, args ...interface{}) {} From 1918ffda4e58e3a34dd5b161c9d2a6c21c809d79 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 10:35:37 +0300 Subject: [PATCH 14/38] implement splitstore check --- blockstore/splitstore/splitstore.go | 4 +- blockstore/splitstore/splitstore_check.go | 130 ++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 blockstore/splitstore/splitstore_check.go diff --git a/blockstore/splitstore/splitstore.go b/blockstore/splitstore/splitstore.go index b401d657e..7a2abf9a8 100644 --- a/blockstore/splitstore/splitstore.go +++ b/blockstore/splitstore/splitstore.go @@ -102,7 +102,8 @@ type SplitStore struct { compacting int32 // compaction/prune/warmup in progress closing int32 // the splitstore is closing - cfg *Config + cfg *Config + path string mx sync.Mutex warmupEpoch abi.ChainEpoch // protected by mx @@ -169,6 +170,7 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co // and now we can make a SplitStore ss := &SplitStore{ cfg: cfg, + path: path, ds: ds, cold: cold, hot: hots, diff --git a/blockstore/splitstore/splitstore_check.go b/blockstore/splitstore/splitstore_check.go new file mode 100644 index 000000000..ba9386aaf --- /dev/null +++ b/blockstore/splitstore/splitstore_check.go @@ -0,0 +1,130 @@ +package splitstore + +import ( + "fmt" + "os" + "path/filepath" + "sync/atomic" + "time" + + "golang.org/x/xerrors" + + "github.com/filecoin-project/lotus/chain/types" + cid "github.com/ipfs/go-cid" +) + +// performs an asynchronous health-check on the splitstore; results are appended to +// /check.txt +func (s *SplitStore) Check() error { + s.headChangeMx.Lock() + defer s.headChangeMx.Unlock() + + // try to take compaction lock and inhibit compaction while the health-check is running + if !atomic.CompareAndSwapInt32(&s.compacting, 0, 1) { + return xerrors.Errorf("can't acquire compaction lock; compacting operation in progress") + } + + if s.compactionIndex == 0 { + atomic.StoreInt32(&s.compacting, 0) + return xerrors.Errorf("splitstore hasn't compacted yet; health check is not meaningful") + } + + // check if we are actually closing first + if err := s.checkClosing(); err != nil { + atomic.StoreInt32(&s.compacting, 0) + return err + } + + curTs := s.chain.GetHeaviestTipSet() + go func() { + defer atomic.StoreInt32(&s.compacting, 0) + + log.Info("checking splitstore health") + start := time.Now() + + err := s.doCheck(curTs) + if err != nil { + log.Errorf("error checking splitstore health: %s", err) + return + } + + log.Infow("health check done", "took", time.Since(start)) + }() + + return nil +} + +func (s *SplitStore) doCheck(curTs *types.TipSet) error { + currentEpoch := curTs.Height() + boundaryEpoch := currentEpoch - CompactionBoundary + + outputPath := filepath.Join(s.path, "check.txt") + output, err := os.OpenFile(outputPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + return xerrors.Errorf("error opening check output file %s: %w", outputPath, err) + } + defer output.Close() //nolint:errcheck + + write := func(format string, args ...interface{}) { + _, err := fmt.Fprintf(output, format, args...) + if err != nil { + log.Warnf("error writing check output: %s", err) + } + } + + ts, _ := time.Now().MarshalText() + write("---------------------------------------------\n") + write("start check at %s\n", ts) + write("current epoch: %d\n", currentEpoch) + write("boundary epoch: %d\n", boundaryEpoch) + write("compaction index: %d\n", s.compactionIndex) + write("--\n") + + var coldCnt, missingCnt int64 + err = s.walkChain(curTs, boundaryEpoch, boundaryEpoch, + func(c cid.Cid) error { + if isUnitaryObject(c) { + return errStopWalk + } + + has, err := s.hot.Has(c) + if err != nil { + return xerrors.Errorf("error checking hotstore: %w", err) + } + + if has { + return nil + } + + has, err = s.cold.Has(c) + if err != nil { + return xerrors.Errorf("error checking coldstore: %w", err) + } + + if has { + coldCnt++ + write("cold object reference: %s", c) + } else { + missingCnt++ + write("missing object reference: %s", c) + } + + return nil + }) + + if err != nil { + err = xerrors.Errorf("error walking chain: %w", err) + write("ERROR: %s\n", err) + return err + } + + if coldCnt == 0 && missingCnt == 0 { + log.Info("check OK") + write("OK\n") + } else { + log.Infow("check failed", "cold", coldCnt, "missing", missingCnt) + write("FAILED\n") + } + + return nil +} From 3d2ae433ee305644bd6b4f4e13a8492cbe49a804 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:14:48 +0300 Subject: [PATCH 15/38] add ChainCheckBlockstore API --- api/api_full.go | 4 ++++ node/impl/full/chain.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/api/api_full.go b/api/api_full.go index 5c72c3613..a4a5dd253 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -164,6 +164,10 @@ type FullNode interface { // If oldmsgskip is set, messages from before the requested roots are also not included. ChainExport(ctx context.Context, nroots abi.ChainEpoch, oldmsgskip bool, tsk types.TipSetKey) (<-chan []byte, error) //perm:read + // ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore + // if supported by the underlying implementation. + ChainCheckBlockstore(context.Context) error + // MethodGroup: Beacon // The Beacon method group contains methods for interacting with the random beacon (DRAND) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 33d14d3ba..579a82227 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -83,6 +83,9 @@ type ChainAPI struct { // expose externally. In the future, this will be segregated into two // blockstores. ExposedBlockstore dtypes.ExposedBlockstore + + // BaseBlockstore is the underyling blockstore + BaseBlockstore dtypes.BaseBlockstore } func (m *ChainModule) ChainNotify(ctx context.Context) (<-chan []*api.HeadChange, error) { @@ -644,3 +647,12 @@ func (a *ChainAPI) ChainExport(ctx context.Context, nroots abi.ChainEpoch, skipo return out, nil } + +func (a *ChainAPI) ChainCheckBlockstore(ctx context.Context) error { + checker, ok := a.BaseBlockstore.(interface{ Check() error }) + if !ok { + return xerrors.Errorf("underlying blockstore does not support health checks") + } + + return checker.Check() +} From c99dc3e8114ff1ece1761c894f545967fd65d721 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:18:46 +0300 Subject: [PATCH 16/38] add splitstore check command --- cmd/lotus-shed/splitstore.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 383419990..ff949fda9 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -19,6 +19,7 @@ import ( "github.com/ipfs/go-datastore" "github.com/ipfs/go-datastore/query" + lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/repo" ) @@ -28,6 +29,7 @@ var splitstoreCmd = &cli.Command{ Description: "splitstore utilities", Subcommands: []*cli.Command{ splitstoreRollbackCmd, + splitstoreCheckCmd, }, } @@ -264,3 +266,18 @@ type badgerLogger struct { func (b *badgerLogger) Warningf(format string, args ...interface{}) {} func (b *badgerLogger) Infof(format string, args ...interface{}) {} func (b *badgerLogger) Debugf(format string, args ...interface{}) {} + +var splitstoreCheckCmd = &cli.Command{ + Name: "check", + Description: "runs a healthcheck on a splitstore installation", + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + return api.ChainCheckBlockstore(ctx) + }, +} From 5b2e4d8ad4aaea3268d7bba043977824f06f52a0 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:23:49 +0300 Subject: [PATCH 17/38] add permission tag to ChainCheckBlockstore API --- api/api_full.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api_full.go b/api/api_full.go index a4a5dd253..472b34596 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -166,7 +166,7 @@ type FullNode interface { // ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore // if supported by the underlying implementation. - ChainCheckBlockstore(context.Context) error + ChainCheckBlockstore(context.Context) error //perm:read // MethodGroup: Beacon // The Beacon method group contains methods for interacting with the random beacon (DRAND) From 21bb2bda099d214fe3bdcd88c2f986cacb73a3b8 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:25:29 +0300 Subject: [PATCH 18/38] make gen --- api/mocks/mock_full.go | 14 ++++++++++++++ api/proxy_gen.go | 10 ++++++++++ build/openrpc/full.json.gz | Bin 23507 -> 23617 bytes build/openrpc/miner.json.gz | Bin 8672 -> 8672 bytes build/openrpc/worker.json.gz | Bin 2513 -> 2513 bytes documentation/en/api-v1-unstable-methods.md | 12 ++++++++++++ 6 files changed, 36 insertions(+) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 69f315be9..a6c091611 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -105,6 +105,20 @@ func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) } +// ChainCheckBlockstore mocks base method. +func (m *MockFullNode) ChainCheckBlockstore(arg0 context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainCheckBlockstore", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// ChainCheckBlockstore indicates an expected call of ChainCheckBlockstore. +func (mr *MockFullNodeMockRecorder) ChainCheckBlockstore(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainCheckBlockstore", reflect.TypeOf((*MockFullNode)(nil).ChainCheckBlockstore), arg0) +} + // ChainDeleteObj mocks base method. func (m *MockFullNode) ChainDeleteObj(arg0 context.Context, arg1 cid.Cid) error { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index fb645eb48..8191e881f 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -98,6 +98,8 @@ type FullNodeStruct struct { Internal struct { BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + ChainCheckBlockstore func(p0 context.Context) error `perm:"read"` + ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"` @@ -951,6 +953,14 @@ func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*t return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ChainCheckBlockstore(p0 context.Context) error { + return s.Internal.ChainCheckBlockstore(p0) +} + +func (s *FullNodeStub) ChainCheckBlockstore(p0 context.Context) error { + return xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { return s.Internal.ChainDeleteObj(p0, p1) } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 92465d5a78c607f3e5dc38fc1b857960bf5935c9..7e8b4dbc629b1fb28e63311afa046372056304ea 100644 GIT binary patch literal 23617 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

w+!f<<%U&e^v zbh(=P{UpKuIf`F&YOU-dqC4`s7yn|B=L!Au_|I)A0Q{j>D1boi?+`MHD}F1}p>Mht zLu3Cw|E6R5@_npul6Oa){m1M%p4KPDW5V*w;lUq8$sR$cX`5nCyK@du#QQvBkW}R5)Fr7*@g1sv z*L|8)1{OX?H>(;kGnf#tj(;>!h3MO>^Cc6jjsfD!r<`_M6T-m3WAWYo>)#{w*|#pmO_S8#ms;wFfJy}iK!&8`eD+d%QFa}`jP#>3{L-#T$y7p$lhIAx_RTH4sDJ)DdSwV zoF=SBCY*sB+iXXW<%KP(Sumj?L7*Lz7Mi53W5riI#?8q~5tfwt51SUSmb{8Ndc8I( zZfy7^0f+RlmPB%V{7uuRDp}R^6bCe5ZsJRO`w zgJ)IK9|1x$41*Z5Nz2nTI<=Uf13AZ~YTY_+TyjST2R^UUfKsSU=NwT?>s}NfS~BBQ z-773nXt*}XCuvL?C)x@ht9)kci0%)CGhL=|e~J$Z5W_RS|NMsx6-W~XC5Kz6S@(My z51)*dK@WR(ixr49DQ|``_LU`GfU95G7=qRccyog9>JUVdGB?uxAvu_O4@s&oz5S25 zxl>0oqz_B(_o$`w&waT;u4z!~R5?d-ZI}6%AFQ>1<*gm^$Qd^!g7&!l8kgvZv3;Q-&)kdb@0I(IGJXgh^M7;ZG#GFTP&WY;N#Q1E+q_Hd5Sic z(uSc^rMN!zi-`|JJN#JgM;NEddP%bGWzu7fB%ecb;&tkr&C}x)Td&-A_dNERifX;^ zA`}Sgei=MB4@xKc9m5Dp;zES4N zj&z8mz7(a)>tRf*iNaV#Gcgh#L6LM_P!jYqi{ zg*RKWdF}&WhIeGdeO9^XQw&+|Dnt5y$#0Rx3N(Gmny zpHwKR$uX19Ne<0B@9BM_?&7CtgU6ePlgYF!>dsmkQ@zJ-<^;dh|7vJku#yu{nCK-- zu#^6gh1dtT;C=Af)~=dTi$8Y$ybNYjW?Wv?NoSpww#)jP-9Trlq{-g4sjY@XJHScbBxmC{Yai5h~0Xu8uNWtD5-*%$jEAVJrWi zJM{N`gMAqH?V`OS<^Syb)3b=?pxBUF{T=UaW`eyAJGn~RX7Nl;^;u5lf3ri5DuX=y z^k{w!=QoqQHd*VpD5M7g93KSIwdOApa`wK)?TW=Cx$lWRl7v2Xbk%pi)B$HVKrDro zVzw?#Kk8JciJ9FK4FUnx9_Lq-*LGIi!n5t)bZ+33$JYh5KqG+NkRd-ZuIQQ1@I4By zJ;UR^)>f~RbFG5KH*A2$Hj_FFZgI)*voVT&Au!)mxr+#$f$^v`Pt~R*gd%V hY4Y%(Xf%DmLGyOyLgd{D>I;8=zc?_Yt*?ZK`7g!VkzxP< literal 23507 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 CmjyWh diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index aa8ba625d7acb408489f4ddf1ac4f201dd4fa984..194de8833742e9e67de726275e9d07c51042ade5 100644 GIT binary patch delta 8478 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 Date: Sun, 25 Jul 2021 11:30:58 +0300 Subject: [PATCH 19/38] handle newlines consistently in check output --- blockstore/splitstore/splitstore_check.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/blockstore/splitstore/splitstore_check.go b/blockstore/splitstore/splitstore_check.go index ba9386aaf..ce63fb726 100644 --- a/blockstore/splitstore/splitstore_check.go +++ b/blockstore/splitstore/splitstore_check.go @@ -66,19 +66,19 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error { defer output.Close() //nolint:errcheck write := func(format string, args ...interface{}) { - _, err := fmt.Fprintf(output, format, args...) + _, err := fmt.Fprintf(output, format+"\n", args...) if err != nil { log.Warnf("error writing check output: %s", err) } } ts, _ := time.Now().MarshalText() - write("---------------------------------------------\n") - write("start check at %s\n", ts) - write("current epoch: %d\n", currentEpoch) - write("boundary epoch: %d\n", boundaryEpoch) - write("compaction index: %d\n", s.compactionIndex) - write("--\n") + write("---------------------------------------------") + write("start check at %s", ts) + write("current epoch: %d", currentEpoch) + write("boundary epoch: %d", boundaryEpoch) + write("compaction index: %d", s.compactionIndex) + write("--") var coldCnt, missingCnt int64 err = s.walkChain(curTs, boundaryEpoch, boundaryEpoch, @@ -114,16 +114,16 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error { if err != nil { err = xerrors.Errorf("error walking chain: %w", err) - write("ERROR: %s\n", err) + write("ERROR: %s", err) return err } if coldCnt == 0 && missingCnt == 0 { log.Info("check OK") - write("OK\n") + write("OK") } else { log.Infow("check failed", "cold", coldCnt, "missing", missingCnt) - write("FAILED\n") + write("FAILED") } return nil From 5285a14d27c65739a955b55b8b0c023464b66998 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:42:13 +0300 Subject: [PATCH 20/38] write check summary at the end --- blockstore/splitstore/splitstore_check.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/blockstore/splitstore/splitstore_check.go b/blockstore/splitstore/splitstore_check.go index ce63fb726..fb567b58a 100644 --- a/blockstore/splitstore/splitstore_check.go +++ b/blockstore/splitstore/splitstore_check.go @@ -118,13 +118,10 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error { return err } - if coldCnt == 0 && missingCnt == 0 { - log.Info("check OK") - write("OK") - } else { - log.Infow("check failed", "cold", coldCnt, "missing", missingCnt) - write("FAILED") - } + log.Infow("check done", "cold", coldCnt, "missing", missingCnt) + write("--") + write("cold: %d missing: %d", coldCnt, missingCnt) + write("DONE") return nil } From 2dc72d58491eef5e73c0616b3bdf626f8c97715e Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 11:47:21 +0300 Subject: [PATCH 21/38] satisfy linter who wants to be a spell checker in comments --- node/impl/full/chain.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 579a82227..c36e99ffc 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -84,7 +84,7 @@ type ChainAPI struct { // blockstores. ExposedBlockstore dtypes.ExposedBlockstore - // BaseBlockstore is the underyling blockstore + // BaseBlockstore is the underlying blockstore BaseBlockstore dtypes.BaseBlockstore } From c00b86e8a86e247aa1da8f86dd7b8bf2f9ae041d Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 13:42:20 +0300 Subject: [PATCH 22/38] stop the walk on missing references --- blockstore/splitstore/splitstore_check.go | 1 + 1 file changed, 1 insertion(+) diff --git a/blockstore/splitstore/splitstore_check.go b/blockstore/splitstore/splitstore_check.go index fb567b58a..43834e87e 100644 --- a/blockstore/splitstore/splitstore_check.go +++ b/blockstore/splitstore/splitstore_check.go @@ -107,6 +107,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error { } else { missingCnt++ write("missing object reference: %s", c) + return errStopWalk } return nil From a0d6fdba33a236b4a2d12f8458397d18b592a732 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:30:07 +0300 Subject: [PATCH 23/38] add ChainBlockstoreInfo APIv1 endpoint --- api/api_full.go | 3 +++ node/impl/full/chain.go | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/api/api_full.go b/api/api_full.go index 472b34596..c03710ad8 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -168,6 +168,9 @@ type FullNode interface { // if supported by the underlying implementation. ChainCheckBlockstore(context.Context) error //perm:read + // ChainBlockstoreInfo returns some basic information about the blockstore + ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read + // MethodGroup: Beacon // The Beacon method group contains methods for interacting with the random beacon (DRAND) diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index c36e99ffc..c5c2334ad 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -656,3 +656,12 @@ func (a *ChainAPI) ChainCheckBlockstore(ctx context.Context) error { return checker.Check() } + +func (a *ChainAPI) ChainBlockstoreInfo(ctx context.Context) (map[string]interface{}, error) { + info, ok := a.BaseBlockstore.(interface{ Info() map[string]interface{} }) + if !ok { + return nil, xerrors.Errorf("underlying blockstore does not provide info") + } + + return info.Info(), nil +} From 77604db71672b4f79088a55ba682ae9a6b932e64 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:33:25 +0300 Subject: [PATCH 24/38] make gen --- api/mocks/mock_full.go | 15 +++++++++++++++ api/proxy_gen.go | 10 ++++++++++ build/openrpc/full.json.gz | Bin 23617 -> 23719 bytes build/openrpc/miner.json.gz | Bin 8672 -> 8671 bytes build/openrpc/worker.json.gz | Bin 2513 -> 2514 bytes documentation/en/api-v1-unstable-methods.md | 16 ++++++++++++++++ 6 files changed, 41 insertions(+) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index a6c091611..124532c14 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -105,6 +105,21 @@ func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1) } +// ChainBlockstoreInfo mocks base method. +func (m *MockFullNode) ChainBlockstoreInfo(arg0 context.Context) (map[string]interface{}, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ChainBlockstoreInfo", arg0) + ret0, _ := ret[0].(map[string]interface{}) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ChainBlockstoreInfo indicates an expected call of ChainBlockstoreInfo. +func (mr *MockFullNodeMockRecorder) ChainBlockstoreInfo(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainBlockstoreInfo", reflect.TypeOf((*MockFullNode)(nil).ChainBlockstoreInfo), arg0) +} + // ChainCheckBlockstore mocks base method. func (m *MockFullNode) ChainCheckBlockstore(arg0 context.Context) error { m.ctrl.T.Helper() diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 8191e881f..4c806350c 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -98,6 +98,8 @@ type FullNodeStruct struct { Internal struct { BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"` + ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"` + ChainCheckBlockstore func(p0 context.Context) error `perm:"read"` ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` @@ -953,6 +955,14 @@ func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*t return nil, xerrors.New("method not supported") } +func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { + return s.Internal.ChainBlockstoreInfo(p0) +} + +func (s *FullNodeStub) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { + return *new(map[string]interface{}), xerrors.New("method not supported") +} + func (s *FullNodeStruct) ChainCheckBlockstore(p0 context.Context) error { return s.Internal.ChainCheckBlockstore(p0) } diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 7e8b4dbc629b1fb28e63311afa046372056304ea..0afa796d59e7161878b9d7418a3cfcfd5b6e533d 100644 GIT binary patch delta 22133 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 delta 22112 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 diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index 194de8833742e9e67de726275e9d07c51042ade5..5cf696bb06582c29553fae067d0b0b285ebb47d2 100644 GIT binary patch delta 8080 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 delta 8159 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 F0RU6d&vO6( diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz index a75e908a889613c6f6d29b0bdeb3f79efed1443a..b6e33a6c5b3f40dd9d21aa56c187d33a45b15b1b 100644 GIT binary patch delta 2245 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 diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 18115ae7c..375fb4725 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -11,6 +11,7 @@ * [Beacon](#Beacon) * [BeaconGetEntry](#BeaconGetEntry) * [Chain](#Chain) + * [ChainBlockstoreInfo](#ChainBlockstoreInfo) * [ChainCheckBlockstore](#ChainCheckBlockstore) * [ChainDeleteObj](#ChainDeleteObj) * [ChainExport](#ChainExport) @@ -351,6 +352,21 @@ The Chain method group contains methods for interacting with the blockchain, but that do not require any form of state computation. +### ChainBlockstoreInfo +ChainBlockstoreInfo returns some basic information about the blockstore + + +Perms: read + +Inputs: `null` + +Response: +```json +{ + "abc": 123 +} +``` + ### ChainCheckBlockstore ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore if supported by the underlying implementation. From baaa9a77382c1726639b40ff6551a92e30d76575 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:42:54 +0300 Subject: [PATCH 25/38] add BlockstoreSize trait for reporting size --- blockstore/blockstore.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/blockstore/blockstore.go b/blockstore/blockstore.go index 97f9f5f7b..43e6cd1a4 100644 --- a/blockstore/blockstore.go +++ b/blockstore/blockstore.go @@ -40,6 +40,11 @@ type BlockstoreGC interface { CollectGarbage() error } +// BlockstoreSize is a trait for on-disk blockstores that can report their size +type BlockstoreSize interface { + Size() (int64, error) +} + // WrapIDStore wraps the underlying blockstore in an "identity" blockstore. // The ID store filters out all puts for blocks with CIDs using the "identity" // hash function. It also extracts inlined blocks from CIDs using the identity From 30e4b405b714f80fd9213a237a89e7ac8ad21197 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:43:09 +0300 Subject: [PATCH 26/38] implement BlockstoreSize for badger --- blockstore/badger/blockstore.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 82f0e3360..91de96b0e 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -95,6 +95,7 @@ var _ blockstore.Blockstore = (*Blockstore)(nil) var _ blockstore.Viewer = (*Blockstore)(nil) var _ blockstore.BlockstoreIterator = (*Blockstore)(nil) var _ blockstore.BlockstoreGC = (*Blockstore)(nil) +var _ blockstore.BlockstoreSize = (*Blockstore)(nil) var _ io.Closer = (*Blockstore)(nil) // Open creates a new badger-backed blockstore, with the supplied options. @@ -191,6 +192,17 @@ func (b *Blockstore) CollectGarbage() error { return err } +// Size returns the aggregate size of the blockstore +func (b *Blockstore) Size() (int64, error) { + if err := b.access(); err != nil { + return 0, err + } + defer b.viewers.Done() + + lsm, vlog := b.DB.Size() + return lsm + vlog, nil +} + // View implements blockstore.Viewer, which leverages zero-copy read-only // access to values. func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error { From ce528a12930c337f5a0bdf55844a0206bf0ba2d5 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:45:46 +0300 Subject: [PATCH 27/38] implement Info in splitstore --- blockstore/splitstore/splitstore_check.go | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/blockstore/splitstore/splitstore_check.go b/blockstore/splitstore/splitstore_check.go index 43834e87e..8c38b07e9 100644 --- a/blockstore/splitstore/splitstore_check.go +++ b/blockstore/splitstore/splitstore_check.go @@ -9,8 +9,10 @@ import ( "golang.org/x/xerrors" - "github.com/filecoin-project/lotus/chain/types" cid "github.com/ipfs/go-cid" + + bstore "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/chain/types" ) // performs an asynchronous health-check on the splitstore; results are appended to @@ -126,3 +128,23 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error { return nil } + +// provides some basic information about the splitstore +func (s *SplitStore) Info() map[string]interface{} { + info := make(map[string]interface{}) + info["base epoch"] = s.baseEpoch + info["warmup epoch"] = s.warmupEpoch + info["compactions"] = s.compactionIndex + + sizer, ok := s.hot.(bstore.BlockstoreSize) + if ok { + size, err := sizer.Size() + if err != nil { + log.Warnf("error getting hotstore size: %s", err) + } else { + info["hotstore size"] = size + } + } + + return info +} From 221dc7024f763f6d470a4a40101a8b3816a7f632 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:47:02 +0300 Subject: [PATCH 28/38] add splitstore info command --- cmd/lotus-shed/splitstore.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index ff949fda9..c2363c655 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -30,6 +30,7 @@ var splitstoreCmd = &cli.Command{ Subcommands: []*cli.Command{ splitstoreRollbackCmd, splitstoreCheckCmd, + splitstoreInfoCmd, }, } @@ -281,3 +282,29 @@ var splitstoreCheckCmd = &cli.Command{ return api.ChainCheckBlockstore(ctx) }, } + +var splitstoreInfoCmd = &cli.Command{ + Name: "info", + Description: "prints some basic splitstore information", + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + defer closer() + + ctx := lcli.ReqContext(cctx) + info, err := api.ChainBlockstoreInfo(ctx) + if err != nil { + return err + } + + for k, v := range info { + fmt.Print(k) + fmt.Print(": ") + fmt.Println(v) + } + + return nil + }, +} From 74009bd67fc05d6186e5d90bc8c9aa70cc479be2 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 08:52:32 +0300 Subject: [PATCH 29/38] document lotus-shed splitstore utiilities in the README --- blockstore/splitstore/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/blockstore/splitstore/README.md b/blockstore/splitstore/README.md index 5b0df61d9..b6f30ef43 100644 --- a/blockstore/splitstore/README.md +++ b/blockstore/splitstore/README.md @@ -99,3 +99,17 @@ Compaction works transactionally with the following algorithm: ## Garbage Collection TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577) + +## Utilities + +`lotus-shed` has a `splitstore` command which provides some utilities: + +- `rollback` -- rolls back a splitstore installation. + This command copies the hotstore on top of the coldstore, and then deletes the splitstore + directory and associated metadata keys. + It can also optionally compact/gc the coldstore after the copy (with the `--gc-coldstore` flag) + and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag). + Note: the node *must be stopped* before running this command. +- `check` -- asynchronously runs a basic healthcheck on the splitstore. + The results are appended to `/datastore/splitstore/check.txt`. +- `info` -- prints some basic information about the splitstore. From 2cfd73c879764224ba4364162cb4cc13126fe83c Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 09:46:21 +0300 Subject: [PATCH 30/38] manually compute size when badger is being stupid --- blockstore/badger/blockstore.go | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/blockstore/badger/blockstore.go b/blockstore/badger/blockstore.go index 91de96b0e..f8d077760 100644 --- a/blockstore/badger/blockstore.go +++ b/blockstore/badger/blockstore.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "io" + "os" + "path/filepath" "runtime" "sync" @@ -84,7 +86,8 @@ type Blockstore struct { state int viewers sync.WaitGroup - DB *badger.DB + DB *badger.DB + opts Options prefixing bool prefix []byte @@ -110,7 +113,7 @@ func Open(opts Options) (*Blockstore, error) { return nil, fmt.Errorf("failed to open badger blockstore: %w", err) } - bs := &Blockstore{DB: db} + bs := &Blockstore{DB: db, opts: opts} if p := opts.Prefix; p != "" { bs.prefixing = true bs.prefix = []byte(p) @@ -200,7 +203,27 @@ func (b *Blockstore) Size() (int64, error) { defer b.viewers.Done() lsm, vlog := b.DB.Size() - return lsm + vlog, nil + size := lsm + vlog + + if size == 0 { + // badger reports a 0 size on symlinked directories... sigh + dir := b.opts.Dir + entries, err := os.ReadDir(dir) + if err != nil { + return 0, err + } + + for _, e := range entries { + path := filepath.Join(dir, e.Name()) + finfo, err := os.Stat(path) + if err != nil { + return 0, err + } + size += finfo.Size() + } + } + + return size, nil } // View implements blockstore.Viewer, which leverages zero-copy read-only From 3c409d50236af50a7a3dbb91d408e06d0b9ebba6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 12:13:41 +0300 Subject: [PATCH 31/38] require admin for running checks on the splitstore. --- api/api_full.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/api_full.go b/api/api_full.go index c03710ad8..412e223cd 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -166,7 +166,7 @@ type FullNode interface { // ChainCheckBlockstore performs an (asynchronous) health check on the chain/state blockstore // if supported by the underlying implementation. - ChainCheckBlockstore(context.Context) error //perm:read + ChainCheckBlockstore(context.Context) error //perm:admin // ChainBlockstoreInfo returns some basic information about the blockstore ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read From 1f6935f8c419dbf71ba671e501b493193ffdd0e4 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 12:15:01 +0300 Subject: [PATCH 32/38] make gen --- api/proxy_gen.go | 2 +- documentation/en/api-v1-unstable-methods.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 4c806350c..50954eac9 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -100,7 +100,7 @@ type FullNodeStruct struct { ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"` - ChainCheckBlockstore func(p0 context.Context) error `perm:"read"` + ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"` ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"` diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 375fb4725..cbaed82af 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -372,7 +372,7 @@ ChainCheckBlockstore performs an (asynchronous) health check on the chain/state if supported by the underlying implementation. -Perms: read +Perms: admin Inputs: `null` From 76a9f4241b1329c55b0fd101f7ee131c6ce2196c Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 23 Jul 2021 19:16:42 -0400 Subject: [PATCH 33/38] feat: Graceful error when api impl is nil --- api/proxy_gen.go | 1822 +++++++++++++++++++++++++++------- api/v0api/proxy_gen.go | 1042 +++++++++++++++---- build/openrpc/full.json.gz | Bin 23719 -> 25240 bytes build/openrpc/miner.json.gz | Bin 8671 -> 9479 bytes build/openrpc/worker.json.gz | Bin 2514 -> 2710 bytes gen/api/proxygen.go | 8 +- go.mod | 4 +- go.sum | 12 +- 8 files changed, 2310 insertions(+), 578 deletions(-) diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 50954eac9..7d96425ff 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -39,6 +39,8 @@ import ( xerrors "golang.org/x/xerrors" ) +var ErrNotSupported = xerrors.New("method not supported") + type ChainIOStruct struct { Internal struct { ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `` @@ -860,2915 +862,4007 @@ type WorkerStub struct { } func (s *ChainIOStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ChainHasObj == nil { + return false, ErrNotSupported + } return s.Internal.ChainHasObj(p0, p1) } func (s *ChainIOStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *ChainIOStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + if s.Internal.ChainReadObj == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.ChainReadObj(p0, p1) } func (s *ChainIOStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *CommonStruct) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { + if s.Internal.AuthNew == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.AuthNew(p0, p1) } func (s *CommonStub) AuthNew(p0 context.Context, p1 []auth.Permission) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *CommonStruct) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { + if s.Internal.AuthVerify == nil { + return *new([]auth.Permission), ErrNotSupported + } return s.Internal.AuthVerify(p0, p1) } func (s *CommonStub) AuthVerify(p0 context.Context, p1 string) ([]auth.Permission, error) { - return *new([]auth.Permission), xerrors.New("method not supported") + return *new([]auth.Permission), ErrNotSupported } func (s *CommonStruct) Closing(p0 context.Context) (<-chan struct{}, error) { + if s.Internal.Closing == nil { + return nil, ErrNotSupported + } return s.Internal.Closing(p0) } func (s *CommonStub) Closing(p0 context.Context) (<-chan struct{}, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *CommonStruct) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { + if s.Internal.Discover == nil { + return *new(apitypes.OpenRPCDocument), ErrNotSupported + } return s.Internal.Discover(p0) } func (s *CommonStub) Discover(p0 context.Context) (apitypes.OpenRPCDocument, error) { - return *new(apitypes.OpenRPCDocument), xerrors.New("method not supported") + return *new(apitypes.OpenRPCDocument), ErrNotSupported } func (s *CommonStruct) LogList(p0 context.Context) ([]string, error) { + if s.Internal.LogList == nil { + return *new([]string), ErrNotSupported + } return s.Internal.LogList(p0) } func (s *CommonStub) LogList(p0 context.Context) ([]string, error) { - return *new([]string), xerrors.New("method not supported") + return *new([]string), ErrNotSupported } func (s *CommonStruct) LogSetLevel(p0 context.Context, p1 string, p2 string) error { + if s.Internal.LogSetLevel == nil { + return ErrNotSupported + } return s.Internal.LogSetLevel(p0, p1, p2) } func (s *CommonStub) LogSetLevel(p0 context.Context, p1 string, p2 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *CommonStruct) Session(p0 context.Context) (uuid.UUID, error) { + if s.Internal.Session == nil { + return *new(uuid.UUID), ErrNotSupported + } return s.Internal.Session(p0) } func (s *CommonStub) Session(p0 context.Context) (uuid.UUID, error) { - return *new(uuid.UUID), xerrors.New("method not supported") + return *new(uuid.UUID), ErrNotSupported } func (s *CommonStruct) Shutdown(p0 context.Context) error { + if s.Internal.Shutdown == nil { + return ErrNotSupported + } return s.Internal.Shutdown(p0) } func (s *CommonStub) Shutdown(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *CommonStruct) Version(p0 context.Context) (APIVersion, error) { + if s.Internal.Version == nil { + return *new(APIVersion), ErrNotSupported + } return s.Internal.Version(p0) } func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { - return *new(APIVersion), xerrors.New("method not supported") + return *new(APIVersion), ErrNotSupported } func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + if s.Internal.BeaconGetEntry == nil { + return nil, ErrNotSupported + } return s.Internal.BeaconGetEntry(p0, p1) } func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { + if s.Internal.ChainBlockstoreInfo == nil { + return *new(map[string]interface{}), ErrNotSupported + } return s.Internal.ChainBlockstoreInfo(p0) } func (s *FullNodeStub) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) { - return *new(map[string]interface{}), xerrors.New("method not supported") + return *new(map[string]interface{}), ErrNotSupported } func (s *FullNodeStruct) ChainCheckBlockstore(p0 context.Context) error { + if s.Internal.ChainCheckBlockstore == nil { + return ErrNotSupported + } return s.Internal.ChainCheckBlockstore(p0) } func (s *FullNodeStub) ChainCheckBlockstore(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + if s.Internal.ChainDeleteObj == nil { + return ErrNotSupported + } return s.Internal.ChainDeleteObj(p0, p1) } func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + if s.Internal.ChainExport == nil { + return nil, ErrNotSupported + } return s.Internal.ChainExport(p0, p1, p2, p3) } func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + if s.Internal.ChainGetBlock == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlock(p0, p1) } func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + if s.Internal.ChainGetBlockMessages == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlockMessages(p0, p1) } func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainGetGenesis == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetGenesis(p0) } func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + if s.Internal.ChainGetMessage == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetMessage(p0, p1) } func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]Message, error) { + if s.Internal.ChainGetMessagesInTipset == nil { + return *new([]Message), ErrNotSupported + } return s.Internal.ChainGetMessagesInTipset(p0, p1) } func (s *FullNodeStub) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]Message, error) { - return *new([]Message), xerrors.New("method not supported") + return *new([]Message), ErrNotSupported } func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { + if s.Internal.ChainGetNode == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetNode(p0, p1) } func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*IpldObject, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { + if s.Internal.ChainGetParentMessages == nil { + return *new([]Message), ErrNotSupported + } return s.Internal.ChainGetParentMessages(p0, p1) } func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]Message, error) { - return *new([]Message), xerrors.New("method not supported") + return *new([]Message), ErrNotSupported } func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + if s.Internal.ChainGetParentReceipts == nil { + return *new([]*types.MessageReceipt), ErrNotSupported + } return s.Internal.ChainGetParentReceipts(p0, p1) } func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { - return *new([]*types.MessageReceipt), xerrors.New("method not supported") + return *new([]*types.MessageReceipt), ErrNotSupported } func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { + if s.Internal.ChainGetPath == nil { + return *new([]*HeadChange), ErrNotSupported + } return s.Internal.ChainGetPath(p0, p1, p2) } func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*HeadChange, error) { - return *new([]*HeadChange), xerrors.New("method not supported") + return *new([]*HeadChange), ErrNotSupported } func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + if s.Internal.ChainGetRandomnessFromBeacon == nil { + return *new(abi.Randomness), ErrNotSupported + } return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) } func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return *new(abi.Randomness), xerrors.New("method not supported") + return *new(abi.Randomness), ErrNotSupported } func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + if s.Internal.ChainGetRandomnessFromTickets == nil { + return *new(abi.Randomness), ErrNotSupported + } return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) } func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return *new(abi.Randomness), xerrors.New("method not supported") + return *new(abi.Randomness), ErrNotSupported } func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSet == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSet(p0, p1) } func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSetByHeight == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ChainHasObj == nil { + return false, ErrNotSupported + } return s.Internal.ChainHasObj(p0, p1) } func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainHead == nil { + return nil, ErrNotSupported + } return s.Internal.ChainHead(p0) } func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + if s.Internal.ChainNotify == nil { + return nil, ErrNotSupported + } return s.Internal.ChainNotify(p0) } func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + if s.Internal.ChainReadObj == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.ChainReadObj(p0, p1) } func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + if s.Internal.ChainSetHead == nil { + return ErrNotSupported + } return s.Internal.ChainSetHead(p0, p1) } func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { + if s.Internal.ChainStatObj == nil { + return *new(ObjStat), ErrNotSupported + } return s.Internal.ChainStatObj(p0, p1, p2) } func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (ObjStat, error) { - return *new(ObjStat), xerrors.New("method not supported") + return *new(ObjStat), ErrNotSupported } func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + if s.Internal.ChainTipSetWeight == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.ChainTipSetWeight(p0, p1) } func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { + if s.Internal.ClientCalcCommP == nil { + return nil, ErrNotSupported + } return s.Internal.ClientCalcCommP(p0, p1) } func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*CommPRet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.ClientCancelDataTransfer == nil { + return ErrNotSupported + } return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + if s.Internal.ClientCancelRetrievalDeal == nil { + return ErrNotSupported + } return s.Internal.ClientCancelRetrievalDeal(p0, p1) } func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + if s.Internal.ClientDataTransferUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientDataTransferUpdates(p0) } func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { + if s.Internal.ClientDealPieceCID == nil { + return *new(DataCIDSize), ErrNotSupported + } return s.Internal.ClientDealPieceCID(p0, p1) } func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (DataCIDSize, error) { - return *new(DataCIDSize), xerrors.New("method not supported") + return *new(DataCIDSize), ErrNotSupported } func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { + if s.Internal.ClientDealSize == nil { + return *new(DataSize), ErrNotSupported + } return s.Internal.ClientDealSize(p0, p1) } func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (DataSize, error) { - return *new(DataSize), xerrors.New("method not supported") + return *new(DataSize), ErrNotSupported } func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { + if s.Internal.ClientFindData == nil { + return *new([]QueryOffer), ErrNotSupported + } return s.Internal.ClientFindData(p0, p1, p2) } func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]QueryOffer, error) { - return *new([]QueryOffer), xerrors.New("method not supported") + return *new([]QueryOffer), ErrNotSupported } func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { + if s.Internal.ClientGenCar == nil { + return ErrNotSupported + } return s.Internal.ClientGenCar(p0, p1, p2) } func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 FileRef, p2 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { + if s.Internal.ClientGetDealInfo == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetDealInfo(p0, p1) } func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*DealInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + if s.Internal.ClientGetDealStatus == nil { + return "", ErrNotSupported + } return s.Internal.ClientGetDealStatus(p0, p1) } func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { - return "", xerrors.New("method not supported") + return "", ErrNotSupported } func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { + if s.Internal.ClientGetDealUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetDealUpdates(p0) } func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan DealInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) { + if s.Internal.ClientGetRetrievalUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetRetrievalUpdates(p0) } func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan RetrievalInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ClientHasLocal == nil { + return false, ErrNotSupported + } return s.Internal.ClientHasLocal(p0, p1) } func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { + if s.Internal.ClientImport == nil { + return nil, ErrNotSupported + } return s.Internal.ClientImport(p0, p1) } func (s *FullNodeStub) ClientImport(p0 context.Context, p1 FileRef) (*ImportRes, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + if s.Internal.ClientListDataTransfers == nil { + return *new([]DataTransferChannel), ErrNotSupported + } return s.Internal.ClientListDataTransfers(p0) } func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { - return *new([]DataTransferChannel), xerrors.New("method not supported") + return *new([]DataTransferChannel), ErrNotSupported } func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]DealInfo, error) { + if s.Internal.ClientListDeals == nil { + return *new([]DealInfo), ErrNotSupported + } return s.Internal.ClientListDeals(p0) } func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]DealInfo, error) { - return *new([]DealInfo), xerrors.New("method not supported") + return *new([]DealInfo), ErrNotSupported } func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]Import, error) { + if s.Internal.ClientListImports == nil { + return *new([]Import), ErrNotSupported + } return s.Internal.ClientListImports(p0) } func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]Import, error) { - return *new([]Import), xerrors.New("method not supported") + return *new([]Import), ErrNotSupported } func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { + if s.Internal.ClientListRetrievals == nil { + return *new([]RetrievalInfo), ErrNotSupported + } return s.Internal.ClientListRetrievals(p0) } func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]RetrievalInfo, error) { - return *new([]RetrievalInfo), xerrors.New("method not supported") + return *new([]RetrievalInfo), ErrNotSupported } func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { + if s.Internal.ClientMinerQueryOffer == nil { + return *new(QueryOffer), ErrNotSupported + } return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (QueryOffer, error) { - return *new(QueryOffer), xerrors.New("method not supported") + return *new(QueryOffer), ErrNotSupported } func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + if s.Internal.ClientQueryAsk == nil { + return nil, ErrNotSupported + } return s.Internal.ClientQueryAsk(p0, p1, p2) } func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + if s.Internal.ClientRemoveImport == nil { + return ErrNotSupported + } return s.Internal.ClientRemoveImport(p0, p1) } func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.ClientRestartDataTransfer == nil { + return ErrNotSupported + } return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { + if s.Internal.ClientRetrieve == nil { + return ErrNotSupported + } return s.Internal.ClientRetrieve(p0, p1, p2) } func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + if s.Internal.ClientRetrieveTryRestartInsufficientFunds == nil { + return ErrNotSupported + } return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { + if s.Internal.ClientRetrieveWithEvents == nil { + return nil, ErrNotSupported + } return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 RetrievalOrder, p2 *FileRef) (<-chan marketevents.RetrievalEvent, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { + if s.Internal.ClientStartDeal == nil { + return nil, ErrNotSupported + } return s.Internal.ClientStartDeal(p0, p1) } func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientStatelessDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { + if s.Internal.ClientStatelessDeal == nil { + return nil, ErrNotSupported + } return s.Internal.ClientStatelessDeal(p0, p1) } func (s *FullNodeStub) ClientStatelessDeal(p0 context.Context, p1 *StartDealParams) (*cid.Cid, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { + if s.Internal.CreateBackup == nil { + return ErrNotSupported + } return s.Internal.CreateBackup(p0, p1) } func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.GasEstimateFeeCap == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) } func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + if s.Internal.GasEstimateGasLimit == nil { + return 0, ErrNotSupported + } return s.Internal.GasEstimateGasLimit(p0, p1, p2) } func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + if s.Internal.GasEstimateGasPremium == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + if s.Internal.GasEstimateMessageGas == nil { + return nil, ErrNotSupported + } return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketAddBalance == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketAddBalance(p0, p1, p2, p3) } func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.MarketGetReserved == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MarketGetReserved(p0, p1) } func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + if s.Internal.MarketReleaseFunds == nil { + return ErrNotSupported + } return s.Internal.MarketReleaseFunds(p0, p1, p2) } func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketReserveFunds == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketReserveFunds(p0, p1, p2, p3) } func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketWithdraw == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketWithdraw(p0, p1, p2, p3) } func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { + if s.Internal.MinerCreateBlock == nil { + return nil, ErrNotSupported + } return s.Internal.MinerCreateBlock(p0, p1) } func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *BlockTemplate) (*types.BlockMsg, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { + if s.Internal.MinerGetBaseInfo == nil { + return nil, ErrNotSupported + } return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*MiningBaseInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + if s.Internal.MpoolBatchPush == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.MpoolBatchPush(p0, p1) } func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { + if s.Internal.MpoolBatchPushMessage == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *MessageSendSpec) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + if s.Internal.MpoolBatchPushUntrusted == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.MpoolBatchPushUntrusted(p0, p1) } func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) { + if s.Internal.MpoolCheckMessages == nil { + return *new([][]MessageCheckStatus), ErrNotSupported + } return s.Internal.MpoolCheckMessages(p0, p1) } func (s *FullNodeStub) MpoolCheckMessages(p0 context.Context, p1 []*MessagePrototype) ([][]MessageCheckStatus, error) { - return *new([][]MessageCheckStatus), xerrors.New("method not supported") + return *new([][]MessageCheckStatus), ErrNotSupported } func (s *FullNodeStruct) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) { + if s.Internal.MpoolCheckPendingMessages == nil { + return *new([][]MessageCheckStatus), ErrNotSupported + } return s.Internal.MpoolCheckPendingMessages(p0, p1) } func (s *FullNodeStub) MpoolCheckPendingMessages(p0 context.Context, p1 address.Address) ([][]MessageCheckStatus, error) { - return *new([][]MessageCheckStatus), xerrors.New("method not supported") + return *new([][]MessageCheckStatus), ErrNotSupported } func (s *FullNodeStruct) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) { + if s.Internal.MpoolCheckReplaceMessages == nil { + return *new([][]MessageCheckStatus), ErrNotSupported + } return s.Internal.MpoolCheckReplaceMessages(p0, p1) } func (s *FullNodeStub) MpoolCheckReplaceMessages(p0 context.Context, p1 []*types.Message) ([][]MessageCheckStatus, error) { - return *new([][]MessageCheckStatus), xerrors.New("method not supported") + return *new([][]MessageCheckStatus), ErrNotSupported } func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { + if s.Internal.MpoolClear == nil { + return ErrNotSupported + } return s.Internal.MpoolClear(p0, p1) } func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + if s.Internal.MpoolGetConfig == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolGetConfig(p0) } func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + if s.Internal.MpoolGetNonce == nil { + return 0, ErrNotSupported + } return s.Internal.MpoolGetNonce(p0, p1) } func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + if s.Internal.MpoolPending == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolPending(p0, p1) } func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPush == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPush(p0, p1) } func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { + if s.Internal.MpoolPushMessage == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolPushMessage(p0, p1, p2) } func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec) (*types.SignedMessage, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPushUntrusted == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPushUntrusted(p0, p1) } func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + if s.Internal.MpoolSelect == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolSelect(p0, p1, p2) } func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + if s.Internal.MpoolSetConfig == nil { + return ErrNotSupported + } return s.Internal.MpoolSetConfig(p0, p1) } func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { + if s.Internal.MpoolSub == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolSub(p0) } func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan MpoolUpdate, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) { + if s.Internal.MsigAddApprove == nil { + return nil, ErrNotSupported + } return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) { + if s.Internal.MsigAddCancel == nil { + return nil, ErrNotSupported + } return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) } func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + if s.Internal.MsigAddPropose == nil { + return nil, ErrNotSupported + } return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) { + if s.Internal.MsigApprove == nil { + return nil, ErrNotSupported + } return s.Internal.MsigApprove(p0, p1, p2, p3) } func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) { + if s.Internal.MsigApproveTxnHash == nil { + return nil, ErrNotSupported + } return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) } func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) { + if s.Internal.MsigCancel == nil { + return nil, ErrNotSupported + } return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) } func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) { + if s.Internal.MsigCreate == nil { + return nil, ErrNotSupported + } return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + if s.Internal.MsigGetPending == nil { + return *new([]*MsigTransaction), ErrNotSupported + } return s.Internal.MsigGetPending(p0, p1, p2) } func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { - return *new([]*MsigTransaction), xerrors.New("method not supported") + return *new([]*MsigTransaction), ErrNotSupported } func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetVested == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetVested(p0, p1, p2, p3) } func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { + if s.Internal.MsigGetVestingSchedule == nil { + return *new(MsigVesting), ErrNotSupported + } return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) { - return *new(MsigVesting), xerrors.New("method not supported") + return *new(MsigVesting), ErrNotSupported } func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) { + if s.Internal.MsigPropose == nil { + return nil, ErrNotSupported + } return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { + if s.Internal.MsigRemoveSigner == nil { + return nil, ErrNotSupported + } return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) { + if s.Internal.MsigSwapApprove == nil { + return nil, ErrNotSupported + } return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) { + if s.Internal.MsigSwapCancel == nil { + return nil, ErrNotSupported + } return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) } func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) { + if s.Internal.MsigSwapPropose == nil { + return nil, ErrNotSupported + } return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) { + if s.Internal.NodeStatus == nil { + return *new(NodeStatus), ErrNotSupported + } return s.Internal.NodeStatus(p0, p1) } func (s *FullNodeStub) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) { - return *new(NodeStatus), xerrors.New("method not supported") + return *new(NodeStatus), ErrNotSupported } func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + if s.Internal.PaychAllocateLane == nil { + return 0, ErrNotSupported + } return s.Internal.PaychAllocateLane(p0, p1) } func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { + if s.Internal.PaychAvailableFunds == nil { + return nil, ErrNotSupported + } return s.Internal.PaychAvailableFunds(p0, p1) } func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*ChannelAvailableFunds, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { + if s.Internal.PaychAvailableFundsByFromTo == nil { + return nil, ErrNotSupported + } return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*ChannelAvailableFunds, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + if s.Internal.PaychCollect == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychCollect(p0, p1) } func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { + if s.Internal.PaychGet == nil { + return nil, ErrNotSupported + } return s.Internal.PaychGet(p0, p1, p2, p3) } func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*ChannelInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + if s.Internal.PaychGetWaitReady == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.PaychGetWaitReady(p0, p1) } func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { + if s.Internal.PaychList == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.PaychList(p0) } func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { + if s.Internal.PaychNewPayment == nil { + return nil, ErrNotSupported + } return s.Internal.PaychNewPayment(p0, p1, p2, p3) } func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []VoucherSpec) (*PaymentInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + if s.Internal.PaychSettle == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychSettle(p0, p1) } func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { + if s.Internal.PaychStatus == nil { + return nil, ErrNotSupported + } return s.Internal.PaychStatus(p0, p1) } func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*PaychStatus, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + if s.Internal.PaychVoucherAdd == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + if s.Internal.PaychVoucherCheckSpendable == nil { + return false, ErrNotSupported + } return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + if s.Internal.PaychVoucherCheckValid == nil { + return ErrNotSupported + } return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { + if s.Internal.PaychVoucherCreate == nil { + return nil, ErrNotSupported + } return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*VoucherCreateResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + if s.Internal.PaychVoucherList == nil { + return *new([]*paych.SignedVoucher), ErrNotSupported + } return s.Internal.PaychVoucherList(p0, p1) } func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { - return *new([]*paych.SignedVoucher), xerrors.New("method not supported") + return *new([]*paych.SignedVoucher), ErrNotSupported } func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + if s.Internal.PaychVoucherSubmit == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateAccountKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateAccountKey(p0, p1, p2) } func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { + if s.Internal.StateAllMinerFaults == nil { + return *new([]*Fault), ErrNotSupported + } return s.Internal.StateAllMinerFaults(p0, p1, p2) } func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*Fault, error) { - return *new([]*Fault), xerrors.New("method not supported") + return *new([]*Fault), ErrNotSupported } func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { + if s.Internal.StateCall == nil { + return nil, ErrNotSupported + } return s.Internal.StateCall(p0, p1, p2) } func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + if s.Internal.StateChangedActors == nil { + return *new(map[string]types.Actor), ErrNotSupported + } return s.Internal.StateChangedActors(p0, p1, p2) } func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { - return *new(map[string]types.Actor), xerrors.New("method not supported") + return *new(map[string]types.Actor), ErrNotSupported } func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + if s.Internal.StateCirculatingSupply == nil { + return *new(abi.TokenAmount), ErrNotSupported + } return s.Internal.StateCirculatingSupply(p0, p1) } func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { - return *new(abi.TokenAmount), xerrors.New("method not supported") + return *new(abi.TokenAmount), ErrNotSupported } func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { + if s.Internal.StateCompute == nil { + return nil, ErrNotSupported + } return s.Internal.StateCompute(p0, p1, p2, p3) } func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*ComputeStateOutput, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + if s.Internal.StateDealProviderCollateralBounds == nil { + return *new(DealCollateralBounds), ErrNotSupported + } return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { - return *new(DealCollateralBounds), xerrors.New("method not supported") + return *new(DealCollateralBounds), ErrNotSupported } func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + if s.Internal.StateDecodeParams == nil { + return nil, ErrNotSupported + } return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) } func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + if s.Internal.StateGetActor == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetActor(p0, p1, p2) } func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListActors == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListActors(p0, p1) } func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + if s.Internal.StateListMessages == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.StateListMessages(p0, p1, p2, p3) } func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListMiners == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListMiners(p0, p1) } func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateLookupID == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateLookupID(p0, p1, p2) } func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + if s.Internal.StateMarketBalance == nil { + return *new(MarketBalance), ErrNotSupported + } return s.Internal.StateMarketBalance(p0, p1, p2) } func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { - return *new(MarketBalance), xerrors.New("method not supported") + return *new(MarketBalance), ErrNotSupported } func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { + if s.Internal.StateMarketDeals == nil { + return *new(map[string]MarketDeal), ErrNotSupported + } return s.Internal.StateMarketDeals(p0, p1) } func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]MarketDeal, error) { - return *new(map[string]MarketDeal), xerrors.New("method not supported") + return *new(map[string]MarketDeal), ErrNotSupported } func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { + if s.Internal.StateMarketParticipants == nil { + return *new(map[string]MarketBalance), ErrNotSupported + } return s.Internal.StateMarketParticipants(p0, p1) } func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]MarketBalance, error) { - return *new(map[string]MarketBalance), xerrors.New("method not supported") + return *new(map[string]MarketBalance), ErrNotSupported } func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + if s.Internal.StateMarketStorageDeal == nil { + return nil, ErrNotSupported + } return s.Internal.StateMarketStorageDeal(p0, p1, p2) } func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + if s.Internal.StateMinerActiveSectors == nil { + return *new([]*miner.SectorOnChainInfo), ErrNotSupported + } return s.Internal.StateMinerActiveSectors(p0, p1, p2) } func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") + return *new([]*miner.SectorOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { + if s.Internal.StateMinerDeadlines == nil { + return *new([]Deadline), ErrNotSupported + } return s.Internal.StateMinerDeadlines(p0, p1, p2) } func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]Deadline, error) { - return *new([]Deadline), xerrors.New("method not supported") + return *new([]Deadline), ErrNotSupported } func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + if s.Internal.StateMinerFaults == nil { + return *new(bitfield.BitField), ErrNotSupported + } return s.Internal.StateMinerFaults(p0, p1, p2) } func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return *new(bitfield.BitField), xerrors.New("method not supported") + return *new(bitfield.BitField), ErrNotSupported } func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + if s.Internal.StateMinerInfo == nil { + return *new(miner.MinerInfo), ErrNotSupported + } return s.Internal.StateMinerInfo(p0, p1, p2) } func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return *new(miner.MinerInfo), xerrors.New("method not supported") + return *new(miner.MinerInfo), ErrNotSupported } func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerInitialPledgeCollateral == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { + if s.Internal.StateMinerPartitions == nil { + return *new([]Partition), ErrNotSupported + } return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]Partition, error) { - return *new([]Partition), xerrors.New("method not supported") + return *new([]Partition), ErrNotSupported } func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + if s.Internal.StateMinerPower == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerPower(p0, p1, p2) } func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerPreCommitDepositForPower == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + if s.Internal.StateMinerProvingDeadline == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + if s.Internal.StateMinerRecoveries == nil { + return *new(bitfield.BitField), ErrNotSupported + } return s.Internal.StateMinerRecoveries(p0, p1, p2) } func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return *new(bitfield.BitField), xerrors.New("method not supported") + return *new(bitfield.BitField), ErrNotSupported } func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + if s.Internal.StateMinerSectorAllocated == nil { + return false, ErrNotSupported + } return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { + if s.Internal.StateMinerSectorCount == nil { + return *new(MinerSectors), ErrNotSupported + } return s.Internal.StateMinerSectorCount(p0, p1, p2) } func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MinerSectors, error) { - return *new(MinerSectors), xerrors.New("method not supported") + return *new(MinerSectors), ErrNotSupported } func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + if s.Internal.StateMinerSectors == nil { + return *new([]*miner.SectorOnChainInfo), ErrNotSupported + } return s.Internal.StateMinerSectors(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") + return *new([]*miner.SectorOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + if s.Internal.StateNetworkName == nil { + return *new(dtypes.NetworkName), ErrNotSupported + } return s.Internal.StateNetworkName(p0) } func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { - return *new(dtypes.NetworkName), xerrors.New("method not supported") + return *new(dtypes.NetworkName), ErrNotSupported } func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + if s.Internal.StateNetworkVersion == nil { + return *new(apitypes.NetworkVersion), ErrNotSupported + } return s.Internal.StateNetworkVersion(p0, p1) } func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { - return *new(apitypes.NetworkVersion), xerrors.New("method not supported") + return *new(apitypes.NetworkVersion), ErrNotSupported } func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { + if s.Internal.StateReadState == nil { + return nil, ErrNotSupported + } return s.Internal.StateReadState(p0, p1, p2) } func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { + if s.Internal.StateReplay == nil { + return nil, ErrNotSupported + } return s.Internal.StateReplay(p0, p1, p2) } func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*InvocResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + if s.Internal.StateSearchMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) } func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + if s.Internal.StateSectorExpiration == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if s.Internal.StateSectorGetInfo == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + if s.Internal.StateSectorPartition == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorPartition(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + if s.Internal.StateSectorPreCommitInfo == nil { + return *new(miner.SectorPreCommitOnChainInfo), ErrNotSupported + } return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { - return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") + return *new(miner.SectorPreCommitOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { + if s.Internal.StateVMCirculatingSupplyInternal == nil { + return *new(CirculatingSupply), ErrNotSupported + } return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (CirculatingSupply, error) { - return *new(CirculatingSupply), xerrors.New("method not supported") + return *new(CirculatingSupply), ErrNotSupported } func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifiedClientStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + if s.Internal.StateVerifiedRegistryRootKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateVerifiedRegistryRootKey(p0, p1) } func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifierStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifierStatus(p0, p1, p2) } func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + if s.Internal.StateWaitMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) } func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + if s.Internal.SyncCheckBad == nil { + return "", ErrNotSupported + } return s.Internal.SyncCheckBad(p0, p1) } func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { - return "", xerrors.New("method not supported") + return "", ErrNotSupported } func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + if s.Internal.SyncCheckpoint == nil { + return ErrNotSupported + } return s.Internal.SyncCheckpoint(p0, p1) } func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + if s.Internal.SyncIncomingBlocks == nil { + return nil, ErrNotSupported + } return s.Internal.SyncIncomingBlocks(p0) } func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + if s.Internal.SyncMarkBad == nil { + return ErrNotSupported + } return s.Internal.SyncMarkBad(p0, p1) } func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncState(p0 context.Context) (*SyncState, error) { + if s.Internal.SyncState == nil { + return nil, ErrNotSupported + } return s.Internal.SyncState(p0) } func (s *FullNodeStub) SyncState(p0 context.Context) (*SyncState, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + if s.Internal.SyncSubmitBlock == nil { + return ErrNotSupported + } return s.Internal.SyncSubmitBlock(p0, p1) } func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { + if s.Internal.SyncUnmarkAllBad == nil { + return ErrNotSupported + } return s.Internal.SyncUnmarkAllBad(p0) } func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + if s.Internal.SyncUnmarkBad == nil { + return ErrNotSupported + } return s.Internal.SyncUnmarkBad(p0, p1) } func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + if s.Internal.SyncValidateTipset == nil { + return false, ErrNotSupported + } return s.Internal.SyncValidateTipset(p0, p1) } func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.WalletBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.WalletBalance(p0, p1) } func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + if s.Internal.WalletDefaultAddress == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletDefaultAddress(p0) } func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + if s.Internal.WalletDelete == nil { + return ErrNotSupported + } return s.Internal.WalletDelete(p0, p1) } func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + if s.Internal.WalletExport == nil { + return nil, ErrNotSupported + } return s.Internal.WalletExport(p0, p1) } func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + if s.Internal.WalletHas == nil { + return false, ErrNotSupported + } return s.Internal.WalletHas(p0, p1) } func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + if s.Internal.WalletImport == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletImport(p0, p1) } func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { + if s.Internal.WalletList == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.WalletList(p0) } func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + if s.Internal.WalletNew == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletNew(p0, p1) } func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { + if s.Internal.WalletSetDefault == nil { + return ErrNotSupported + } return s.Internal.WalletSetDefault(p0, p1) } func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + if s.Internal.WalletSign == nil { + return nil, ErrNotSupported + } return s.Internal.WalletSign(p0, p1, p2) } func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + if s.Internal.WalletSignMessage == nil { + return nil, ErrNotSupported + } return s.Internal.WalletSignMessage(p0, p1, p2) } func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + if s.Internal.WalletValidateAddress == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletValidateAddress(p0, p1) } func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + if s.Internal.WalletVerify == nil { + return false, ErrNotSupported + } return s.Internal.WalletVerify(p0, p1, p2, p3) } func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { + if s.Internal.ChainGetBlockMessages == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlockMessages(p0, p1) } func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + if s.Internal.ChainGetMessage == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetMessage(p0, p1) } func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSet == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSet(p0, p1) } func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSetByHeight == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ChainHasObj == nil { + return false, ErrNotSupported + } return s.Internal.ChainHasObj(p0, p1) } func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainHead == nil { + return nil, ErrNotSupported + } return s.Internal.ChainHead(p0) } func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { + if s.Internal.ChainNotify == nil { + return nil, ErrNotSupported + } return s.Internal.ChainNotify(p0) } func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*HeadChange, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + if s.Internal.ChainReadObj == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.ChainReadObj(p0, p1) } func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + if s.Internal.GasEstimateMessageGas == nil { + return nil, ErrNotSupported + } return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPush == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPush(p0, p1) } func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { + if s.Internal.MsigGetPending == nil { + return *new([]*MsigTransaction), ErrNotSupported + } return s.Internal.MsigGetPending(p0, p1, p2) } func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*MsigTransaction, error) { - return *new([]*MsigTransaction), xerrors.New("method not supported") + return *new([]*MsigTransaction), ErrNotSupported } func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetVested == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetVested(p0, p1, p2, p3) } func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateAccountKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateAccountKey(p0, p1, p2) } func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { + if s.Internal.StateDealProviderCollateralBounds == nil { + return *new(DealCollateralBounds), ErrNotSupported + } return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) { - return *new(DealCollateralBounds), xerrors.New("method not supported") + return *new(DealCollateralBounds), ErrNotSupported } func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + if s.Internal.StateGetActor == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetActor(p0, p1, p2) } func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListMiners == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListMiners(p0, p1) } func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateLookupID == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateLookupID(p0, p1, p2) } func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { + if s.Internal.StateMarketBalance == nil { + return *new(MarketBalance), ErrNotSupported + } return s.Internal.StateMarketBalance(p0, p1, p2) } func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MarketBalance, error) { - return *new(MarketBalance), xerrors.New("method not supported") + return *new(MarketBalance), ErrNotSupported } func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { + if s.Internal.StateMarketStorageDeal == nil { + return nil, ErrNotSupported + } return s.Internal.StateMarketStorageDeal(p0, p1, p2) } func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*MarketDeal, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + if s.Internal.StateMinerInfo == nil { + return *new(miner.MinerInfo), ErrNotSupported + } return s.Internal.StateMinerInfo(p0, p1, p2) } func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return *new(miner.MinerInfo), xerrors.New("method not supported") + return *new(miner.MinerInfo), ErrNotSupported } func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { + if s.Internal.StateMinerPower == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerPower(p0, p1, p2) } func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*MinerPower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + if s.Internal.StateMinerProvingDeadline == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + if s.Internal.StateNetworkVersion == nil { + return *new(apitypes.NetworkVersion), ErrNotSupported + } return s.Internal.StateNetworkVersion(p0, p1) } func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { - return *new(apitypes.NetworkVersion), xerrors.New("method not supported") + return *new(apitypes.NetworkVersion), ErrNotSupported } func (s *GatewayStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { + if s.Internal.StateReadState == nil { + return nil, ErrNotSupported + } return s.Internal.StateReadState(p0, p1, p2) } func (s *GatewayStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + if s.Internal.StateSearchMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateSearchMsg(p0, p1, p2, p3, p4) } func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if s.Internal.StateSectorGetInfo == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifiedClientStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { + if s.Internal.StateWaitMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateWaitMsg(p0, p1, p2, p3, p4) } func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) Version(p0 context.Context) (APIVersion, error) { + if s.Internal.Version == nil { + return *new(APIVersion), ErrNotSupported + } return s.Internal.Version(p0) } func (s *GatewayStub) Version(p0 context.Context) (APIVersion, error) { - return *new(APIVersion), xerrors.New("method not supported") + return *new(APIVersion), ErrNotSupported } func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.WalletBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.WalletBalance(p0, p1) } func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *NetStruct) ID(p0 context.Context) (peer.ID, error) { + if s.Internal.ID == nil { + return *new(peer.ID), ErrNotSupported + } return s.Internal.ID(p0) } func (s *NetStub) ID(p0 context.Context) (peer.ID, error) { - return *new(peer.ID), xerrors.New("method not supported") + return *new(peer.ID), ErrNotSupported } func (s *NetStruct) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { + if s.Internal.NetAddrsListen == nil { + return *new(peer.AddrInfo), ErrNotSupported + } return s.Internal.NetAddrsListen(p0) } func (s *NetStub) NetAddrsListen(p0 context.Context) (peer.AddrInfo, error) { - return *new(peer.AddrInfo), xerrors.New("method not supported") + return *new(peer.AddrInfo), ErrNotSupported } func (s *NetStruct) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { + if s.Internal.NetAgentVersion == nil { + return "", ErrNotSupported + } return s.Internal.NetAgentVersion(p0, p1) } func (s *NetStub) NetAgentVersion(p0 context.Context, p1 peer.ID) (string, error) { - return "", xerrors.New("method not supported") + return "", ErrNotSupported } func (s *NetStruct) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { + if s.Internal.NetAutoNatStatus == nil { + return *new(NatInfo), ErrNotSupported + } return s.Internal.NetAutoNatStatus(p0) } func (s *NetStub) NetAutoNatStatus(p0 context.Context) (NatInfo, error) { - return *new(NatInfo), xerrors.New("method not supported") + return *new(NatInfo), ErrNotSupported } func (s *NetStruct) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { + if s.Internal.NetBandwidthStats == nil { + return *new(metrics.Stats), ErrNotSupported + } return s.Internal.NetBandwidthStats(p0) } func (s *NetStub) NetBandwidthStats(p0 context.Context) (metrics.Stats, error) { - return *new(metrics.Stats), xerrors.New("method not supported") + return *new(metrics.Stats), ErrNotSupported } func (s *NetStruct) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { + if s.Internal.NetBandwidthStatsByPeer == nil { + return *new(map[string]metrics.Stats), ErrNotSupported + } return s.Internal.NetBandwidthStatsByPeer(p0) } func (s *NetStub) NetBandwidthStatsByPeer(p0 context.Context) (map[string]metrics.Stats, error) { - return *new(map[string]metrics.Stats), xerrors.New("method not supported") + return *new(map[string]metrics.Stats), ErrNotSupported } func (s *NetStruct) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { + if s.Internal.NetBandwidthStatsByProtocol == nil { + return *new(map[protocol.ID]metrics.Stats), ErrNotSupported + } return s.Internal.NetBandwidthStatsByProtocol(p0) } func (s *NetStub) NetBandwidthStatsByProtocol(p0 context.Context) (map[protocol.ID]metrics.Stats, error) { - return *new(map[protocol.ID]metrics.Stats), xerrors.New("method not supported") + return *new(map[protocol.ID]metrics.Stats), ErrNotSupported } func (s *NetStruct) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { + if s.Internal.NetBlockAdd == nil { + return ErrNotSupported + } return s.Internal.NetBlockAdd(p0, p1) } func (s *NetStub) NetBlockAdd(p0 context.Context, p1 NetBlockList) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *NetStruct) NetBlockList(p0 context.Context) (NetBlockList, error) { + if s.Internal.NetBlockList == nil { + return *new(NetBlockList), ErrNotSupported + } return s.Internal.NetBlockList(p0) } func (s *NetStub) NetBlockList(p0 context.Context) (NetBlockList, error) { - return *new(NetBlockList), xerrors.New("method not supported") + return *new(NetBlockList), ErrNotSupported } func (s *NetStruct) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { + if s.Internal.NetBlockRemove == nil { + return ErrNotSupported + } return s.Internal.NetBlockRemove(p0, p1) } func (s *NetStub) NetBlockRemove(p0 context.Context, p1 NetBlockList) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *NetStruct) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { + if s.Internal.NetConnect == nil { + return ErrNotSupported + } return s.Internal.NetConnect(p0, p1) } func (s *NetStub) NetConnect(p0 context.Context, p1 peer.AddrInfo) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *NetStruct) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { + if s.Internal.NetConnectedness == nil { + return *new(network.Connectedness), ErrNotSupported + } return s.Internal.NetConnectedness(p0, p1) } func (s *NetStub) NetConnectedness(p0 context.Context, p1 peer.ID) (network.Connectedness, error) { - return *new(network.Connectedness), xerrors.New("method not supported") + return *new(network.Connectedness), ErrNotSupported } func (s *NetStruct) NetDisconnect(p0 context.Context, p1 peer.ID) error { + if s.Internal.NetDisconnect == nil { + return ErrNotSupported + } return s.Internal.NetDisconnect(p0, p1) } func (s *NetStub) NetDisconnect(p0 context.Context, p1 peer.ID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *NetStruct) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { + if s.Internal.NetFindPeer == nil { + return *new(peer.AddrInfo), ErrNotSupported + } return s.Internal.NetFindPeer(p0, p1) } func (s *NetStub) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) { - return *new(peer.AddrInfo), xerrors.New("method not supported") + return *new(peer.AddrInfo), ErrNotSupported } func (s *NetStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { + if s.Internal.NetPeerInfo == nil { + return nil, ErrNotSupported + } return s.Internal.NetPeerInfo(p0, p1) } func (s *NetStub) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *NetStruct) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { + if s.Internal.NetPeers == nil { + return *new([]peer.AddrInfo), ErrNotSupported + } return s.Internal.NetPeers(p0) } func (s *NetStub) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) { - return *new([]peer.AddrInfo), xerrors.New("method not supported") + return *new([]peer.AddrInfo), ErrNotSupported } func (s *NetStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { + if s.Internal.NetPubsubScores == nil { + return *new([]PubsubScore), ErrNotSupported + } return s.Internal.NetPubsubScores(p0) } func (s *NetStub) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) { - return *new([]PubsubScore), xerrors.New("method not supported") + return *new([]PubsubScore), ErrNotSupported } func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error { + if s.Internal.Sign == nil { + return ErrNotSupported + } return s.Internal.Sign(p0, p1) } func (s *SignableStub) Sign(p0 context.Context, p1 SignFunc) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ActorAddress(p0 context.Context) (address.Address, error) { + if s.Internal.ActorAddress == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.ActorAddress(p0) } func (s *StorageMinerStub) ActorAddress(p0 context.Context) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *StorageMinerStruct) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { + if s.Internal.ActorAddressConfig == nil { + return *new(AddressConfig), ErrNotSupported + } return s.Internal.ActorAddressConfig(p0) } func (s *StorageMinerStub) ActorAddressConfig(p0 context.Context) (AddressConfig, error) { - return *new(AddressConfig), xerrors.New("method not supported") + return *new(AddressConfig), ErrNotSupported } func (s *StorageMinerStruct) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { + if s.Internal.ActorSectorSize == nil { + return *new(abi.SectorSize), ErrNotSupported + } return s.Internal.ActorSectorSize(p0, p1) } func (s *StorageMinerStub) ActorSectorSize(p0 context.Context, p1 address.Address) (abi.SectorSize, error) { - return *new(abi.SectorSize), xerrors.New("method not supported") + return *new(abi.SectorSize), ErrNotSupported } func (s *StorageMinerStruct) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { + if s.Internal.CheckProvable == nil { + return *new(map[abi.SectorNumber]string), ErrNotSupported + } return s.Internal.CheckProvable(p0, p1, p2, p3) } func (s *StorageMinerStub) CheckProvable(p0 context.Context, p1 abi.RegisteredPoStProof, p2 []storage.SectorRef, p3 bool) (map[abi.SectorNumber]string, error) { - return *new(map[abi.SectorNumber]string), xerrors.New("method not supported") + return *new(map[abi.SectorNumber]string), ErrNotSupported } func (s *StorageMinerStruct) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { + if s.Internal.ComputeProof == nil { + return *new([]builtin.PoStProof), ErrNotSupported + } return s.Internal.ComputeProof(p0, p1, p2) } func (s *StorageMinerStub) ComputeProof(p0 context.Context, p1 []builtin.SectorInfo, p2 abi.PoStRandomness) ([]builtin.PoStProof, error) { - return *new([]builtin.PoStProof), xerrors.New("method not supported") + return *new([]builtin.PoStProof), ErrNotSupported } func (s *StorageMinerStruct) CreateBackup(p0 context.Context, p1 string) error { + if s.Internal.CreateBackup == nil { + return ErrNotSupported + } return s.Internal.CreateBackup(p0, p1) } func (s *StorageMinerStub) CreateBackup(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderOfflineRetrievalDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderOfflineRetrievalDeals(p0) } func (s *StorageMinerStub) DealsConsiderOfflineRetrievalDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderOfflineStorageDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderOfflineStorageDeals(p0) } func (s *StorageMinerStub) DealsConsiderOfflineStorageDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderOnlineRetrievalDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderOnlineRetrievalDeals(p0) } func (s *StorageMinerStub) DealsConsiderOnlineRetrievalDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderOnlineStorageDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderOnlineStorageDeals(p0) } func (s *StorageMinerStub) DealsConsiderOnlineStorageDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderUnverifiedStorageDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderUnverifiedStorageDeals(p0) } func (s *StorageMinerStub) DealsConsiderUnverifiedStorageDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { + if s.Internal.DealsConsiderVerifiedStorageDeals == nil { + return false, ErrNotSupported + } return s.Internal.DealsConsiderVerifiedStorageDeals(p0) } func (s *StorageMinerStub) DealsConsiderVerifiedStorageDeals(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { + if s.Internal.DealsImportData == nil { + return ErrNotSupported + } return s.Internal.DealsImportData(p0, p1, p2) } func (s *StorageMinerStub) DealsImportData(p0 context.Context, p1 cid.Cid, p2 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsList(p0 context.Context) ([]MarketDeal, error) { + if s.Internal.DealsList == nil { + return *new([]MarketDeal), ErrNotSupported + } return s.Internal.DealsList(p0) } func (s *StorageMinerStub) DealsList(p0 context.Context) ([]MarketDeal, error) { - return *new([]MarketDeal), xerrors.New("method not supported") + return *new([]MarketDeal), ErrNotSupported } func (s *StorageMinerStruct) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { + if s.Internal.DealsPieceCidBlocklist == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.DealsPieceCidBlocklist(p0) } func (s *StorageMinerStub) DealsPieceCidBlocklist(p0 context.Context) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderOfflineRetrievalDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderOfflineRetrievalDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderOfflineRetrievalDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderOfflineStorageDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderOfflineStorageDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderOfflineStorageDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderOnlineRetrievalDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderOnlineRetrievalDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderOnlineRetrievalDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderOnlineStorageDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderOnlineStorageDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderOnlineStorageDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderUnverifiedStorageDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderUnverifiedStorageDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderUnverifiedStorageDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { + if s.Internal.DealsSetConsiderVerifiedStorageDeals == nil { + return ErrNotSupported + } return s.Internal.DealsSetConsiderVerifiedStorageDeals(p0, p1) } func (s *StorageMinerStub) DealsSetConsiderVerifiedStorageDeals(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { + if s.Internal.DealsSetPieceCidBlocklist == nil { + return ErrNotSupported + } return s.Internal.DealsSetPieceCidBlocklist(p0, p1) } func (s *StorageMinerStub) DealsSetPieceCidBlocklist(p0 context.Context, p1 []cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.MarketCancelDataTransfer == nil { + return ErrNotSupported + } return s.Internal.MarketCancelDataTransfer(p0, p1, p2, p3) } func (s *StorageMinerStub) MarketCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { + if s.Internal.MarketDataTransferUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.MarketDataTransferUpdates(p0) } func (s *StorageMinerStub) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { + if s.Internal.MarketGetAsk == nil { + return nil, ErrNotSupported + } return s.Internal.MarketGetAsk(p0) } func (s *StorageMinerStub) MarketGetAsk(p0 context.Context) (*storagemarket.SignedStorageAsk, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { + if s.Internal.MarketGetDealUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.MarketGetDealUpdates(p0) } func (s *StorageMinerStub) MarketGetDealUpdates(p0 context.Context) (<-chan storagemarket.MinerDeal, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { + if s.Internal.MarketGetRetrievalAsk == nil { + return nil, ErrNotSupported + } return s.Internal.MarketGetRetrievalAsk(p0) } func (s *StorageMinerStub) MarketGetRetrievalAsk(p0 context.Context) (*retrievalmarket.Ask, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { + if s.Internal.MarketImportDealData == nil { + return ErrNotSupported + } return s.Internal.MarketImportDealData(p0, p1, p2) } func (s *StorageMinerStub) MarketImportDealData(p0 context.Context, p1 cid.Cid, p2 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { + if s.Internal.MarketListDataTransfers == nil { + return *new([]DataTransferChannel), ErrNotSupported + } return s.Internal.MarketListDataTransfers(p0) } func (s *StorageMinerStub) MarketListDataTransfers(p0 context.Context) ([]DataTransferChannel, error) { - return *new([]DataTransferChannel), xerrors.New("method not supported") + return *new([]DataTransferChannel), ErrNotSupported } func (s *StorageMinerStruct) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { + if s.Internal.MarketListDeals == nil { + return *new([]MarketDeal), ErrNotSupported + } return s.Internal.MarketListDeals(p0) } func (s *StorageMinerStub) MarketListDeals(p0 context.Context) ([]MarketDeal, error) { - return *new([]MarketDeal), xerrors.New("method not supported") + return *new([]MarketDeal), ErrNotSupported } func (s *StorageMinerStruct) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { + if s.Internal.MarketListIncompleteDeals == nil { + return *new([]storagemarket.MinerDeal), ErrNotSupported + } return s.Internal.MarketListIncompleteDeals(p0) } func (s *StorageMinerStub) MarketListIncompleteDeals(p0 context.Context) ([]storagemarket.MinerDeal, error) { - return *new([]storagemarket.MinerDeal), xerrors.New("method not supported") + return *new([]storagemarket.MinerDeal), ErrNotSupported } func (s *StorageMinerStruct) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { + if s.Internal.MarketListRetrievalDeals == nil { + return *new([]retrievalmarket.ProviderDealState), ErrNotSupported + } return s.Internal.MarketListRetrievalDeals(p0) } func (s *StorageMinerStub) MarketListRetrievalDeals(p0 context.Context) ([]retrievalmarket.ProviderDealState, error) { - return *new([]retrievalmarket.ProviderDealState), xerrors.New("method not supported") + return *new([]retrievalmarket.ProviderDealState), ErrNotSupported } func (s *StorageMinerStruct) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { + if s.Internal.MarketPendingDeals == nil { + return *new(PendingDealInfo), ErrNotSupported + } return s.Internal.MarketPendingDeals(p0) } func (s *StorageMinerStub) MarketPendingDeals(p0 context.Context) (PendingDealInfo, error) { - return *new(PendingDealInfo), xerrors.New("method not supported") + return *new(PendingDealInfo), ErrNotSupported } func (s *StorageMinerStruct) MarketPublishPendingDeals(p0 context.Context) error { + if s.Internal.MarketPublishPendingDeals == nil { + return ErrNotSupported + } return s.Internal.MarketPublishPendingDeals(p0) } func (s *StorageMinerStub) MarketPublishPendingDeals(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.MarketRestartDataTransfer == nil { + return ErrNotSupported + } return s.Internal.MarketRestartDataTransfer(p0, p1, p2, p3) } func (s *StorageMinerStub) MarketRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { + if s.Internal.MarketSetAsk == nil { + return ErrNotSupported + } return s.Internal.MarketSetAsk(p0, p1, p2, p3, p4, p5) } func (s *StorageMinerStub) MarketSetAsk(p0 context.Context, p1 types.BigInt, p2 types.BigInt, p3 abi.ChainEpoch, p4 abi.PaddedPieceSize, p5 abi.PaddedPieceSize) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { + if s.Internal.MarketSetRetrievalAsk == nil { + return ErrNotSupported + } return s.Internal.MarketSetRetrievalAsk(p0, p1) } func (s *StorageMinerStub) MarketSetRetrievalAsk(p0 context.Context, p1 *retrievalmarket.Ask) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) MiningBase(p0 context.Context) (*types.TipSet, error) { + if s.Internal.MiningBase == nil { + return nil, ErrNotSupported + } return s.Internal.MiningBase(p0) } func (s *StorageMinerStub) MiningBase(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { + if s.Internal.PiecesGetCIDInfo == nil { + return nil, ErrNotSupported + } return s.Internal.PiecesGetCIDInfo(p0, p1) } func (s *StorageMinerStub) PiecesGetCIDInfo(p0 context.Context, p1 cid.Cid) (*piecestore.CIDInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { + if s.Internal.PiecesGetPieceInfo == nil { + return nil, ErrNotSupported + } return s.Internal.PiecesGetPieceInfo(p0, p1) } func (s *StorageMinerStub) PiecesGetPieceInfo(p0 context.Context, p1 cid.Cid) (*piecestore.PieceInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { + if s.Internal.PiecesListCidInfos == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.PiecesListCidInfos(p0) } func (s *StorageMinerStub) PiecesListCidInfos(p0 context.Context) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *StorageMinerStruct) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { + if s.Internal.PiecesListPieces == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.PiecesListPieces(p0) } func (s *StorageMinerStub) PiecesListPieces(p0 context.Context) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *StorageMinerStruct) PledgeSector(p0 context.Context) (abi.SectorID, error) { + if s.Internal.PledgeSector == nil { + return *new(abi.SectorID), ErrNotSupported + } return s.Internal.PledgeSector(p0) } func (s *StorageMinerStub) PledgeSector(p0 context.Context) (abi.SectorID, error) { - return *new(abi.SectorID), xerrors.New("method not supported") + return *new(abi.SectorID), ErrNotSupported } func (s *StorageMinerStruct) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { + if s.Internal.ReturnAddPiece == nil { + return ErrNotSupported + } return s.Internal.ReturnAddPiece(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnAddPiece(p0 context.Context, p1 storiface.CallID, p2 abi.PieceInfo, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + if s.Internal.ReturnFetch == nil { + return ErrNotSupported + } return s.Internal.ReturnFetch(p0, p1, p2) } func (s *StorageMinerStub) ReturnFetch(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + if s.Internal.ReturnFinalizeSector == nil { + return ErrNotSupported + } return s.Internal.ReturnFinalizeSector(p0, p1, p2) } func (s *StorageMinerStub) ReturnFinalizeSector(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + if s.Internal.ReturnMoveStorage == nil { + return ErrNotSupported + } return s.Internal.ReturnMoveStorage(p0, p1, p2) } func (s *StorageMinerStub) ReturnMoveStorage(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { + if s.Internal.ReturnReadPiece == nil { + return ErrNotSupported + } return s.Internal.ReturnReadPiece(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnReadPiece(p0 context.Context, p1 storiface.CallID, p2 bool, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + if s.Internal.ReturnReleaseUnsealed == nil { + return ErrNotSupported + } return s.Internal.ReturnReleaseUnsealed(p0, p1, p2) } func (s *StorageMinerStub) ReturnReleaseUnsealed(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { + if s.Internal.ReturnSealCommit1 == nil { + return ErrNotSupported + } return s.Internal.ReturnSealCommit1(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnSealCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.Commit1Out, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { + if s.Internal.ReturnSealCommit2 == nil { + return ErrNotSupported + } return s.Internal.ReturnSealCommit2(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnSealCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.Proof, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { + if s.Internal.ReturnSealPreCommit1 == nil { + return ErrNotSupported + } return s.Internal.ReturnSealPreCommit1(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnSealPreCommit1(p0 context.Context, p1 storiface.CallID, p2 storage.PreCommit1Out, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { + if s.Internal.ReturnSealPreCommit2 == nil { + return ErrNotSupported + } return s.Internal.ReturnSealPreCommit2(p0, p1, p2, p3) } func (s *StorageMinerStub) ReturnSealPreCommit2(p0 context.Context, p1 storiface.CallID, p2 storage.SectorCids, p3 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { + if s.Internal.ReturnUnsealPiece == nil { + return ErrNotSupported + } return s.Internal.ReturnUnsealPiece(p0, p1, p2) } func (s *StorageMinerStub) ReturnUnsealPiece(p0 context.Context, p1 storiface.CallID, p2 *storiface.CallError) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SealingAbort(p0 context.Context, p1 storiface.CallID) error { + if s.Internal.SealingAbort == nil { + return ErrNotSupported + } return s.Internal.SealingAbort(p0, p1) } func (s *StorageMinerStub) SealingAbort(p0 context.Context, p1 storiface.CallID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { + if s.Internal.SealingSchedDiag == nil { + return nil, ErrNotSupported + } return s.Internal.SealingSchedDiag(p0, p1) } func (s *StorageMinerStub) SealingSchedDiag(p0 context.Context, p1 bool) (interface{}, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) SectorAddPieceToAny(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) { + if s.Internal.SectorAddPieceToAny == nil { + return *new(SectorOffset), ErrNotSupported + } return s.Internal.SectorAddPieceToAny(p0, p1, p2, p3) } func (s *StorageMinerStub) SectorAddPieceToAny(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) { - return *new(SectorOffset), xerrors.New("method not supported") + return *new(SectorOffset), ErrNotSupported } func (s *StorageMinerStruct) SectorCommitFlush(p0 context.Context) ([]sealiface.CommitBatchRes, error) { + if s.Internal.SectorCommitFlush == nil { + return *new([]sealiface.CommitBatchRes), ErrNotSupported + } return s.Internal.SectorCommitFlush(p0) } func (s *StorageMinerStub) SectorCommitFlush(p0 context.Context) ([]sealiface.CommitBatchRes, error) { - return *new([]sealiface.CommitBatchRes), xerrors.New("method not supported") + return *new([]sealiface.CommitBatchRes), ErrNotSupported } func (s *StorageMinerStruct) SectorCommitPending(p0 context.Context) ([]abi.SectorID, error) { + if s.Internal.SectorCommitPending == nil { + return *new([]abi.SectorID), ErrNotSupported + } return s.Internal.SectorCommitPending(p0) } func (s *StorageMinerStub) SectorCommitPending(p0 context.Context) ([]abi.SectorID, error) { - return *new([]abi.SectorID), xerrors.New("method not supported") + return *new([]abi.SectorID), ErrNotSupported } func (s *StorageMinerStruct) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { + if s.Internal.SectorGetExpectedSealDuration == nil { + return *new(time.Duration), ErrNotSupported + } return s.Internal.SectorGetExpectedSealDuration(p0) } func (s *StorageMinerStub) SectorGetExpectedSealDuration(p0 context.Context) (time.Duration, error) { - return *new(time.Duration), xerrors.New("method not supported") + return *new(time.Duration), ErrNotSupported } func (s *StorageMinerStruct) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { + if s.Internal.SectorGetSealDelay == nil { + return *new(time.Duration), ErrNotSupported + } return s.Internal.SectorGetSealDelay(p0) } func (s *StorageMinerStub) SectorGetSealDelay(p0 context.Context) (time.Duration, error) { - return *new(time.Duration), xerrors.New("method not supported") + return *new(time.Duration), ErrNotSupported } func (s *StorageMinerStruct) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { + if s.Internal.SectorMarkForUpgrade == nil { + return ErrNotSupported + } return s.Internal.SectorMarkForUpgrade(p0, p1) } func (s *StorageMinerStub) SectorMarkForUpgrade(p0 context.Context, p1 abi.SectorNumber) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorPreCommitFlush(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) { + if s.Internal.SectorPreCommitFlush == nil { + return *new([]sealiface.PreCommitBatchRes), ErrNotSupported + } return s.Internal.SectorPreCommitFlush(p0) } func (s *StorageMinerStub) SectorPreCommitFlush(p0 context.Context) ([]sealiface.PreCommitBatchRes, error) { - return *new([]sealiface.PreCommitBatchRes), xerrors.New("method not supported") + return *new([]sealiface.PreCommitBatchRes), ErrNotSupported } func (s *StorageMinerStruct) SectorPreCommitPending(p0 context.Context) ([]abi.SectorID, error) { + if s.Internal.SectorPreCommitPending == nil { + return *new([]abi.SectorID), ErrNotSupported + } return s.Internal.SectorPreCommitPending(p0) } func (s *StorageMinerStub) SectorPreCommitPending(p0 context.Context) ([]abi.SectorID, error) { - return *new([]abi.SectorID), xerrors.New("method not supported") + return *new([]abi.SectorID), ErrNotSupported } func (s *StorageMinerStruct) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { + if s.Internal.SectorRemove == nil { + return ErrNotSupported + } return s.Internal.SectorRemove(p0, p1) } func (s *StorageMinerStub) SectorRemove(p0 context.Context, p1 abi.SectorNumber) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { + if s.Internal.SectorSetExpectedSealDuration == nil { + return ErrNotSupported + } return s.Internal.SectorSetExpectedSealDuration(p0, p1) } func (s *StorageMinerStub) SectorSetExpectedSealDuration(p0 context.Context, p1 time.Duration) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { + if s.Internal.SectorSetSealDelay == nil { + return ErrNotSupported + } return s.Internal.SectorSetSealDelay(p0, p1) } func (s *StorageMinerStub) SectorSetSealDelay(p0 context.Context, p1 time.Duration) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { + if s.Internal.SectorStartSealing == nil { + return ErrNotSupported + } return s.Internal.SectorStartSealing(p0, p1) } func (s *StorageMinerStub) SectorStartSealing(p0 context.Context, p1 abi.SectorNumber) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { + if s.Internal.SectorTerminate == nil { + return ErrNotSupported + } return s.Internal.SectorTerminate(p0, p1) } func (s *StorageMinerStub) SectorTerminate(p0 context.Context, p1 abi.SectorNumber) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { + if s.Internal.SectorTerminateFlush == nil { + return nil, ErrNotSupported + } return s.Internal.SectorTerminateFlush(p0) } func (s *StorageMinerStub) SectorTerminateFlush(p0 context.Context) (*cid.Cid, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *StorageMinerStruct) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { + if s.Internal.SectorTerminatePending == nil { + return *new([]abi.SectorID), ErrNotSupported + } return s.Internal.SectorTerminatePending(p0) } func (s *StorageMinerStub) SectorTerminatePending(p0 context.Context) ([]abi.SectorID, error) { - return *new([]abi.SectorID), xerrors.New("method not supported") + return *new([]abi.SectorID), ErrNotSupported } func (s *StorageMinerStruct) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { + if s.Internal.SectorsList == nil { + return *new([]abi.SectorNumber), ErrNotSupported + } return s.Internal.SectorsList(p0) } func (s *StorageMinerStub) SectorsList(p0 context.Context) ([]abi.SectorNumber, error) { - return *new([]abi.SectorNumber), xerrors.New("method not supported") + return *new([]abi.SectorNumber), ErrNotSupported } func (s *StorageMinerStruct) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { + if s.Internal.SectorsListInStates == nil { + return *new([]abi.SectorNumber), ErrNotSupported + } return s.Internal.SectorsListInStates(p0, p1) } func (s *StorageMinerStub) SectorsListInStates(p0 context.Context, p1 []SectorState) ([]abi.SectorNumber, error) { - return *new([]abi.SectorNumber), xerrors.New("method not supported") + return *new([]abi.SectorNumber), ErrNotSupported } func (s *StorageMinerStruct) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { + if s.Internal.SectorsRefs == nil { + return *new(map[string][]SealedRef), ErrNotSupported + } return s.Internal.SectorsRefs(p0) } func (s *StorageMinerStub) SectorsRefs(p0 context.Context) (map[string][]SealedRef, error) { - return *new(map[string][]SealedRef), xerrors.New("method not supported") + return *new(map[string][]SealedRef), ErrNotSupported } func (s *StorageMinerStruct) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { + if s.Internal.SectorsStatus == nil { + return *new(SectorInfo), ErrNotSupported + } return s.Internal.SectorsStatus(p0, p1, p2) } func (s *StorageMinerStub) SectorsStatus(p0 context.Context, p1 abi.SectorNumber, p2 bool) (SectorInfo, error) { - return *new(SectorInfo), xerrors.New("method not supported") + return *new(SectorInfo), ErrNotSupported } func (s *StorageMinerStruct) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { + if s.Internal.SectorsSummary == nil { + return *new(map[SectorState]int), ErrNotSupported + } return s.Internal.SectorsSummary(p0) } func (s *StorageMinerStub) SectorsSummary(p0 context.Context) (map[SectorState]int, error) { - return *new(map[SectorState]int), xerrors.New("method not supported") + return *new(map[SectorState]int), ErrNotSupported } func (s *StorageMinerStruct) SectorsUnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error { + if s.Internal.SectorsUnsealPiece == nil { + return ErrNotSupported + } return s.Internal.SectorsUnsealPiece(p0, p1, p2, p3, p4, p5) } func (s *StorageMinerStub) SectorsUnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 *cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { + if s.Internal.SectorsUpdate == nil { + return ErrNotSupported + } return s.Internal.SectorsUpdate(p0, p1, p2) } func (s *StorageMinerStub) SectorsUpdate(p0 context.Context, p1 abi.SectorNumber, p2 SectorState) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageAddLocal(p0 context.Context, p1 string) error { + if s.Internal.StorageAddLocal == nil { + return ErrNotSupported + } return s.Internal.StorageAddLocal(p0, p1) } func (s *StorageMinerStub) StorageAddLocal(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { + if s.Internal.StorageAttach == nil { + return ErrNotSupported + } return s.Internal.StorageAttach(p0, p1, p2) } func (s *StorageMinerStub) StorageAttach(p0 context.Context, p1 stores.StorageInfo, p2 fsutil.FsStat) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { + if s.Internal.StorageBestAlloc == nil { + return *new([]stores.StorageInfo), ErrNotSupported + } return s.Internal.StorageBestAlloc(p0, p1, p2, p3) } func (s *StorageMinerStub) StorageBestAlloc(p0 context.Context, p1 storiface.SectorFileType, p2 abi.SectorSize, p3 storiface.PathType) ([]stores.StorageInfo, error) { - return *new([]stores.StorageInfo), xerrors.New("method not supported") + return *new([]stores.StorageInfo), ErrNotSupported } func (s *StorageMinerStruct) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { + if s.Internal.StorageDeclareSector == nil { + return ErrNotSupported + } return s.Internal.StorageDeclareSector(p0, p1, p2, p3, p4) } func (s *StorageMinerStub) StorageDeclareSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType, p4 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { + if s.Internal.StorageDropSector == nil { + return ErrNotSupported + } return s.Internal.StorageDropSector(p0, p1, p2, p3) } func (s *StorageMinerStub) StorageDropSector(p0 context.Context, p1 stores.ID, p2 abi.SectorID, p3 storiface.SectorFileType) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { + if s.Internal.StorageFindSector == nil { + return *new([]stores.SectorStorageInfo), ErrNotSupported + } return s.Internal.StorageFindSector(p0, p1, p2, p3, p4) } func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) { - return *new([]stores.SectorStorageInfo), xerrors.New("method not supported") + return *new([]stores.SectorStorageInfo), ErrNotSupported } func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { + if s.Internal.StorageInfo == nil { + return *new(stores.StorageInfo), ErrNotSupported + } return s.Internal.StorageInfo(p0, p1) } func (s *StorageMinerStub) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) { - return *new(stores.StorageInfo), xerrors.New("method not supported") + return *new(stores.StorageInfo), ErrNotSupported } func (s *StorageMinerStruct) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { + if s.Internal.StorageList == nil { + return *new(map[stores.ID][]stores.Decl), ErrNotSupported + } return s.Internal.StorageList(p0) } func (s *StorageMinerStub) StorageList(p0 context.Context) (map[stores.ID][]stores.Decl, error) { - return *new(map[stores.ID][]stores.Decl), xerrors.New("method not supported") + return *new(map[stores.ID][]stores.Decl), ErrNotSupported } func (s *StorageMinerStruct) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { + if s.Internal.StorageLocal == nil { + return *new(map[stores.ID]string), ErrNotSupported + } return s.Internal.StorageLocal(p0) } func (s *StorageMinerStub) StorageLocal(p0 context.Context) (map[stores.ID]string, error) { - return *new(map[stores.ID]string), xerrors.New("method not supported") + return *new(map[stores.ID]string), ErrNotSupported } func (s *StorageMinerStruct) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { + if s.Internal.StorageLock == nil { + return ErrNotSupported + } return s.Internal.StorageLock(p0, p1, p2, p3) } func (s *StorageMinerStub) StorageLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { + if s.Internal.StorageReportHealth == nil { + return ErrNotSupported + } return s.Internal.StorageReportHealth(p0, p1, p2) } func (s *StorageMinerStub) StorageReportHealth(p0 context.Context, p1 stores.ID, p2 stores.HealthReport) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { + if s.Internal.StorageStat == nil { + return *new(fsutil.FsStat), ErrNotSupported + } return s.Internal.StorageStat(p0, p1) } func (s *StorageMinerStub) StorageStat(p0 context.Context, p1 stores.ID) (fsutil.FsStat, error) { - return *new(fsutil.FsStat), xerrors.New("method not supported") + return *new(fsutil.FsStat), ErrNotSupported } func (s *StorageMinerStruct) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { + if s.Internal.StorageTryLock == nil { + return false, ErrNotSupported + } return s.Internal.StorageTryLock(p0, p1, p2, p3) } func (s *StorageMinerStub) StorageTryLock(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error { + if s.Internal.WorkerConnect == nil { + return ErrNotSupported + } return s.Internal.WorkerConnect(p0, p1) } func (s *StorageMinerStub) WorkerConnect(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *StorageMinerStruct) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { + if s.Internal.WorkerJobs == nil { + return *new(map[uuid.UUID][]storiface.WorkerJob), ErrNotSupported + } return s.Internal.WorkerJobs(p0) } func (s *StorageMinerStub) WorkerJobs(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) { - return *new(map[uuid.UUID][]storiface.WorkerJob), xerrors.New("method not supported") + return *new(map[uuid.UUID][]storiface.WorkerJob), ErrNotSupported } func (s *StorageMinerStruct) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { + if s.Internal.WorkerStats == nil { + return *new(map[uuid.UUID]storiface.WorkerStats), ErrNotSupported + } return s.Internal.WorkerStats(p0) } func (s *StorageMinerStub) WorkerStats(p0 context.Context) (map[uuid.UUID]storiface.WorkerStats, error) { - return *new(map[uuid.UUID]storiface.WorkerStats), xerrors.New("method not supported") + return *new(map[uuid.UUID]storiface.WorkerStats), ErrNotSupported } func (s *WalletStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + if s.Internal.WalletDelete == nil { + return ErrNotSupported + } return s.Internal.WalletDelete(p0, p1) } func (s *WalletStub) WalletDelete(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WalletStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + if s.Internal.WalletExport == nil { + return nil, ErrNotSupported + } return s.Internal.WalletExport(p0, p1) } func (s *WalletStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *WalletStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + if s.Internal.WalletHas == nil { + return false, ErrNotSupported + } return s.Internal.WalletHas(p0, p1) } func (s *WalletStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *WalletStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + if s.Internal.WalletImport == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletImport(p0, p1) } func (s *WalletStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *WalletStruct) WalletList(p0 context.Context) ([]address.Address, error) { + if s.Internal.WalletList == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.WalletList(p0) } func (s *WalletStub) WalletList(p0 context.Context) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *WalletStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + if s.Internal.WalletNew == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletNew(p0, p1) } func (s *WalletStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *WalletStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { + if s.Internal.WalletSign == nil { + return nil, ErrNotSupported + } return s.Internal.WalletSign(p0, p1, p2, p3) } func (s *WalletStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte, p3 MsgMeta) (*crypto.Signature, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *WorkerStruct) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { + if s.Internal.AddPiece == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.AddPiece(p0, p1, p2, p3, p4) } func (s *WorkerStub) AddPiece(p0 context.Context, p1 storage.SectorRef, p2 []abi.UnpaddedPieceSize, p3 abi.UnpaddedPieceSize, p4 storage.Data) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Enabled(p0 context.Context) (bool, error) { + if s.Internal.Enabled == nil { + return false, ErrNotSupported + } return s.Internal.Enabled(p0) } func (s *WorkerStub) Enabled(p0 context.Context) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *WorkerStruct) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { + if s.Internal.Fetch == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.Fetch(p0, p1, p2, p3, p4) } func (s *WorkerStub) Fetch(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType, p3 storiface.PathType, p4 storiface.AcquireMode) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + if s.Internal.FinalizeSector == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.FinalizeSector(p0, p1, p2) } func (s *WorkerStub) FinalizeSector(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Info(p0 context.Context) (storiface.WorkerInfo, error) { + if s.Internal.Info == nil { + return *new(storiface.WorkerInfo), ErrNotSupported + } return s.Internal.Info(p0) } func (s *WorkerStub) Info(p0 context.Context) (storiface.WorkerInfo, error) { - return *new(storiface.WorkerInfo), xerrors.New("method not supported") + return *new(storiface.WorkerInfo), ErrNotSupported } func (s *WorkerStruct) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { + if s.Internal.MoveStorage == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.MoveStorage(p0, p1, p2) } func (s *WorkerStub) MoveStorage(p0 context.Context, p1 storage.SectorRef, p2 storiface.SectorFileType) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Paths(p0 context.Context) ([]stores.StoragePath, error) { + if s.Internal.Paths == nil { + return *new([]stores.StoragePath), ErrNotSupported + } return s.Internal.Paths(p0) } func (s *WorkerStub) Paths(p0 context.Context) ([]stores.StoragePath, error) { - return *new([]stores.StoragePath), xerrors.New("method not supported") + return *new([]stores.StoragePath), ErrNotSupported } func (s *WorkerStruct) ProcessSession(p0 context.Context) (uuid.UUID, error) { + if s.Internal.ProcessSession == nil { + return *new(uuid.UUID), ErrNotSupported + } return s.Internal.ProcessSession(p0) } func (s *WorkerStub) ProcessSession(p0 context.Context) (uuid.UUID, error) { - return *new(uuid.UUID), xerrors.New("method not supported") + return *new(uuid.UUID), ErrNotSupported } func (s *WorkerStruct) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { + if s.Internal.ReleaseUnsealed == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.ReleaseUnsealed(p0, p1, p2) } func (s *WorkerStub) ReleaseUnsealed(p0 context.Context, p1 storage.SectorRef, p2 []storage.Range) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Remove(p0 context.Context, p1 abi.SectorID) error { + if s.Internal.Remove == nil { + return ErrNotSupported + } return s.Internal.Remove(p0, p1) } func (s *WorkerStub) Remove(p0 context.Context, p1 abi.SectorID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WorkerStruct) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { + if s.Internal.SealCommit1 == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.SealCommit1(p0, p1, p2, p3, p4, p5) } func (s *WorkerStub) SealCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 abi.InteractiveSealRandomness, p4 []abi.PieceInfo, p5 storage.SectorCids) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { + if s.Internal.SealCommit2 == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.SealCommit2(p0, p1, p2) } func (s *WorkerStub) SealCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.Commit1Out) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { + if s.Internal.SealPreCommit1 == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.SealPreCommit1(p0, p1, p2, p3) } func (s *WorkerStub) SealPreCommit1(p0 context.Context, p1 storage.SectorRef, p2 abi.SealRandomness, p3 []abi.PieceInfo) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { + if s.Internal.SealPreCommit2 == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.SealPreCommit2(p0, p1, p2) } func (s *WorkerStub) SealPreCommit2(p0 context.Context, p1 storage.SectorRef, p2 storage.PreCommit1Out) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Session(p0 context.Context) (uuid.UUID, error) { + if s.Internal.Session == nil { + return *new(uuid.UUID), ErrNotSupported + } return s.Internal.Session(p0) } func (s *WorkerStub) Session(p0 context.Context) (uuid.UUID, error) { - return *new(uuid.UUID), xerrors.New("method not supported") + return *new(uuid.UUID), ErrNotSupported } func (s *WorkerStruct) SetEnabled(p0 context.Context, p1 bool) error { + if s.Internal.SetEnabled == nil { + return ErrNotSupported + } return s.Internal.SetEnabled(p0, p1) } func (s *WorkerStub) SetEnabled(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WorkerStruct) StorageAddLocal(p0 context.Context, p1 string) error { + if s.Internal.StorageAddLocal == nil { + return ErrNotSupported + } return s.Internal.StorageAddLocal(p0, p1) } func (s *WorkerStub) StorageAddLocal(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WorkerStruct) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { + if s.Internal.TaskDisable == nil { + return ErrNotSupported + } return s.Internal.TaskDisable(p0, p1) } func (s *WorkerStub) TaskDisable(p0 context.Context, p1 sealtasks.TaskType) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WorkerStruct) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { + if s.Internal.TaskEnable == nil { + return ErrNotSupported + } return s.Internal.TaskEnable(p0, p1) } func (s *WorkerStub) TaskEnable(p0 context.Context, p1 sealtasks.TaskType) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *WorkerStruct) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { + if s.Internal.TaskTypes == nil { + return *new(map[sealtasks.TaskType]struct{}), ErrNotSupported + } return s.Internal.TaskTypes(p0) } func (s *WorkerStub) TaskTypes(p0 context.Context) (map[sealtasks.TaskType]struct{}, error) { - return *new(map[sealtasks.TaskType]struct{}), xerrors.New("method not supported") + return *new(map[sealtasks.TaskType]struct{}), ErrNotSupported } func (s *WorkerStruct) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { + if s.Internal.UnsealPiece == nil { + return *new(storiface.CallID), ErrNotSupported + } return s.Internal.UnsealPiece(p0, p1, p2, p3, p4, p5) } func (s *WorkerStub) UnsealPiece(p0 context.Context, p1 storage.SectorRef, p2 storiface.UnpaddedByteIndex, p3 abi.UnpaddedPieceSize, p4 abi.SealRandomness, p5 cid.Cid) (storiface.CallID, error) { - return *new(storiface.CallID), xerrors.New("method not supported") + return *new(storiface.CallID), ErrNotSupported } func (s *WorkerStruct) Version(p0 context.Context) (Version, error) { + if s.Internal.Version == nil { + return *new(Version), ErrNotSupported + } return s.Internal.Version(p0) } func (s *WorkerStub) Version(p0 context.Context) (Version, error) { - return *new(Version), xerrors.New("method not supported") + return *new(Version), ErrNotSupported } func (s *WorkerStruct) WaitQuiet(p0 context.Context) error { + if s.Internal.WaitQuiet == nil { + return ErrNotSupported + } return s.Internal.WaitQuiet(p0) } func (s *WorkerStub) WaitQuiet(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } var _ ChainIO = new(ChainIOStruct) diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go index 4cb96b53e..21b751ca2 100644 --- a/api/v0api/proxy_gen.go +++ b/api/v0api/proxy_gen.go @@ -27,6 +27,8 @@ import ( "golang.org/x/xerrors" ) +var ErrNotSupported = xerrors.New("method not supported") + type FullNodeStruct struct { CommonStruct @@ -465,1667 +467,2291 @@ type GatewayStub struct { } func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { + if s.Internal.BeaconGetEntry == nil { + return nil, ErrNotSupported + } return s.Internal.BeaconGetEntry(p0, p1) } func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { + if s.Internal.ChainDeleteObj == nil { + return ErrNotSupported + } return s.Internal.ChainDeleteObj(p0, p1) } func (s *FullNodeStub) ChainDeleteObj(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { + if s.Internal.ChainExport == nil { + return nil, ErrNotSupported + } return s.Internal.ChainExport(p0, p1, p2, p3) } func (s *FullNodeStub) ChainExport(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { + if s.Internal.ChainGetBlock == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlock(p0, p1) } func (s *FullNodeStub) ChainGetBlock(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + if s.Internal.ChainGetBlockMessages == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlockMessages(p0, p1) } func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainGetGenesis == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetGenesis(p0) } func (s *FullNodeStub) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + if s.Internal.ChainGetMessage == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetMessage(p0, p1) } func (s *FullNodeStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) { + if s.Internal.ChainGetMessagesInTipset == nil { + return *new([]api.Message), ErrNotSupported + } return s.Internal.ChainGetMessagesInTipset(p0, p1) } func (s *FullNodeStub) ChainGetMessagesInTipset(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) { - return *new([]api.Message), xerrors.New("method not supported") + return *new([]api.Message), ErrNotSupported } func (s *FullNodeStruct) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { + if s.Internal.ChainGetNode == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetNode(p0, p1) } func (s *FullNodeStub) ChainGetNode(p0 context.Context, p1 string) (*api.IpldObject, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { + if s.Internal.ChainGetParentMessages == nil { + return *new([]api.Message), ErrNotSupported + } return s.Internal.ChainGetParentMessages(p0, p1) } func (s *FullNodeStub) ChainGetParentMessages(p0 context.Context, p1 cid.Cid) ([]api.Message, error) { - return *new([]api.Message), xerrors.New("method not supported") + return *new([]api.Message), ErrNotSupported } func (s *FullNodeStruct) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { + if s.Internal.ChainGetParentReceipts == nil { + return *new([]*types.MessageReceipt), ErrNotSupported + } return s.Internal.ChainGetParentReceipts(p0, p1) } func (s *FullNodeStub) ChainGetParentReceipts(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) { - return *new([]*types.MessageReceipt), xerrors.New("method not supported") + return *new([]*types.MessageReceipt), ErrNotSupported } func (s *FullNodeStruct) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { + if s.Internal.ChainGetPath == nil { + return *new([]*api.HeadChange), ErrNotSupported + } return s.Internal.ChainGetPath(p0, p1, p2) } func (s *FullNodeStub) ChainGetPath(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) { - return *new([]*api.HeadChange), xerrors.New("method not supported") + return *new([]*api.HeadChange), ErrNotSupported } func (s *FullNodeStruct) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + if s.Internal.ChainGetRandomnessFromBeacon == nil { + return *new(abi.Randomness), ErrNotSupported + } return s.Internal.ChainGetRandomnessFromBeacon(p0, p1, p2, p3, p4) } func (s *FullNodeStub) ChainGetRandomnessFromBeacon(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return *new(abi.Randomness), xerrors.New("method not supported") + return *new(abi.Randomness), ErrNotSupported } func (s *FullNodeStruct) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { + if s.Internal.ChainGetRandomnessFromTickets == nil { + return *new(abi.Randomness), ErrNotSupported + } return s.Internal.ChainGetRandomnessFromTickets(p0, p1, p2, p3, p4) } func (s *FullNodeStub) ChainGetRandomnessFromTickets(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) { - return *new(abi.Randomness), xerrors.New("method not supported") + return *new(abi.Randomness), ErrNotSupported } func (s *FullNodeStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSet == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSet(p0, p1) } func (s *FullNodeStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSetByHeight == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } func (s *FullNodeStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ChainHasObj == nil { + return false, ErrNotSupported + } return s.Internal.ChainHasObj(p0, p1) } func (s *FullNodeStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainHead == nil { + return nil, ErrNotSupported + } return s.Internal.ChainHead(p0) } func (s *FullNodeStub) ChainHead(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + if s.Internal.ChainNotify == nil { + return nil, ErrNotSupported + } return s.Internal.ChainNotify(p0) } func (s *FullNodeStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + if s.Internal.ChainReadObj == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.ChainReadObj(p0, p1) } func (s *FullNodeStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *FullNodeStruct) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { + if s.Internal.ChainSetHead == nil { + return ErrNotSupported + } return s.Internal.ChainSetHead(p0, p1) } func (s *FullNodeStub) ChainSetHead(p0 context.Context, p1 types.TipSetKey) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { + if s.Internal.ChainStatObj == nil { + return *new(api.ObjStat), ErrNotSupported + } return s.Internal.ChainStatObj(p0, p1, p2) } func (s *FullNodeStub) ChainStatObj(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) { - return *new(api.ObjStat), xerrors.New("method not supported") + return *new(api.ObjStat), ErrNotSupported } func (s *FullNodeStruct) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { + if s.Internal.ChainTipSetWeight == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.ChainTipSetWeight(p0, p1) } func (s *FullNodeStub) ChainTipSetWeight(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { + if s.Internal.ClientCalcCommP == nil { + return nil, ErrNotSupported + } return s.Internal.ClientCalcCommP(p0, p1) } func (s *FullNodeStub) ClientCalcCommP(p0 context.Context, p1 string) (*api.CommPRet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.ClientCancelDataTransfer == nil { + return ErrNotSupported + } return s.Internal.ClientCancelDataTransfer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientCancelDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { + if s.Internal.ClientCancelRetrievalDeal == nil { + return ErrNotSupported + } return s.Internal.ClientCancelRetrievalDeal(p0, p1) } func (s *FullNodeStub) ClientCancelRetrievalDeal(p0 context.Context, p1 retrievalmarket.DealID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { + if s.Internal.ClientDataTransferUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientDataTransferUpdates(p0) } func (s *FullNodeStub) ClientDataTransferUpdates(p0 context.Context) (<-chan api.DataTransferChannel, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { + if s.Internal.ClientDealPieceCID == nil { + return *new(api.DataCIDSize), ErrNotSupported + } return s.Internal.ClientDealPieceCID(p0, p1) } func (s *FullNodeStub) ClientDealPieceCID(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) { - return *new(api.DataCIDSize), xerrors.New("method not supported") + return *new(api.DataCIDSize), ErrNotSupported } func (s *FullNodeStruct) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { + if s.Internal.ClientDealSize == nil { + return *new(api.DataSize), ErrNotSupported + } return s.Internal.ClientDealSize(p0, p1) } func (s *FullNodeStub) ClientDealSize(p0 context.Context, p1 cid.Cid) (api.DataSize, error) { - return *new(api.DataSize), xerrors.New("method not supported") + return *new(api.DataSize), ErrNotSupported } func (s *FullNodeStruct) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { + if s.Internal.ClientFindData == nil { + return *new([]api.QueryOffer), ErrNotSupported + } return s.Internal.ClientFindData(p0, p1, p2) } func (s *FullNodeStub) ClientFindData(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) { - return *new([]api.QueryOffer), xerrors.New("method not supported") + return *new([]api.QueryOffer), ErrNotSupported } func (s *FullNodeStruct) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { + if s.Internal.ClientGenCar == nil { + return ErrNotSupported + } return s.Internal.ClientGenCar(p0, p1, p2) } func (s *FullNodeStub) ClientGenCar(p0 context.Context, p1 api.FileRef, p2 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { + if s.Internal.ClientGetDealInfo == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetDealInfo(p0, p1) } func (s *FullNodeStub) ClientGetDealInfo(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { + if s.Internal.ClientGetDealStatus == nil { + return "", ErrNotSupported + } return s.Internal.ClientGetDealStatus(p0, p1) } func (s *FullNodeStub) ClientGetDealStatus(p0 context.Context, p1 uint64) (string, error) { - return "", xerrors.New("method not supported") + return "", ErrNotSupported } func (s *FullNodeStruct) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { + if s.Internal.ClientGetDealUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetDealUpdates(p0) } func (s *FullNodeStub) ClientGetDealUpdates(p0 context.Context) (<-chan api.DealInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) { + if s.Internal.ClientGetRetrievalUpdates == nil { + return nil, ErrNotSupported + } return s.Internal.ClientGetRetrievalUpdates(p0) } func (s *FullNodeStub) ClientGetRetrievalUpdates(p0 context.Context) (<-chan api.RetrievalInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ClientHasLocal == nil { + return false, ErrNotSupported + } return s.Internal.ClientHasLocal(p0, p1) } func (s *FullNodeStub) ClientHasLocal(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { + if s.Internal.ClientImport == nil { + return nil, ErrNotSupported + } return s.Internal.ClientImport(p0, p1) } func (s *FullNodeStub) ClientImport(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { + if s.Internal.ClientListDataTransfers == nil { + return *new([]api.DataTransferChannel), ErrNotSupported + } return s.Internal.ClientListDataTransfers(p0) } func (s *FullNodeStub) ClientListDataTransfers(p0 context.Context) ([]api.DataTransferChannel, error) { - return *new([]api.DataTransferChannel), xerrors.New("method not supported") + return *new([]api.DataTransferChannel), ErrNotSupported } func (s *FullNodeStruct) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { + if s.Internal.ClientListDeals == nil { + return *new([]api.DealInfo), ErrNotSupported + } return s.Internal.ClientListDeals(p0) } func (s *FullNodeStub) ClientListDeals(p0 context.Context) ([]api.DealInfo, error) { - return *new([]api.DealInfo), xerrors.New("method not supported") + return *new([]api.DealInfo), ErrNotSupported } func (s *FullNodeStruct) ClientListImports(p0 context.Context) ([]api.Import, error) { + if s.Internal.ClientListImports == nil { + return *new([]api.Import), ErrNotSupported + } return s.Internal.ClientListImports(p0) } func (s *FullNodeStub) ClientListImports(p0 context.Context) ([]api.Import, error) { - return *new([]api.Import), xerrors.New("method not supported") + return *new([]api.Import), ErrNotSupported } func (s *FullNodeStruct) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { + if s.Internal.ClientListRetrievals == nil { + return *new([]api.RetrievalInfo), ErrNotSupported + } return s.Internal.ClientListRetrievals(p0) } func (s *FullNodeStub) ClientListRetrievals(p0 context.Context) ([]api.RetrievalInfo, error) { - return *new([]api.RetrievalInfo), xerrors.New("method not supported") + return *new([]api.RetrievalInfo), ErrNotSupported } func (s *FullNodeStruct) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { + if s.Internal.ClientMinerQueryOffer == nil { + return *new(api.QueryOffer), ErrNotSupported + } return s.Internal.ClientMinerQueryOffer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientMinerQueryOffer(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) { - return *new(api.QueryOffer), xerrors.New("method not supported") + return *new(api.QueryOffer), ErrNotSupported } func (s *FullNodeStruct) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { + if s.Internal.ClientQueryAsk == nil { + return nil, ErrNotSupported + } return s.Internal.ClientQueryAsk(p0, p1, p2) } func (s *FullNodeStub) ClientQueryAsk(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { + if s.Internal.ClientRemoveImport == nil { + return ErrNotSupported + } return s.Internal.ClientRemoveImport(p0, p1) } func (s *FullNodeStub) ClientRemoveImport(p0 context.Context, p1 multistore.StoreID) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { + if s.Internal.ClientRestartDataTransfer == nil { + return ErrNotSupported + } return s.Internal.ClientRestartDataTransfer(p0, p1, p2, p3) } func (s *FullNodeStub) ClientRestartDataTransfer(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { + if s.Internal.ClientRetrieve == nil { + return ErrNotSupported + } return s.Internal.ClientRetrieve(p0, p1, p2) } func (s *FullNodeStub) ClientRetrieve(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { + if s.Internal.ClientRetrieveTryRestartInsufficientFunds == nil { + return ErrNotSupported + } return s.Internal.ClientRetrieveTryRestartInsufficientFunds(p0, p1) } func (s *FullNodeStub) ClientRetrieveTryRestartInsufficientFunds(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { + if s.Internal.ClientRetrieveWithEvents == nil { + return nil, ErrNotSupported + } return s.Internal.ClientRetrieveWithEvents(p0, p1, p2) } func (s *FullNodeStub) ClientRetrieveWithEvents(p0 context.Context, p1 api.RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { + if s.Internal.ClientStartDeal == nil { + return nil, ErrNotSupported + } return s.Internal.ClientStartDeal(p0, p1) } func (s *FullNodeStub) ClientStartDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) ClientStatelessDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { + if s.Internal.ClientStatelessDeal == nil { + return nil, ErrNotSupported + } return s.Internal.ClientStatelessDeal(p0, p1) } func (s *FullNodeStub) ClientStatelessDeal(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) CreateBackup(p0 context.Context, p1 string) error { + if s.Internal.CreateBackup == nil { + return ErrNotSupported + } return s.Internal.CreateBackup(p0, p1) } func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.GasEstimateFeeCap == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.GasEstimateFeeCap(p0, p1, p2, p3) } func (s *FullNodeStub) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { + if s.Internal.GasEstimateGasLimit == nil { + return 0, ErrNotSupported + } return s.Internal.GasEstimateGasLimit(p0, p1, p2) } func (s *FullNodeStub) GasEstimateGasLimit(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { + if s.Internal.GasEstimateGasPremium == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.GasEstimateGasPremium(p0, p1, p2, p3, p4) } func (s *FullNodeStub) GasEstimateGasPremium(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + if s.Internal.GasEstimateMessageGas == nil { + return nil, ErrNotSupported + } return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } func (s *FullNodeStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketAddBalance == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketAddBalance(p0, p1, p2, p3) } func (s *FullNodeStub) MarketAddBalance(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.MarketGetReserved == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MarketGetReserved(p0, p1) } func (s *FullNodeStub) MarketGetReserved(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { + if s.Internal.MarketReleaseFunds == nil { + return ErrNotSupported + } return s.Internal.MarketReleaseFunds(p0, p1, p2) } func (s *FullNodeStub) MarketReleaseFunds(p0 context.Context, p1 address.Address, p2 types.BigInt) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketReserveFunds == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketReserveFunds(p0, p1, p2, p3) } func (s *FullNodeStub) MarketReserveFunds(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { + if s.Internal.MarketWithdraw == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MarketWithdraw(p0, p1, p2, p3) } func (s *FullNodeStub) MarketWithdraw(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { + if s.Internal.MinerCreateBlock == nil { + return nil, ErrNotSupported + } return s.Internal.MinerCreateBlock(p0, p1) } func (s *FullNodeStub) MinerCreateBlock(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { + if s.Internal.MinerGetBaseInfo == nil { + return nil, ErrNotSupported + } return s.Internal.MinerGetBaseInfo(p0, p1, p2, p3) } func (s *FullNodeStub) MinerGetBaseInfo(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + if s.Internal.MpoolBatchPush == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.MpoolBatchPush(p0, p1) } func (s *FullNodeStub) MpoolBatchPush(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { + if s.Internal.MpoolBatchPushMessage == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolBatchPushMessage(p0, p1, p2) } func (s *FullNodeStub) MpoolBatchPushMessage(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { + if s.Internal.MpoolBatchPushUntrusted == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.MpoolBatchPushUntrusted(p0, p1) } func (s *FullNodeStub) MpoolBatchPushUntrusted(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolClear(p0 context.Context, p1 bool) error { + if s.Internal.MpoolClear == nil { + return ErrNotSupported + } return s.Internal.MpoolClear(p0, p1) } func (s *FullNodeStub) MpoolClear(p0 context.Context, p1 bool) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { + if s.Internal.MpoolGetConfig == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolGetConfig(p0) } func (s *FullNodeStub) MpoolGetConfig(p0 context.Context) (*types.MpoolConfig, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { + if s.Internal.MpoolGetNonce == nil { + return 0, ErrNotSupported + } return s.Internal.MpoolGetNonce(p0, p1) } func (s *FullNodeStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { + if s.Internal.MpoolPending == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolPending(p0, p1) } func (s *FullNodeStub) MpoolPending(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPush == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPush(p0, p1) } func (s *FullNodeStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { + if s.Internal.MpoolPushMessage == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolPushMessage(p0, p1, p2) } func (s *FullNodeStub) MpoolPushMessage(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPushUntrusted == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPushUntrusted(p0, p1) } func (s *FullNodeStub) MpoolPushUntrusted(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { + if s.Internal.MpoolSelect == nil { + return *new([]*types.SignedMessage), ErrNotSupported + } return s.Internal.MpoolSelect(p0, p1, p2) } func (s *FullNodeStub) MpoolSelect(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) { - return *new([]*types.SignedMessage), xerrors.New("method not supported") + return *new([]*types.SignedMessage), ErrNotSupported } func (s *FullNodeStruct) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { + if s.Internal.MpoolSetConfig == nil { + return ErrNotSupported + } return s.Internal.MpoolSetConfig(p0, p1) } func (s *FullNodeStub) MpoolSetConfig(p0 context.Context, p1 *types.MpoolConfig) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { + if s.Internal.MpoolSub == nil { + return nil, ErrNotSupported + } return s.Internal.MpoolSub(p0) } func (s *FullNodeStub) MpoolSub(p0 context.Context) (<-chan api.MpoolUpdate, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { + if s.Internal.MsigAddApprove == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigAddApprove(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigAddApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { + if s.Internal.MsigAddCancel == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigAddCancel(p0, p1, p2, p3, p4, p5) } func (s *FullNodeStub) MsigAddCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + if s.Internal.MsigAddPropose == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigAddPropose(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigAddPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { + if s.Internal.MsigApprove == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigApprove(p0, p1, p2, p3) } func (s *FullNodeStub) MsigApprove(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { + if s.Internal.MsigApproveTxnHash == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigApproveTxnHash(p0, p1, p2, p3, p4, p5, p6, p7, p8) } func (s *FullNodeStub) MsigApproveTxnHash(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { + if s.Internal.MsigCancel == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigCancel(p0, p1, p2, p3, p4, p5, p6, p7) } func (s *FullNodeStub) MsigCancel(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { + if s.Internal.MsigCreate == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigCreate(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigCreate(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } func (s *FullNodeStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + if s.Internal.MsigGetPending == nil { + return *new([]*api.MsigTransaction), ErrNotSupported + } return s.Internal.MsigGetPending(p0, p1, p2) } func (s *FullNodeStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { - return *new([]*api.MsigTransaction), xerrors.New("method not supported") + return *new([]*api.MsigTransaction), ErrNotSupported } func (s *FullNodeStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetVested == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetVested(p0, p1, p2, p3) } func (s *FullNodeStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { + if s.Internal.MsigGetVestingSchedule == nil { + return *new(api.MsigVesting), ErrNotSupported + } return s.Internal.MsigGetVestingSchedule(p0, p1, p2) } func (s *FullNodeStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) { - return *new(api.MsigVesting), xerrors.New("method not supported") + return *new(api.MsigVesting), ErrNotSupported } func (s *FullNodeStruct) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { + if s.Internal.MsigPropose == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigPropose(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { + if s.Internal.MsigRemoveSigner == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigRemoveSigner(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigRemoveSigner(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { + if s.Internal.MsigSwapApprove == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigSwapApprove(p0, p1, p2, p3, p4, p5, p6) } func (s *FullNodeStub) MsigSwapApprove(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { + if s.Internal.MsigSwapCancel == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigSwapCancel(p0, p1, p2, p3, p4, p5) } func (s *FullNodeStub) MsigSwapCancel(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { + if s.Internal.MsigSwapPropose == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MsigSwapPropose(p0, p1, p2, p3, p4) } func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { + if s.Internal.PaychAllocateLane == nil { + return 0, ErrNotSupported + } return s.Internal.PaychAllocateLane(p0, p1) } func (s *FullNodeStub) PaychAllocateLane(p0 context.Context, p1 address.Address) (uint64, error) { - return 0, xerrors.New("method not supported") + return 0, ErrNotSupported } func (s *FullNodeStruct) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { + if s.Internal.PaychAvailableFunds == nil { + return nil, ErrNotSupported + } return s.Internal.PaychAvailableFunds(p0, p1) } func (s *FullNodeStub) PaychAvailableFunds(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { + if s.Internal.PaychAvailableFundsByFromTo == nil { + return nil, ErrNotSupported + } return s.Internal.PaychAvailableFundsByFromTo(p0, p1, p2) } func (s *FullNodeStub) PaychAvailableFundsByFromTo(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { + if s.Internal.PaychCollect == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychCollect(p0, p1) } func (s *FullNodeStub) PaychCollect(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { + if s.Internal.PaychGet == nil { + return nil, ErrNotSupported + } return s.Internal.PaychGet(p0, p1, p2, p3) } func (s *FullNodeStub) PaychGet(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { + if s.Internal.PaychGetWaitReady == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.PaychGetWaitReady(p0, p1) } func (s *FullNodeStub) PaychGetWaitReady(p0 context.Context, p1 cid.Cid) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) PaychList(p0 context.Context) ([]address.Address, error) { + if s.Internal.PaychList == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.PaychList(p0) } func (s *FullNodeStub) PaychList(p0 context.Context) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { + if s.Internal.PaychNewPayment == nil { + return nil, ErrNotSupported + } return s.Internal.PaychNewPayment(p0, p1, p2, p3) } func (s *FullNodeStub) PaychNewPayment(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { + if s.Internal.PaychSettle == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychSettle(p0, p1) } func (s *FullNodeStub) PaychSettle(p0 context.Context, p1 address.Address) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { + if s.Internal.PaychStatus == nil { + return nil, ErrNotSupported + } return s.Internal.PaychStatus(p0, p1) } func (s *FullNodeStub) PaychStatus(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { + if s.Internal.PaychVoucherAdd == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.PaychVoucherAdd(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherAdd(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { + if s.Internal.PaychVoucherCheckSpendable == nil { + return false, ErrNotSupported + } return s.Internal.PaychVoucherCheckSpendable(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherCheckSpendable(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { + if s.Internal.PaychVoucherCheckValid == nil { + return ErrNotSupported + } return s.Internal.PaychVoucherCheckValid(p0, p1, p2) } func (s *FullNodeStub) PaychVoucherCheckValid(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { + if s.Internal.PaychVoucherCreate == nil { + return nil, ErrNotSupported + } return s.Internal.PaychVoucherCreate(p0, p1, p2, p3) } func (s *FullNodeStub) PaychVoucherCreate(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { + if s.Internal.PaychVoucherList == nil { + return *new([]*paych.SignedVoucher), ErrNotSupported + } return s.Internal.PaychVoucherList(p0, p1) } func (s *FullNodeStub) PaychVoucherList(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) { - return *new([]*paych.SignedVoucher), xerrors.New("method not supported") + return *new([]*paych.SignedVoucher), ErrNotSupported } func (s *FullNodeStruct) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { + if s.Internal.PaychVoucherSubmit == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.PaychVoucherSubmit(p0, p1, p2, p3, p4) } func (s *FullNodeStub) PaychVoucherSubmit(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *FullNodeStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateAccountKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateAccountKey(p0, p1, p2) } func (s *FullNodeStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { + if s.Internal.StateAllMinerFaults == nil { + return *new([]*api.Fault), ErrNotSupported + } return s.Internal.StateAllMinerFaults(p0, p1, p2) } func (s *FullNodeStub) StateAllMinerFaults(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) { - return *new([]*api.Fault), xerrors.New("method not supported") + return *new([]*api.Fault), ErrNotSupported } func (s *FullNodeStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { + if s.Internal.StateCall == nil { + return nil, ErrNotSupported + } return s.Internal.StateCall(p0, p1, p2) } func (s *FullNodeStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { + if s.Internal.StateChangedActors == nil { + return *new(map[string]types.Actor), ErrNotSupported + } return s.Internal.StateChangedActors(p0, p1, p2) } func (s *FullNodeStub) StateChangedActors(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) { - return *new(map[string]types.Actor), xerrors.New("method not supported") + return *new(map[string]types.Actor), ErrNotSupported } func (s *FullNodeStruct) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { + if s.Internal.StateCirculatingSupply == nil { + return *new(abi.TokenAmount), ErrNotSupported + } return s.Internal.StateCirculatingSupply(p0, p1) } func (s *FullNodeStub) StateCirculatingSupply(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) { - return *new(abi.TokenAmount), xerrors.New("method not supported") + return *new(abi.TokenAmount), ErrNotSupported } func (s *FullNodeStruct) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { + if s.Internal.StateCompute == nil { + return nil, ErrNotSupported + } return s.Internal.StateCompute(p0, p1, p2, p3) } func (s *FullNodeStub) StateCompute(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + if s.Internal.StateDealProviderCollateralBounds == nil { + return *new(api.DealCollateralBounds), ErrNotSupported + } return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } func (s *FullNodeStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { - return *new(api.DealCollateralBounds), xerrors.New("method not supported") + return *new(api.DealCollateralBounds), ErrNotSupported } func (s *FullNodeStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { + if s.Internal.StateDecodeParams == nil { + return nil, ErrNotSupported + } return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4) } func (s *FullNodeStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + if s.Internal.StateGetActor == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetActor(p0, p1, p2) } func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + if s.Internal.StateGetReceipt == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetReceipt(p0, p1, p2) } func (s *FullNodeStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListActors == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListActors(p0, p1) } func (s *FullNodeStub) StateListActors(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { + if s.Internal.StateListMessages == nil { + return *new([]cid.Cid), ErrNotSupported + } return s.Internal.StateListMessages(p0, p1, p2, p3) } func (s *FullNodeStub) StateListMessages(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) { - return *new([]cid.Cid), xerrors.New("method not supported") + return *new([]cid.Cid), ErrNotSupported } func (s *FullNodeStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListMiners == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListMiners(p0, p1) } func (s *FullNodeStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateLookupID == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateLookupID(p0, p1, p2) } func (s *FullNodeStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + if s.Internal.StateMarketBalance == nil { + return *new(api.MarketBalance), ErrNotSupported + } return s.Internal.StateMarketBalance(p0, p1, p2) } func (s *FullNodeStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { - return *new(api.MarketBalance), xerrors.New("method not supported") + return *new(api.MarketBalance), ErrNotSupported } func (s *FullNodeStruct) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { + if s.Internal.StateMarketDeals == nil { + return *new(map[string]api.MarketDeal), ErrNotSupported + } return s.Internal.StateMarketDeals(p0, p1) } func (s *FullNodeStub) StateMarketDeals(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketDeal, error) { - return *new(map[string]api.MarketDeal), xerrors.New("method not supported") + return *new(map[string]api.MarketDeal), ErrNotSupported } func (s *FullNodeStruct) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { + if s.Internal.StateMarketParticipants == nil { + return *new(map[string]api.MarketBalance), ErrNotSupported + } return s.Internal.StateMarketParticipants(p0, p1) } func (s *FullNodeStub) StateMarketParticipants(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) { - return *new(map[string]api.MarketBalance), xerrors.New("method not supported") + return *new(map[string]api.MarketBalance), ErrNotSupported } func (s *FullNodeStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + if s.Internal.StateMarketStorageDeal == nil { + return nil, ErrNotSupported + } return s.Internal.StateMarketStorageDeal(p0, p1, p2) } func (s *FullNodeStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + if s.Internal.StateMinerActiveSectors == nil { + return *new([]*miner.SectorOnChainInfo), ErrNotSupported + } return s.Internal.StateMinerActiveSectors(p0, p1, p2) } func (s *FullNodeStub) StateMinerActiveSectors(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") + return *new([]*miner.SectorOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerAvailableBalance(p0, p1, p2) } func (s *FullNodeStub) StateMinerAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { + if s.Internal.StateMinerDeadlines == nil { + return *new([]api.Deadline), ErrNotSupported + } return s.Internal.StateMinerDeadlines(p0, p1, p2) } func (s *FullNodeStub) StateMinerDeadlines(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) { - return *new([]api.Deadline), xerrors.New("method not supported") + return *new([]api.Deadline), ErrNotSupported } func (s *FullNodeStruct) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + if s.Internal.StateMinerFaults == nil { + return *new(bitfield.BitField), ErrNotSupported + } return s.Internal.StateMinerFaults(p0, p1, p2) } func (s *FullNodeStub) StateMinerFaults(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return *new(bitfield.BitField), xerrors.New("method not supported") + return *new(bitfield.BitField), ErrNotSupported } func (s *FullNodeStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + if s.Internal.StateMinerInfo == nil { + return *new(miner.MinerInfo), ErrNotSupported + } return s.Internal.StateMinerInfo(p0, p1, p2) } func (s *FullNodeStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return *new(miner.MinerInfo), xerrors.New("method not supported") + return *new(miner.MinerInfo), ErrNotSupported } func (s *FullNodeStruct) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerInitialPledgeCollateral == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerInitialPledgeCollateral(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerInitialPledgeCollateral(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { + if s.Internal.StateMinerPartitions == nil { + return *new([]api.Partition), ErrNotSupported + } return s.Internal.StateMinerPartitions(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerPartitions(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) { - return *new([]api.Partition), xerrors.New("method not supported") + return *new([]api.Partition), ErrNotSupported } func (s *FullNodeStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + if s.Internal.StateMinerPower == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerPower(p0, p1, p2) } func (s *FullNodeStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.StateMinerPreCommitDepositForPower == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.StateMinerPreCommitDepositForPower(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerPreCommitDepositForPower(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + if s.Internal.StateMinerProvingDeadline == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } func (s *FullNodeStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { + if s.Internal.StateMinerRecoveries == nil { + return *new(bitfield.BitField), ErrNotSupported + } return s.Internal.StateMinerRecoveries(p0, p1, p2) } func (s *FullNodeStub) StateMinerRecoveries(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) { - return *new(bitfield.BitField), xerrors.New("method not supported") + return *new(bitfield.BitField), ErrNotSupported } func (s *FullNodeStruct) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { + if s.Internal.StateMinerSectorAllocated == nil { + return false, ErrNotSupported + } return s.Internal.StateMinerSectorAllocated(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerSectorAllocated(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { + if s.Internal.StateMinerSectorCount == nil { + return *new(api.MinerSectors), ErrNotSupported + } return s.Internal.StateMinerSectorCount(p0, p1, p2) } func (s *FullNodeStub) StateMinerSectorCount(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) { - return *new(api.MinerSectors), xerrors.New("method not supported") + return *new(api.MinerSectors), ErrNotSupported } func (s *FullNodeStruct) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { + if s.Internal.StateMinerSectors == nil { + return *new([]*miner.SectorOnChainInfo), ErrNotSupported + } return s.Internal.StateMinerSectors(p0, p1, p2, p3) } func (s *FullNodeStub) StateMinerSectors(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) { - return *new([]*miner.SectorOnChainInfo), xerrors.New("method not supported") + return *new([]*miner.SectorOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { + if s.Internal.StateNetworkName == nil { + return *new(dtypes.NetworkName), ErrNotSupported + } return s.Internal.StateNetworkName(p0) } func (s *FullNodeStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) { - return *new(dtypes.NetworkName), xerrors.New("method not supported") + return *new(dtypes.NetworkName), ErrNotSupported } func (s *FullNodeStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { + if s.Internal.StateNetworkVersion == nil { + return *new(apitypes.NetworkVersion), ErrNotSupported + } return s.Internal.StateNetworkVersion(p0, p1) } func (s *FullNodeStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) { - return *new(apitypes.NetworkVersion), xerrors.New("method not supported") + return *new(apitypes.NetworkVersion), ErrNotSupported } func (s *FullNodeStruct) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { + if s.Internal.StateReadState == nil { + return nil, ErrNotSupported + } return s.Internal.StateReadState(p0, p1, p2) } func (s *FullNodeStub) StateReadState(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { + if s.Internal.StateReplay == nil { + return nil, ErrNotSupported + } return s.Internal.StateReplay(p0, p1, p2) } func (s *FullNodeStub) StateReplay(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + if s.Internal.StateSearchMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateSearchMsg(p0, p1) } func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { + if s.Internal.StateSearchMsgLimited == nil { + return nil, ErrNotSupported + } return s.Internal.StateSearchMsgLimited(p0, p1, p2) } func (s *FullNodeStub) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { + if s.Internal.StateSectorExpiration == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorExpiration(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if s.Internal.StateSectorGetInfo == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { + if s.Internal.StateSectorPartition == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorPartition(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { + if s.Internal.StateSectorPreCommitInfo == nil { + return *new(miner.SectorPreCommitOnChainInfo), ErrNotSupported + } return s.Internal.StateSectorPreCommitInfo(p0, p1, p2, p3) } func (s *FullNodeStub) StateSectorPreCommitInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) { - return *new(miner.SectorPreCommitOnChainInfo), xerrors.New("method not supported") + return *new(miner.SectorPreCommitOnChainInfo), ErrNotSupported } func (s *FullNodeStruct) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { + if s.Internal.StateVMCirculatingSupplyInternal == nil { + return *new(api.CirculatingSupply), ErrNotSupported + } return s.Internal.StateVMCirculatingSupplyInternal(p0, p1) } func (s *FullNodeStub) StateVMCirculatingSupplyInternal(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) { - return *new(api.CirculatingSupply), xerrors.New("method not supported") + return *new(api.CirculatingSupply), ErrNotSupported } func (s *FullNodeStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifiedClientStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } func (s *FullNodeStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { + if s.Internal.StateVerifiedRegistryRootKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateVerifiedRegistryRootKey(p0, p1) } func (s *FullNodeStub) StateVerifiedRegistryRootKey(p0 context.Context, p1 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifierStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifierStatus(p0, p1, p2) } func (s *FullNodeStub) StateVerifierStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + if s.Internal.StateWaitMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateWaitMsg(p0, p1, p2) } func (s *FullNodeStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { + if s.Internal.StateWaitMsgLimited == nil { + return nil, ErrNotSupported + } return s.Internal.StateWaitMsgLimited(p0, p1, p2, p3) } func (s *FullNodeStub) StateWaitMsgLimited(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { + if s.Internal.SyncCheckBad == nil { + return "", ErrNotSupported + } return s.Internal.SyncCheckBad(p0, p1) } func (s *FullNodeStub) SyncCheckBad(p0 context.Context, p1 cid.Cid) (string, error) { - return "", xerrors.New("method not supported") + return "", ErrNotSupported } func (s *FullNodeStruct) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { + if s.Internal.SyncCheckpoint == nil { + return ErrNotSupported + } return s.Internal.SyncCheckpoint(p0, p1) } func (s *FullNodeStub) SyncCheckpoint(p0 context.Context, p1 types.TipSetKey) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { + if s.Internal.SyncIncomingBlocks == nil { + return nil, ErrNotSupported + } return s.Internal.SyncIncomingBlocks(p0) } func (s *FullNodeStub) SyncIncomingBlocks(p0 context.Context) (<-chan *types.BlockHeader, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { + if s.Internal.SyncMarkBad == nil { + return ErrNotSupported + } return s.Internal.SyncMarkBad(p0, p1) } func (s *FullNodeStub) SyncMarkBad(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncState(p0 context.Context) (*api.SyncState, error) { + if s.Internal.SyncState == nil { + return nil, ErrNotSupported + } return s.Internal.SyncState(p0) } func (s *FullNodeStub) SyncState(p0 context.Context) (*api.SyncState, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { + if s.Internal.SyncSubmitBlock == nil { + return ErrNotSupported + } return s.Internal.SyncSubmitBlock(p0, p1) } func (s *FullNodeStub) SyncSubmitBlock(p0 context.Context, p1 *types.BlockMsg) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncUnmarkAllBad(p0 context.Context) error { + if s.Internal.SyncUnmarkAllBad == nil { + return ErrNotSupported + } return s.Internal.SyncUnmarkAllBad(p0) } func (s *FullNodeStub) SyncUnmarkAllBad(p0 context.Context) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { + if s.Internal.SyncUnmarkBad == nil { + return ErrNotSupported + } return s.Internal.SyncUnmarkBad(p0, p1) } func (s *FullNodeStub) SyncUnmarkBad(p0 context.Context, p1 cid.Cid) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { + if s.Internal.SyncValidateTipset == nil { + return false, ErrNotSupported + } return s.Internal.SyncValidateTipset(p0, p1) } func (s *FullNodeStub) SyncValidateTipset(p0 context.Context, p1 types.TipSetKey) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.WalletBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.WalletBalance(p0, p1) } func (s *FullNodeStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *FullNodeStruct) WalletDefaultAddress(p0 context.Context) (address.Address, error) { + if s.Internal.WalletDefaultAddress == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletDefaultAddress(p0) } func (s *FullNodeStub) WalletDefaultAddress(p0 context.Context) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletDelete(p0 context.Context, p1 address.Address) error { + if s.Internal.WalletDelete == nil { + return ErrNotSupported + } return s.Internal.WalletDelete(p0, p1) } func (s *FullNodeStub) WalletDelete(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { + if s.Internal.WalletExport == nil { + return nil, ErrNotSupported + } return s.Internal.WalletExport(p0, p1) } func (s *FullNodeStub) WalletExport(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { + if s.Internal.WalletHas == nil { + return false, ErrNotSupported + } return s.Internal.WalletHas(p0, p1) } func (s *FullNodeStub) WalletHas(p0 context.Context, p1 address.Address) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *FullNodeStruct) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { + if s.Internal.WalletImport == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletImport(p0, p1) } func (s *FullNodeStub) WalletImport(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletList(p0 context.Context) ([]address.Address, error) { + if s.Internal.WalletList == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.WalletList(p0) } func (s *FullNodeStub) WalletList(p0 context.Context) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { + if s.Internal.WalletNew == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletNew(p0, p1) } func (s *FullNodeStub) WalletNew(p0 context.Context, p1 types.KeyType) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletSetDefault(p0 context.Context, p1 address.Address) error { + if s.Internal.WalletSetDefault == nil { + return ErrNotSupported + } return s.Internal.WalletSetDefault(p0, p1) } func (s *FullNodeStub) WalletSetDefault(p0 context.Context, p1 address.Address) error { - return xerrors.New("method not supported") + return ErrNotSupported } func (s *FullNodeStruct) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { + if s.Internal.WalletSign == nil { + return nil, ErrNotSupported + } return s.Internal.WalletSign(p0, p1, p2) } func (s *FullNodeStub) WalletSign(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { + if s.Internal.WalletSignMessage == nil { + return nil, ErrNotSupported + } return s.Internal.WalletSignMessage(p0, p1, p2) } func (s *FullNodeStub) WalletSignMessage(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *FullNodeStruct) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { + if s.Internal.WalletValidateAddress == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.WalletValidateAddress(p0, p1) } func (s *FullNodeStub) WalletValidateAddress(p0 context.Context, p1 string) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *FullNodeStruct) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { + if s.Internal.WalletVerify == nil { + return false, ErrNotSupported + } return s.Internal.WalletVerify(p0, p1, p2, p3) } func (s *FullNodeStub) WalletVerify(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *GatewayStruct) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { + if s.Internal.ChainGetBlockMessages == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetBlockMessages(p0, p1) } func (s *GatewayStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { + if s.Internal.ChainGetMessage == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetMessage(p0, p1) } func (s *GatewayStub) ChainGetMessage(p0 context.Context, p1 cid.Cid) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSet == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSet(p0, p1) } func (s *GatewayStub) ChainGetTipSet(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { + if s.Internal.ChainGetTipSetByHeight == nil { + return nil, ErrNotSupported + } return s.Internal.ChainGetTipSetByHeight(p0, p1, p2) } func (s *GatewayStub) ChainGetTipSetByHeight(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { + if s.Internal.ChainHasObj == nil { + return false, ErrNotSupported + } return s.Internal.ChainHasObj(p0, p1) } func (s *GatewayStub) ChainHasObj(p0 context.Context, p1 cid.Cid) (bool, error) { - return false, xerrors.New("method not supported") + return false, ErrNotSupported } func (s *GatewayStruct) ChainHead(p0 context.Context) (*types.TipSet, error) { + if s.Internal.ChainHead == nil { + return nil, ErrNotSupported + } return s.Internal.ChainHead(p0) } func (s *GatewayStub) ChainHead(p0 context.Context) (*types.TipSet, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { + if s.Internal.ChainNotify == nil { + return nil, ErrNotSupported + } return s.Internal.ChainNotify(p0) } func (s *GatewayStub) ChainNotify(p0 context.Context) (<-chan []*api.HeadChange, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { + if s.Internal.ChainReadObj == nil { + return *new([]byte), ErrNotSupported + } return s.Internal.ChainReadObj(p0, p1) } func (s *GatewayStub) ChainReadObj(p0 context.Context, p1 cid.Cid) ([]byte, error) { - return *new([]byte), xerrors.New("method not supported") + return *new([]byte), ErrNotSupported } func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { + if s.Internal.GasEstimateMessageGas == nil { + return nil, ErrNotSupported + } return s.Internal.GasEstimateMessageGas(p0, p1, p2, p3) } func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { + if s.Internal.MpoolPush == nil { + return *new(cid.Cid), ErrNotSupported + } return s.Internal.MpoolPush(p0, p1) } func (s *GatewayStub) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) { - return *new(cid.Cid), xerrors.New("method not supported") + return *new(cid.Cid), ErrNotSupported } func (s *GatewayStruct) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetAvailableBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetAvailableBalance(p0, p1, p2) } func (s *GatewayStub) MsigGetAvailableBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *GatewayStruct) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { + if s.Internal.MsigGetPending == nil { + return *new([]*api.MsigTransaction), ErrNotSupported + } return s.Internal.MsigGetPending(p0, p1, p2) } func (s *GatewayStub) MsigGetPending(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) { - return *new([]*api.MsigTransaction), xerrors.New("method not supported") + return *new([]*api.MsigTransaction), ErrNotSupported } func (s *GatewayStruct) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { + if s.Internal.MsigGetVested == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.MsigGetVested(p0, p1, p2, p3) } func (s *GatewayStub) MsigGetVested(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateAccountKey == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateAccountKey(p0, p1, p2) } func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { + if s.Internal.StateDealProviderCollateralBounds == nil { + return *new(api.DealCollateralBounds), ErrNotSupported + } return s.Internal.StateDealProviderCollateralBounds(p0, p1, p2, p3) } func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) { - return *new(api.DealCollateralBounds), xerrors.New("method not supported") + return *new(api.DealCollateralBounds), ErrNotSupported } func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { + if s.Internal.StateGetActor == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetActor(p0, p1, p2) } func (s *GatewayStub) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { + if s.Internal.StateGetReceipt == nil { + return nil, ErrNotSupported + } return s.Internal.StateGetReceipt(p0, p1, p2) } func (s *GatewayStub) StateGetReceipt(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { + if s.Internal.StateListMiners == nil { + return *new([]address.Address), ErrNotSupported + } return s.Internal.StateListMiners(p0, p1) } func (s *GatewayStub) StateListMiners(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) { - return *new([]address.Address), xerrors.New("method not supported") + return *new([]address.Address), ErrNotSupported } func (s *GatewayStruct) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { + if s.Internal.StateLookupID == nil { + return *new(address.Address), ErrNotSupported + } return s.Internal.StateLookupID(p0, p1, p2) } func (s *GatewayStub) StateLookupID(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) { - return *new(address.Address), xerrors.New("method not supported") + return *new(address.Address), ErrNotSupported } func (s *GatewayStruct) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { + if s.Internal.StateMarketBalance == nil { + return *new(api.MarketBalance), ErrNotSupported + } return s.Internal.StateMarketBalance(p0, p1, p2) } func (s *GatewayStub) StateMarketBalance(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) { - return *new(api.MarketBalance), xerrors.New("method not supported") + return *new(api.MarketBalance), ErrNotSupported } func (s *GatewayStruct) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { + if s.Internal.StateMarketStorageDeal == nil { + return nil, ErrNotSupported + } return s.Internal.StateMarketStorageDeal(p0, p1, p2) } func (s *GatewayStub) StateMarketStorageDeal(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { + if s.Internal.StateMinerInfo == nil { + return *new(miner.MinerInfo), ErrNotSupported + } return s.Internal.StateMinerInfo(p0, p1, p2) } func (s *GatewayStub) StateMinerInfo(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (miner.MinerInfo, error) { - return *new(miner.MinerInfo), xerrors.New("method not supported") + return *new(miner.MinerInfo), ErrNotSupported } func (s *GatewayStruct) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { + if s.Internal.StateMinerPower == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerPower(p0, p1, p2) } func (s *GatewayStub) StateMinerPower(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { + if s.Internal.StateMinerProvingDeadline == nil { + return nil, ErrNotSupported + } return s.Internal.StateMinerProvingDeadline(p0, p1, p2) } func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { + if s.Internal.StateNetworkVersion == nil { + return *new(network.Version), ErrNotSupported + } return s.Internal.StateNetworkVersion(p0, p1) } func (s *GatewayStub) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (network.Version, error) { - return *new(network.Version), xerrors.New("method not supported") + return *new(network.Version), ErrNotSupported } func (s *GatewayStruct) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { + if s.Internal.StateSearchMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateSearchMsg(p0, p1) } func (s *GatewayStub) StateSearchMsg(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { + if s.Internal.StateSectorGetInfo == nil { + return nil, ErrNotSupported + } return s.Internal.StateSectorGetInfo(p0, p1, p2, p3) } func (s *GatewayStub) StateSectorGetInfo(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { + if s.Internal.StateVerifiedClientStatus == nil { + return nil, ErrNotSupported + } return s.Internal.StateVerifiedClientStatus(p0, p1, p2) } func (s *GatewayStub) StateVerifiedClientStatus(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { + if s.Internal.StateWaitMsg == nil { + return nil, ErrNotSupported + } return s.Internal.StateWaitMsg(p0, p1, p2) } func (s *GatewayStub) StateWaitMsg(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) { - return nil, xerrors.New("method not supported") + return nil, ErrNotSupported } func (s *GatewayStruct) Version(p0 context.Context) (api.APIVersion, error) { + if s.Internal.Version == nil { + return *new(api.APIVersion), ErrNotSupported + } return s.Internal.Version(p0) } func (s *GatewayStub) Version(p0 context.Context) (api.APIVersion, error) { - return *new(api.APIVersion), xerrors.New("method not supported") + return *new(api.APIVersion), ErrNotSupported } func (s *GatewayStruct) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { + if s.Internal.WalletBalance == nil { + return *new(types.BigInt), ErrNotSupported + } return s.Internal.WalletBalance(p0, p1) } func (s *GatewayStub) WalletBalance(p0 context.Context, p1 address.Address) (types.BigInt, error) { - return *new(types.BigInt), xerrors.New("method not supported") + return *new(types.BigInt), ErrNotSupported } var _ FullNode = new(FullNodeStruct) diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 0afa796d59e7161878b9d7418a3cfcfd5b6e533d..c940d921b0af50de4f243bc595a80f87b709ce86 100644 GIT binary patch literal 25240 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 literal 23719 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 ZHas>SA3s0-{{R30|Nlrm^lT}?0RZ{gmVf{N literal 8671 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 Q1pom5|0BYO@mYER0Jxzq&;S4c literal 2514 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 Date: Mon, 26 Jul 2021 11:07:53 -0400 Subject: [PATCH 34/38] ValidateBlock: Assert that block header height's are greater than their parents --- chain/sync.go | 5 +++ chain/sync_test.go | 99 ++++++++++++++++++++++++++++------------------ 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/chain/sync.go b/chain/sync.go index 5a5362ccd..5d3c1d992 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -727,6 +727,11 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock, use } // fast checks first + + if h.Height <= baseTs.Height() { + return xerrors.Errorf("block height not greater than parent height: %d != %d", h.Height, baseTs.Height()) + } + nulls := h.Height - (baseTs.Height() + 1) if tgtTs := baseTs.MinTimestamp() + build.BlockDelaySecs*uint64(nulls+1); h.Timestamp != tgtTs { return xerrors.Errorf("block has wrong timestamp: %d != %d", h.Timestamp, tgtTs) diff --git a/chain/sync_test.go b/chain/sync_test.go index 5312dff0b..bda8c60ee 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -230,7 +230,7 @@ func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bo } } -func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool, msgs [][]*types.SignedMessage, nulls abi.ChainEpoch) *store.FullTipSet { +func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool, msgs [][]*types.SignedMessage, nulls abi.ChainEpoch, push bool) *store.FullTipSet { if miners == nil { for i := range tu.g.Miners { miners = append(miners, i) @@ -247,7 +247,7 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, var nts *store.FullTipSet var err error if msgs != nil { - nts, err = tu.g.NextTipSetFromMinersWithMessagesAndNulls(blk.TipSet(), maddrs, msgs, 0) + nts, err = tu.g.NextTipSetFromMinersWithMessagesAndNulls(blk.TipSet(), maddrs, msgs, nulls) require.NoError(tu.t, err) } else { mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs, nulls) @@ -255,17 +255,19 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, nts = mt.TipSet } - if fail { - tu.pushTsExpectErr(to, nts, true) - } else { - tu.pushFtsAndWait(to, nts, wait) + if push { + if fail { + tu.pushTsExpectErr(to, nts, true) + } else { + tu.pushFtsAndWait(to, nts, wait) + } } return nts } func (tu *syncTestUtil) mineNewBlock(src int, miners []int) { - mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false, nil, 0) + mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false, nil, 0, true) tu.g.CurTipset = mts } @@ -510,7 +512,7 @@ func TestSyncBadTimestamp(t *testing.T) { fmt.Println("BASE: ", base.Cids()) tu.printHeads() - a1 := tu.mineOnBlock(base, 0, nil, false, true, nil, 0) + a1 := tu.mineOnBlock(base, 0, nil, false, true, nil, 0, true) tu.g.Timestamper = nil require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) @@ -519,7 +521,7 @@ func TestSyncBadTimestamp(t *testing.T) { fmt.Println("After mine bad block!") tu.printHeads() - a2 := tu.mineOnBlock(base, 0, nil, true, false, nil, 0) + a2 := tu.mineOnBlock(base, 0, nil, true, false, nil, 0, true) tu.waitUntilSync(0, client) @@ -563,7 +565,7 @@ func TestSyncBadWinningPoSt(t *testing.T) { tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{}) // now ensure that new blocks are not accepted - tu.mineOnBlock(base, client, nil, false, true, nil, 0) + tu.mineOnBlock(base, client, nil, false, true, nil, 0, true) } func (tu *syncTestUtil) loadChainToNode(to int) { @@ -613,16 +615,16 @@ func TestSyncFork(t *testing.T) { fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height()) // The two nodes fork at this point into 'a' and 'b' - a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0) - a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0) - a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0) + a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0, true) + a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0, true) + a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0, true) require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) // chain B will now be heaviest - b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) + b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) fmt.Println("A: ", a.Cids(), a.TipSet().Height()) fmt.Println("B: ", b.Cids(), b.TipSet().Height()) @@ -686,13 +688,13 @@ func TestDuplicateNonce(t *testing.T) { msgs[k] = []*types.SignedMessage{makeMsg(tu.g.Miners[k])} } - ts1 := tu.mineOnBlock(base, 0, []int{0, 1}, true, false, msgs, 0) + ts1 := tu.mineOnBlock(base, 0, []int{0, 1}, true, false, msgs, 0, true) tu.waitUntilSyncTarget(0, ts1.TipSet()) // mine another tipset - ts2 := tu.mineOnBlock(ts1, 0, []int{0, 1}, true, false, make([][]*types.SignedMessage, 2), 0) + ts2 := tu.mineOnBlock(ts1, 0, []int{0, 1}, true, false, make([][]*types.SignedMessage, 2), 0, true) tu.waitUntilSyncTarget(0, ts2.TipSet()) var includedMsg cid.Cid @@ -778,7 +780,7 @@ func TestBadNonce(t *testing.T) { msgs := make([][]*types.SignedMessage, 1) msgs[0] = []*types.SignedMessage{makeBadMsg()} - tu.mineOnBlock(base, 0, []int{0}, true, true, msgs, 0) + tu.mineOnBlock(base, 0, []int{0}, true, true, msgs, 0, true) } // This test introduces a block that has 2 messages, with the same sender, and same nonce. @@ -832,7 +834,7 @@ func TestMismatchedNoncesRobustID(t *testing.T) { msgs := make([][]*types.SignedMessage, 1) msgs[0] = []*types.SignedMessage{makeMsg(false), makeMsg(true)} - tu.mineOnBlock(base, 0, []int{0}, true, true, msgs, 0) + tu.mineOnBlock(base, 0, []int{0}, true, true, msgs, 0, true) } // This test introduces a block that has 2 messages, with the same sender, and nonces N and N+1 (so both can be included in a block) @@ -886,7 +888,7 @@ func TestMatchedNoncesRobustID(t *testing.T) { msgs := make([][]*types.SignedMessage, 1) msgs[0] = []*types.SignedMessage{makeMsg(ba.Nonce, false), makeMsg(ba.Nonce+1, true)} - tu.mineOnBlock(base, 0, []int{0}, true, false, msgs, 0) + tu.mineOnBlock(base, 0, []int{0}, true, false, msgs, 0, true) } func BenchmarkSyncBasic(b *testing.B) { @@ -951,19 +953,19 @@ func TestSyncCheckpointHead(t *testing.T) { fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height()) // The two nodes fork at this point into 'a' and 'b' - a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0) - a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0) - a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0) + a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0, true) + a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0, true) + a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0, true) tu.waitUntilSyncTarget(p1, a.TipSet()) tu.checkpointTs(p1, a.TipSet().Key()) require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) // chain B will now be heaviest - b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) + b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) fmt.Println("A: ", a.Cids(), a.TipSet().Height()) fmt.Println("B: ", b.Cids(), b.TipSet().Height()) @@ -998,19 +1000,19 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) { fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height()) // The two nodes fork at this point into 'a' and 'b' - a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0) - a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0) - a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0) + a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0, true) + a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0, true) + a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0, true) tu.waitUntilSyncTarget(p1, a.TipSet()) tu.checkpointTs(p1, a1.TipSet().Key()) require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet())) // chain B will now be heaviest - b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) - b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0) + b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) + b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0, true) fmt.Println("A: ", a.Cids(), a.TipSet().Height()) fmt.Println("B: ", b.Cids(), b.TipSet().Height()) @@ -1048,7 +1050,7 @@ func TestDrandNull(t *testing.T) { pers := crypto.DomainSeparationTag_WinningPoStChallengeSeed beforeNull := tu.g.CurTipset - afterNull := tu.mineOnBlock(beforeNull, p0, nil, false, false, nil, 2) + afterNull := tu.mineOnBlock(beforeNull, p0, nil, false, false, nil, 2, true) nullHeight := beforeNull.TipSet().Height() + 1 if afterNull.TipSet().Height() == nullHeight { t.Fatal("didn't inject nulls as expected") @@ -1065,14 +1067,14 @@ func TestDrandNull(t *testing.T) { require.Equal(t, []byte(rand), expectedRand) // zoom zoom to past the v5 upgrade by injecting many many nulls - postUpgrade := tu.mineOnBlock(afterNull, p0, nil, false, false, nil, v5h) + postUpgrade := tu.mineOnBlock(afterNull, p0, nil, false, false, nil, v5h, true) nv, err := tu.nds[p0].StateNetworkVersion(tu.ctx, postUpgrade.TipSet().Key()) require.NoError(t, err) if nv != network.Version13 { t.Fatal("expect to be v13 by now") } - afterNull = tu.mineOnBlock(postUpgrade, p0, nil, false, false, nil, 2) + afterNull = tu.mineOnBlock(postUpgrade, p0, nil, false, false, nil, 2, true) nullHeight = postUpgrade.TipSet().Height() + 1 if afterNull.TipSet().Height() == nullHeight { t.Fatal("didn't inject nulls as expected") @@ -1104,3 +1106,22 @@ func TestDrandNull(t *testing.T) { build.UpgradeHyperdriveHeight = ov5h } + +func TestInvalidHeight(t *testing.T) { + H := 50 + tu := prepSyncTest(t, H) + + client := tu.addClientNode() + + require.NoError(t, tu.mn.LinkAll()) + tu.connect(client, 0) + tu.waitUntilSync(0, client) + + base := tu.g.CurTipset + + for i := 0; i < 5; i++ { + base = tu.mineOnBlock(base, 0, nil, false, false, nil, 0, false) + } + + tu.mineOnBlock(base, 0, nil, false, true, nil, -1, true) +} From 0fd8fc24e102c543cf833b38526c15729e626d8a Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 12:25:42 +0300 Subject: [PATCH 35/38] load a full finality worth of state during warmup --- blockstore/splitstore/splitstore_test.go | 1 + blockstore/splitstore/splitstore_warmup.go | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/blockstore/splitstore/splitstore_test.go b/blockstore/splitstore/splitstore_test.go index b945eb90b..df9984d41 100644 --- a/blockstore/splitstore/splitstore_test.go +++ b/blockstore/splitstore/splitstore_test.go @@ -24,6 +24,7 @@ import ( func init() { CompactionThreshold = 5 CompactionBoundary = 2 + WarmupBoundary = 0 logging.SetLogLevel("splitstore", "DEBUG") } diff --git a/blockstore/splitstore/splitstore_warmup.go b/blockstore/splitstore/splitstore_warmup.go index 7c5769e22..fd4e7f7b1 100644 --- a/blockstore/splitstore/splitstore_warmup.go +++ b/blockstore/splitstore/splitstore_warmup.go @@ -10,9 +10,15 @@ import ( cid "github.com/ipfs/go-cid" bstore "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" ) +var ( + // WarmupBoundary is the number of epochs to load state during warmup. + WarmupBoundary = build.Finality +) + // warmup acuiqres the compaction lock and spawns a goroutine to warm up the hotstore; // this is necessary when we sync from a snapshot or when we enable the splitstore // on top of an existing blockstore (which becomes the coldstore). @@ -44,11 +50,12 @@ func (s *SplitStore) warmup(curTs *types.TipSet) error { // objects are written in batches so as to minimize overhead. func (s *SplitStore) doWarmup(curTs *types.TipSet) error { epoch := curTs.Height() + boundaryEpoch := epoch - WarmupBoundary batchHot := make([]blocks.Block, 0, batchSize) count := int64(0) xcount := int64(0) missing := int64(0) - err := s.walkChain(curTs, epoch, epoch+1, // we don't load messages/receipts in warmup + err := s.walkChain(curTs, boundaryEpoch, epoch+1, // we don't load messages/receipts in warmup func(c cid.Cid) error { if isUnitaryObject(c) { return errStopWalk From 18caefc4a12b321818baacc6bbfcd5584630e3cf Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 25 Jul 2021 13:34:18 +0300 Subject: [PATCH 36/38] fix missing object condition; short-circuit walk --- blockstore/splitstore/splitstore_warmup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockstore/splitstore/splitstore_warmup.go b/blockstore/splitstore/splitstore_warmup.go index fd4e7f7b1..039cb1a46 100644 --- a/blockstore/splitstore/splitstore_warmup.go +++ b/blockstore/splitstore/splitstore_warmup.go @@ -76,7 +76,7 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error { if err != nil { if err == bstore.ErrNotFound { missing++ - return nil + return errStopWalk } return err } From c52c2738abbb66fa802d205d12b500a50017f307 Mon Sep 17 00:00:00 2001 From: vyzo Date: Mon, 26 Jul 2021 18:36:01 +0300 Subject: [PATCH 37/38] fix potential underflow --- blockstore/splitstore/splitstore_warmup.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/blockstore/splitstore/splitstore_warmup.go b/blockstore/splitstore/splitstore_warmup.go index 039cb1a46..2079a5474 100644 --- a/blockstore/splitstore/splitstore_warmup.go +++ b/blockstore/splitstore/splitstore_warmup.go @@ -9,6 +9,7 @@ import ( blocks "github.com/ipfs/go-block-format" cid "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" @@ -49,8 +50,11 @@ func (s *SplitStore) warmup(curTs *types.TipSet) error { // and headers all the way up to genesis. // objects are written in batches so as to minimize overhead. func (s *SplitStore) doWarmup(curTs *types.TipSet) error { + var boundaryEpoch abi.ChainEpoch epoch := curTs.Height() - boundaryEpoch := epoch - WarmupBoundary + if WarmupBoundary < epoch { + boundaryEpoch = epoch - WarmupBoundary + } batchHot := make([]blocks.Block, 0, batchSize) count := int64(0) xcount := int64(0) From ed387b43cc35edbac38ad853057a7680c0530dc9 Mon Sep 17 00:00:00 2001 From: Peter Rabbitson Date: Wed, 30 Jun 2021 11:40:54 +0200 Subject: [PATCH 38/38] Bump go-multihash, adjust test for supported version --- chain/events/state/predicates_test.go | 2 +- go.mod | 4 ++-- go.sum | 15 +++++++++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/chain/events/state/predicates_test.go b/chain/events/state/predicates_test.go index 8af3bb6a0..bdc7523dc 100644 --- a/chain/events/state/predicates_test.go +++ b/chain/events/state/predicates_test.go @@ -21,7 +21,7 @@ import ( market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market" miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner" adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt" - tutils "github.com/filecoin-project/specs-actors/v2/support/testing" + tutils "github.com/filecoin-project/specs-actors/v5/support/testing" bstore "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/builtin/market" diff --git a/go.mod b/go.mod index fa90d65cb..808a74ea1 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/filecoin-project/specs-actors/v2 v2.3.5 github.com/filecoin-project/specs-actors/v3 v3.1.1 github.com/filecoin-project/specs-actors/v4 v4.0.1 - github.com/filecoin-project/specs-actors/v5 v5.0.2 + github.com/filecoin-project/specs-actors/v5 v5.0.3-0.20210722213508-58cb5de23d1f github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 github.com/filecoin-project/test-vectors/schema v0.0.5 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 @@ -126,7 +126,7 @@ require ( github.com/multiformats/go-multiaddr v0.3.1 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.0.3 - github.com/multiformats/go-multihash v0.0.14 + github.com/multiformats/go-multihash v0.0.15 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 github.com/opentracing/opentracing-go v1.2.0 github.com/polydawn/refmt v0.0.0-20190809202753-05966cbd336a diff --git a/go.sum b/go.sum index 7a2d357de..63773c2c7 100644 --- a/go.sum +++ b/go.sum @@ -332,8 +332,8 @@ github.com/filecoin-project/specs-actors/v4 v4.0.0/go.mod h1:TkHXf/l7Wyw4ZejyXIP github.com/filecoin-project/specs-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg= github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng= github.com/filecoin-project/specs-actors/v5 v5.0.0-20210512015452-4fe3889fff57/go.mod h1:283yBMMUSDB2abcjP/hhrwTkhb9h3sfM6KGrep/ZlBI= -github.com/filecoin-project/specs-actors/v5 v5.0.2 h1:pLNFUt9xtFuhrgZZ0tPnzGchAVu4koyCRIopzkx/OP0= -github.com/filecoin-project/specs-actors/v5 v5.0.2/go.mod h1:E0yeEl6Scl6eWeeWmxwQsAufvOAC72H6ELyh2Y62H90= +github.com/filecoin-project/specs-actors/v5 v5.0.3-0.20210722213508-58cb5de23d1f h1:hSgH0xcKkL+fCnEl/beqzn2loBN9+YUsxvVvefZ6cP4= +github.com/filecoin-project/specs-actors/v5 v5.0.3-0.20210722213508-58cb5de23d1f/go.mod h1:E0yeEl6Scl6eWeeWmxwQsAufvOAC72H6ELyh2Y62H90= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw= github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg= @@ -817,6 +817,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -1217,8 +1219,9 @@ github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+ github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= -github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -1283,8 +1286,9 @@ github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa github.com/multiformats/go-multihash v0.0.9/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= -github.com/multiformats/go-multihash v0.0.14 h1:QoBceQYQQtNUuf6s7wHxnE2c8bhbMqhfGzNI032se/I= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= github.com/multiformats/go-multistream v0.0.1/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.0.4/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= @@ -1707,6 +1711,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1882,11 +1887,13 @@ golang.org/x/sys v0.0.0-20200926100807-9d91bd62050c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=