Compare commits

..
Author SHA1 Message Date
Aayush 6cc9eecc85 Lotus release v1.14.0-rc4 2022-01-25 13:28:03 -05:00
Aayush 817c155287 chore: deps: update to latest proofs 2022-01-25 13:23:00 -05:00
Aayush Rajasekaran 6e44de1e10 Update params_2k.go 2022-01-25 13:04:22 -05:00
Aayush Rajasekaran a6460be37b remove a log 2022-01-25 13:02:45 -05:00
Aayush 6b7b488e00 Lotus release v1.14.0-rc3 2022-01-25 13:02:08 -05:00
Aayush e7123d1a8e fix: sealer: correctly pipe through errors for SectorAbortUpgrade 2022-01-25 13:02:00 -05:00
Aayush 50aba9a8e6 fix: sealer: don't replica update sectors unless they have deals in them 2022-01-25 13:01:56 -05:00
Aayush 1b18236f91 feat: sealer: allow users to abort in-flight snap upgrades 2022-01-25 13:01:51 -05:00
Aayush e17ae2eaf4 fix: sealer: manager should lock Unsealed for ReplicaUpdate 2022-01-25 13:01:37 -05:00
Aayush 6d567b36e3 Fix: sealer: ReplicaUpdate should fetch the correct files 2022-01-25 13:01:27 -05:00
Aayush Rajasekaran 7b7ab016db create replica update paths in acquireSectors 2022-01-25 13:01:18 -05:00
Aayush Rajasekaran 0c9c94bad1 fix: checkReplica incorrectly returns ErrBadPR 2022-01-25 13:01:12 -05:00
Aayush Rajasekaran a3c5fadcc0 feat: sealing: Add ReplicaUpdate work to Resource table 2022-01-25 13:01:05 -05:00
Jennifer Wang ca444bb71d revert #7646 from v1.14.0 - this is not concensus breaking change and needs more testing before landing 2022-01-14 19:00:33 -05:00
Jennifer Wang 5f1ae545e3 add 7939 to change log 2022-01-14 18:57:57 -05:00
Aayush Rajasekaran 99d0d5019b Add missing locks to Get() 2022-01-14 18:57:57 -05:00
Aayush Rajasekaran be09474615 Apply suggestions from code review 2022-01-14 18:57:57 -05:00
Jennifer Wang a67f97e8a2 address reviews 2022-01-14 18:57:57 -05:00
Jennifer Wang 9453734434 fix the statsboard link 2022-01-14 18:57:57 -05:00
Jennifer Wang 2fde9e63cd update change log 2022-01-14 18:57:57 -05:00
Aayush Rajasekaran 51b4458d32 Resolve conflict 2022-01-14 17:18:47 -05:00
Steven Allen 9872ca7f12 correctness fixes for the autobatch blockstore
1. Simplify shutdown and make it idempotent by using a context.
2. Make sure `Flush` actually _fully_ flushes if the previous flush failed.
3. Don't clear the flush batch if flushing fails.
2022-01-14 17:17:51 -05:00
Aayush Rajasekaran 2871ed74d0 go mod tidy 2022-01-14 17:17:51 -05:00
Jiaying Wang 07e68aa064 update snap net upgrade epoch 2022-01-14 17:17:51 -05:00
Jennifer Wang 1b264d5a53 update network version for test ground 2022-01-14 17:17:51 -05:00
Jennifer Wang 03cb555d1d Update the ntwk v15 name to OhSnap 2022-01-14 17:17:51 -05:00
Jennifer Wang e097578e85 add butterfly ohsnap epoch 2022-01-14 17:17:51 -05:00
Aayush Rajasekaran b3ab3ce170 Update butterflynet params 2022-01-14 17:17:49 -05:00
Aayush Rajasekaran 84e6ba5dff Update butterflynet params 2022-01-14 17:17:36 -05:00
Jennifer Wang b7ba08476c remove power change 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran aad8aa0893 Appease the linter 2022-01-14 17:15:44 -05:00
Jennifer Wang 30013c1f06 fix lint 2022-01-14 17:15:44 -05:00
Jennifer Wang 6901e998e6 Check piece before PRU2 instead of PRU1 as PRU2 is the heavy computation part 2022-01-14 17:15:44 -05:00
Jennifer Wang 8939d5982f just use checkPiece 2022-01-14 17:15:44 -05:00
Jennifer Wang a20916f9af Add more deal expiration handling for snap deals 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran 107f80274c Don't lock in Get 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran 4ec8fbf1ff Address review part 2 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran 5b38419c5f Address review 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran dafd1f77fa Support faster Get, retry flushes on error 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran ce6e328d52 Use channels to trigger flushes in a dedicated goroutine 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran 2bc4b35f51 implement stubs 2022-01-14 17:15:44 -05:00
Aayush Rajasekaran 031b06be77 cache added cids 2022-01-14 17:15:43 -05:00
Aayush Rajasekaran b9474cf0a2 Implement an autobatcher 2022-01-14 17:15:20 -05:00
Aayush Rajasekaran 074a4cc3e4 Update to actors v7.0.0-rc1 2022-01-14 17:15:20 -05:00
Aayush Rajasekaran 790ba155b8 Fast migration for v15 2022-01-14 17:15:15 -05:00
vyzo 0ca95a5ea0 satisfy the spellchecker that masquarades as a linter 2022-01-14 17:14:33 -05:00
vyzo 7e43bfc109 hook the upgrade schedule to splitstore start 2022-01-14 17:14:32 -05:00
vyzo 6cfee12f31 add unit test for compaction supression 2022-01-14 17:14:32 -05:00
vyzo 6ac3d529ef add logic for supressing compaction near upgrade boundaries 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran e4cb68e05d format 2022-01-14 17:14:32 -05:00
Jiaying Wang 0626330d44 Update default-lotus-miner-config.toml 2022-01-14 17:14:32 -05:00
Jennifer Wang 60cf2a71cf fix lint 2022-01-14 17:14:32 -05:00
Jennifer Wang 87babdf3e7 Disable mark-for-upgrade two days before the network v15 OhSnap upgrade to avoid unexpected edge cases that may cause deal/sector failure 2022-01-14 17:14:32 -05:00
Jennifer Wang ac3bea489b Integrate proof v11.0.0 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran ca57546ef5 Remove unnecessary params from VerifyWinningPost 2022-01-14 17:14:32 -05:00
Łukasz Magiera 7bd9af7856 address review 2022-01-14 17:14:32 -05:00
zenground0 5b0a0baa9a Fix hande deal recover return value bug 2022-01-14 17:14:32 -05:00
zenground0 a9a523d8c0 Fix TooManyMarkedForUpgrade 2022-01-14 17:14:32 -05:00
zenground0 c6277922ac Deflake more practically 2022-01-14 17:14:32 -05:00
zenground0 a82ac00d9a Deflake snap deals integration test 2022-01-14 17:14:32 -05:00
zenground0 d6aa17e21f Snap Deals Integration
- FSM handles the actual cc upgrade process including error states
- PoSting (winning and window) works over upgraded and upgrading sectors
- Integration test and changes to itest framework to reduce flakes
- Update CLI to handle new upgrade
- Update dependencies
2022-01-14 17:14:32 -05:00
Jennifer Wang ba816a1c13 bump the version to v1.14.0-rc1 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran ceb11bfe77 Update go-paramfetch 2022-01-14 17:14:32 -05:00
Jiaying Wang c99f8a17ac Update pull_request_template.md 2022-01-14 17:14:32 -05:00
Jiaying Wang 1e03fac105 Remove ticket number from the title
issue number in PR title is not that useful because reader cannot click it and need to mention the issue in the body for auto close either way.
2022-01-14 17:14:32 -05:00
Jakub Sztandera 0b105dad97 Add gas charge for VerifyReplicaUpdate
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 832e204ec4 Fix circsuypply calc around null blocks 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran bfbd01ab15 VM: Circ supply should be constant per epoch 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 58f63ca8a2 Add a log for when message selection fails 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 012efed117 Mempool: add selection tests 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 1f1e341c36 Mempool: Selection should respect CBOR limits 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 80c9c26560 Consensus: Safety check against unknown sig types 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 011ea43496 Mempool: Selection logic should respect block message limits 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 3a8ac6dffa Update FFI 2022-01-14 17:14:32 -05:00
zenground0 d1480c36c0 RemoveData and Decode
- Unsealing replica update with sector key works and tested
- Sector key generation added and tested
2022-01-14 17:14:32 -05:00
Jiaying Wang 5c9a10617b Create pull_request_template.md
This is the very first iteration of the lotus PR template. The goal of adding PR template is to standardize PR requests and encourage contributors to:
- come up with good PR descriptions to give code reviewers a clear overview of what's in the PR 
- have a clear PR title as lotus generates a change log based on it
- check that tests and documentation for the codes that changed are icnluded 

The PR type follows the https://www.conventionalcommits.org/en/v1.0.0-beta.2/.  The [contribution guideline](https://github.com/filecoin-project/lotus#contribute) should be updated with how to create a pr after the template is accepted.
2022-01-14 17:14:32 -05:00
Jennifer Wang a93d7499d9 docs gen 2022-01-14 17:14:32 -05:00
Jennifer Wang e24b454a1f Bump the master version to v1.13.3-dev 2022-01-14 17:14:32 -05:00
zenground0 4936b4ea44 Review Response 2022-01-14 17:14:32 -05:00
zenground0 c4069824f7 WIP 2022-01-14 17:14:32 -05:00
c r 7efaa708a6 reorder transfer checks so as to ensure sending more money than you have to yourself fails with an error (fixing issue 7596)
PR #7637, also adds tests to make sure behavior is correct across versions.
2022-01-14 17:14:32 -05:00
zenground0 93656e65f8 WIP sector storage and integration test 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 3a7c364562 Address review 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran c0bb554d8d Update actors 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 073b7b4ff5 Update FFI 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 393d8541e2 Update deps 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran 1ef780d96f Plug in the FFI call 2022-01-14 17:14:32 -05:00
Aayush Rajasekaran a8cb027c08 Integrate v7 actors 2022-01-14 17:14:32 -05:00
Jiaying Wang a95b77a940 Merge pull request #7931 from filecoin-project/jen/proof
feat: param: add temp snap params
2022-01-11 18:08:50 -05:00
Jennifer Wang edd3486d2c add temp snap params 2022-01-11 17:01:15 -05:00
292 changed files with 3064 additions and 10786 deletions
-5
View File
@@ -785,11 +785,6 @@ workflows:
suite: itest-deals_512mb
target: "./itests/deals_512mb_test.go"
- test:
name: test-itest-deals_anycid
suite: itest-deals_anycid
target: "./itests/deals_anycid_test.go"
- test:
name: test-itest-deals_concurrent
suite: itest-deals_concurrent
+3 -3
View File
@@ -12,10 +12,10 @@
Before you mark the PR ready for review, please make sure that:
- [ ] All commits have a clear commit message.
- [ ] The PR title is in the form of of `<PR type>: <area>: <change being made>`
- [ ] The PR title is in the form of `<PR type>: <area>: <change being made>`
- example: ` fix: mempool: Introduce a cache for valid signatures`
- `PR type`: _fix_, _feat_, _INTERFACE BREAKING CHANGE_, _CONSENSUS BREAKING_, _build_, _chore_, _ci_, _docs_,_perf_, _refactor_, _revert_, _style_, _test_
- `area`: _api_, _chain_, _state_, _vm_, _data transfer_, _market_, _mempool_, _message_, _block production_, _multisig_, _networking_, _paychan_, _proving_, _sealing_, _wallet_, _deps_
- `PR type`: _fix_, _feat_, _INTERFACE BREAKING CHANGE_, _CONSENSUS BREAKING_, _build_, _chore_, _ci_, _docs_, _misc_,_perf_, _refactor_, _revert_, _style_, _test_
- `area`: _api_, _chain_, _state_, _vm_, _data transfer_, _market_, _mempool_, _message_, _block production_, _multisig_, _networking_, _paychan_, _proving_, _sealing_, _wallet_
- [ ] This PR has tests for new functionality or change in behaviour
- [ ] If new user-facing features are introduced, clear usage guidelines and / or documentation updates should be included in https://lotus.filecoin.io or [Discussion Tutorials.](https://github.com/filecoin-project/lotus/discussions/categories/tutorials)
- [ ] CI is green
+84
View File
@@ -1,5 +1,89 @@
# Lotus changelog
# 1.14.0-rc3 / 2022-01-25
This is the fourth release candidate for the mandatory release v1.14.0 of Lotus that introduces [Filecoin network v15,
codenamed the OhSnap upgrade](https://github.com/filecoin-project/community/discussions/74?sort=new#discussioncomment-1922550).
The OhSnap upgrade introduces the following FIPs, delivered in [actors v7-rc1](https://github.com/filecoin-project/specs-actors/releases/tag/v7.0.0-rc1):
- [FIP-0019 Snap Deals](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0019.md)
- [FIP-0028 Remove Datacap from Verified clients](https://github.com/filecoin-project/FIPs/pull/226)
Note:
- This release is built on top of lotus v1.13.2. Enterprising users like storage providers, data brokers and others
are recommended to test out v1.15.0-rc1(coming on Jan 18th, 2022) for latest new features, improvements and bug
fixes and be ready for the upgrade!
- This release candidate uses temporary proof params for Snap Deals.
- It only sets upgrade epoch for Butterfly-SnapNet, and it does not set the upgrade epochs for calibration and mainnet.
## Butterfly - SnapNet
The ButterFly-SnapNet will be upgraded to Network v15 OhSnap at epoch 30262, around 2022-01-17T19:00:00Z.
To join the network, simply build lotus by running `make butterflynet`.
The network supports three sector sizes, 512MiB, 32GiB and 64GiB. Temporary proof params for Snap Deals should be downloaded upon your node restarts.
- The parameters are pinged on IPFS gateway https://proofs.filecoin.io/ipfs/ and the CIDs can be found [here](https://github.com/filecoin-project/lotus/blob/edd3486d2cf53b960382e9cda6671e647844aa41/build/proof-params/parameters.json), please let the lotus team know in #lotus-ohsnap if the params are not fetched automatically. You can also download the params manually from s3://proof-params-ap/filecoin-snapdeal-parameters/.
*SnapNet Resources*:
- [Faucet](https://faucet.butterfly.fildev.network/)
- [Stats Dashboard](https://stats.butterfly.fildev.network/d/z6FtI92Zz/chain?orgId=1&refresh=25s&from=now-30m&to=now&kiosk)
- For questions and feedbacks:
- Primary: [Discussion](https://github.com/filecoin-project/lotus/discussions/7935)
- Secondary: #lotus-ohsnap in Filecoin Slack
## New Features and Changes
- Integrate actor v7-rc1:
- Integrate v7 actors ([#7617](https://github.com/filecoin-project/lotus/pull/7617))
- feat: state: Fast migration for v15 ([#7933](https://github.com/filecoin-project/lotus/pull/7933))
- fix: blockstore: Add missing locks to autobatch::Get() [#7939](https://github.com/filecoin-project/lotus/pull/7939))
- correctness fixes for the autobatch blockstore ([#7940](https://github.com/filecoin-project/lotus/pull/7940))
- Implement and support [FIP-0019 Snap Deals](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0019.md)
- chore: deps: Integrate proof v11.0.0 ([#7923](https://github.com/filecoin-project/lotus/pull/7923))
- Snap Deals Lotus Integration: FSM Posting and integration test ([#7810](https://github.com/filecoin-project/lotus/pull/7810))
- Feat/sector storage unseal ([#7730](https://github.com/filecoin-project/lotus/pull/7730))
- Feat/snap deals storage ([#7615](https://github.com/filecoin-project/lotus/pull/7615))
- fix: sealing: Add more deal expiration checks during PRU pipeline ([#7871](https://github.com/filecoin-project/lotus/pull/7871))
- chore: deps: Update go-paramfetch ([#7917](https://github.com/filecoin-project/lotus/pull/7917))
- feat: #7880 gas: add gas charge for VerifyReplicaUpdate ([#7897](https://github.com/filecoin-project/lotus/pull/7897))
- enhancement: sectors: disable existing cc upgrade path 2 days before the upgrade epoch ([#7900](https://github.com/filecoin-project/lotus/pull/7900))
## Improvements
- updating to new datastore/blockstore code with contexts ([#7646](https://github.com/filecoin-project/lotus/pull/7646))
- reorder transfer checks so as to ensure sending 2B FIL to yourself fails if you don't have that amount ([#7637](https://github.com/filecoin-project/lotus/pull/7637))
- VM: Circ supply should be constant per epoch ([#7811](https://github.com/filecoin-project/lotus/pull/7811))
## Bug Fixes
- Fix: state: circsuypply calc around null blocks ([#7890](https://github.com/filecoin-project/lotus/pull/7890))
- Mempool msg selection should respect block message limits ([#7321](https://github.com/filecoin-project/lotus/pull/7321))
SplitStore: supress compaction near upgrades ([#7734](https://github.com/filecoin-project/lotus/pull/7734))
## Others
- chore: create pull_request_template.md ([#7726](https://github.com/filecoin-project/lotus/pull/7726))
## Contributors
| Contributor | Commits | Lines ± | Files Changed |
|-------------|---------|---------|---------------|
| Aayush Rajasekaran | 56 | +5866/-2523 | 316 |
| zenground0 | 11 | +3316/-524 | 124 |
| vyzo | 38 | +722/-485 | 117 |
| Rod Vagg | 2 | +6/-941 | 4 |
| whyrusleeping | 2 | +376/-339 | 27 |
| ZenGround0 | 3 | +263/-25 | 11 |
| c r | 2 | +198/-30 | 6 |
| Łukasz Magiera | 2 | +184/-3 | 3 |
| Jennifer Wang | 14 | +97/-69 | 41 |
| Whyrusleeping | 1 | +76/-70 | 8 |
| web3-bot | 10 | +99/-17 | 10 |
| Steven Allen | 1 | +55/-37 | 1 |
| Jiaying Wang | 5 | +30/-8 | 5 |
| Hannah Howard | 1 | +4/-29 | 3 |
| dirkmc | 1 | +11/-0 | 1 |
| Jakub Sztandera | 2 | +8/-3 | 3 |
| Colin Kennedy | 1 | +4/-2 | 1 |
# v1.13.2 / 2022-01-09
Lotus v1.13.2 is a *highly recommended* feature release with remarkable retrieval improvements, new features like
-1
View File
@@ -900,7 +900,6 @@ type QueryOffer struct {
Size uint64
MinPrice types.BigInt
UnsealPrice types.BigInt
PricePerByte abi.TokenAmount
PaymentInterval uint64
PaymentIntervalIncrease uint64
Miner address.Address
-9
View File
@@ -51,15 +51,6 @@ type Net interface {
NetBlockRemove(ctx context.Context, acl NetBlockList) error //perm:admin
NetBlockList(ctx context.Context) (NetBlockList, error) //perm:read
NetProtectAdd(ctx context.Context, acl []peer.ID) error //perm:admin
NetProtectRemove(ctx context.Context, acl []peer.ID) error //perm:admin
NetProtectList(ctx context.Context) ([]peer.ID, error) //perm:read
// ResourceManager API
NetStat(ctx context.Context, scope string) (NetStat, error) //perm:read
NetLimit(ctx context.Context, scope string) (NetLimit, error) //perm:read
NetSetLimit(ctx context.Context, scope string, limit NetLimit) error //perm:admin
// ID returns peerID of libp2p node backing this API
ID(context.Context) (peer.ID, error) //perm:read
}
+2 -16
View File
@@ -113,6 +113,8 @@ type StorageMiner interface {
// SectorCommitPending returns a list of pending Commit sectors to be sent in the next aggregate message
SectorCommitPending(ctx context.Context) ([]abi.SectorID, error) //perm:admin
SectorMatchPendingPiecesToOpenSectors(ctx context.Context) error //perm:admin
// SectorAbortUpgrade can be called on sectors that are in the process of being upgraded to abort it
SectorAbortUpgrade(context.Context, abi.SectorNumber) error //perm:admin
// WorkerConnect tells the node to connect to workers RPC
WorkerConnect(context.Context, string) error //perm:admin retry:true
@@ -151,7 +153,6 @@ type StorageMiner interface {
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
StorageGetLocks(ctx context.Context) (storiface.SectorLocks, error) //perm:admin
StorageLocal(ctx context.Context) (map[stores.ID]string, error) //perm:admin
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) //perm:admin
@@ -167,8 +168,6 @@ type StorageMiner interface {
MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error) //perm:read
MarketListDataTransfers(ctx context.Context) ([]DataTransferChannel, error) //perm:write
MarketDataTransferUpdates(ctx context.Context) (<-chan DataTransferChannel, error) //perm:write
// MarketDataTransferDiagnostics generates debugging information about current data transfers over graphsync
MarketDataTransferDiagnostics(ctx context.Context, p peer.ID) (*TransferDiagnostics, error) //perm:write
// MarketRestartDataTransfer attempts to restart a data transfer with the given transfer ID and other peer
MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error //perm:write
// MarketCancelDataTransfer cancels a data transfer with the given transfer ID and other peer
@@ -219,19 +218,6 @@ type StorageMiner interface {
// DagstoreGC runs garbage collection on the DAG store.
DagstoreGC(ctx context.Context) ([]DagstoreShardResult, error) //perm:admin
// IndexerAnnounceDeal informs indexer nodes that a new deal was received,
// so they can download its index
IndexerAnnounceDeal(ctx context.Context, proposalCid cid.Cid) error //perm:admin
// IndexerAnnounceAllDeals informs the indexer nodes aboutall active deals.
IndexerAnnounceAllDeals(ctx context.Context) error //perm:admin
// DagstorePieceIndexSize returns the size of the piece index.
DagstorePieceIndexSize(ctx context.Context) (int64, error) //perm:admin
// DagstoreLookupPieces returns information about shards that contain the given CID.
DagstoreLookupPieces(ctx context.Context, cid cid.Cid) ([]DagstoreShardInfo, error) //perm:admin
// RuntimeSubsystems returns the subsystems that are enabled
// in this instance.
RuntimeSubsystems(ctx context.Context) (MinerSubsystems, error) //perm:read
+1 -40
View File
@@ -1,7 +1,6 @@
package docgen
import (
"encoding/json"
"fmt"
"go/ast"
"go/parser"
@@ -16,7 +15,6 @@ import (
"github.com/filecoin-project/go-bitfield"
"github.com/google/uuid"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-graphsync"
"github.com/libp2p/go-libp2p-core/metrics"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
@@ -122,7 +120,6 @@ func init() {
addExample(api.FullAPIVersion1)
addExample(api.PCHInbound)
addExample(time.Minute)
addExample(graphsync.RequestID(4))
addExample(datatransfer.TransferID(3))
addExample(datatransfer.Ongoing)
addExample(storeIDExample)
@@ -253,18 +250,10 @@ func init() {
addExample(map[abi.SectorNumber]string{
123: "can't acquire read lock",
})
addExample(json.RawMessage(`"json raw message"`))
addExample(map[api.SectorState]int{
api.SectorState(sealing.Proving): 120,
})
addExample([]abi.SectorNumber{123, 124})
addExample([]storiface.SectorLock{
{
Sector: abi.SectorID{Number: 123, Miner: 1000},
Write: [storiface.FileTypes]uint{0, 0, 1},
Read: [storiface.FileTypes]uint{2, 3, 0},
},
})
// worker specific
addExample(storiface.AcquireMove)
@@ -300,34 +289,6 @@ func init() {
Error: "<error>",
})
addExample(storiface.ResourceTable)
addExample(network.ScopeStat{
Memory: 123,
NumStreamsInbound: 1,
NumStreamsOutbound: 2,
NumConnsInbound: 3,
NumConnsOutbound: 4,
NumFD: 5,
})
addExample(map[string]network.ScopeStat{
"abc": {
Memory: 123,
NumStreamsInbound: 1,
NumStreamsOutbound: 2,
NumConnsInbound: 3,
NumConnsOutbound: 4,
NumFD: 5,
}})
addExample(api.NetLimit{
Memory: 123,
StreamsInbound: 1,
StreamsOutbound: 2,
Streams: 3,
ConnsInbound: 3,
ConnsOutbound: 4,
Conns: 4,
FD: 5,
})
}
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
@@ -378,7 +339,7 @@ func ExampleValue(method string, t, parent reflect.Type) interface{} {
switch t.Kind() {
case reflect.Slice:
out := reflect.New(t).Elem()
out = reflect.Append(out, reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
reflect.Append(out, reflect.ValueOf(ExampleValue(method, t.Elem(), t)))
return out.Interface()
case reflect.Chan:
return ExampleValue(method, t.Elem(), nil)
-87
View File
@@ -1811,21 +1811,6 @@ func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
}
// NetLimit mocks base method.
func (m *MockFullNode) NetLimit(arg0 context.Context, arg1 string) (api.NetLimit, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetLimit", arg0, arg1)
ret0, _ := ret[0].(api.NetLimit)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetLimit indicates an expected call of NetLimit.
func (mr *MockFullNodeMockRecorder) NetLimit(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetLimit", reflect.TypeOf((*MockFullNode)(nil).NetLimit), arg0, arg1)
}
// NetPeerInfo mocks base method.
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
m.ctrl.T.Helper()
@@ -1856,49 +1841,6 @@ func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
}
// NetProtectAdd mocks base method.
func (m *MockFullNode) NetProtectAdd(arg0 context.Context, arg1 []peer.ID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectAdd", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// NetProtectAdd indicates an expected call of NetProtectAdd.
func (mr *MockFullNodeMockRecorder) NetProtectAdd(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectAdd", reflect.TypeOf((*MockFullNode)(nil).NetProtectAdd), arg0, arg1)
}
// NetProtectList mocks base method.
func (m *MockFullNode) NetProtectList(arg0 context.Context) ([]peer.ID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectList", arg0)
ret0, _ := ret[0].([]peer.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetProtectList indicates an expected call of NetProtectList.
func (mr *MockFullNodeMockRecorder) NetProtectList(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectList", reflect.TypeOf((*MockFullNode)(nil).NetProtectList), arg0)
}
// NetProtectRemove mocks base method.
func (m *MockFullNode) NetProtectRemove(arg0 context.Context, arg1 []peer.ID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectRemove", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// NetProtectRemove indicates an expected call of NetProtectRemove.
func (mr *MockFullNodeMockRecorder) NetProtectRemove(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectRemove", reflect.TypeOf((*MockFullNode)(nil).NetProtectRemove), arg0, arg1)
}
// NetPubsubScores mocks base method.
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
m.ctrl.T.Helper()
@@ -1914,35 +1856,6 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
}
// NetSetLimit mocks base method.
func (m *MockFullNode) NetSetLimit(arg0 context.Context, arg1 string, arg2 api.NetLimit) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetSetLimit", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// NetSetLimit indicates an expected call of NetSetLimit.
func (mr *MockFullNodeMockRecorder) NetSetLimit(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetSetLimit", reflect.TypeOf((*MockFullNode)(nil).NetSetLimit), arg0, arg1, arg2)
}
// NetStat mocks base method.
func (m *MockFullNode) NetStat(arg0 context.Context, arg1 string) (api.NetStat, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetStat", arg0, arg1)
ret0, _ := ret[0].(api.NetStat)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetStat indicates an expected call of NetStat.
func (mr *MockFullNodeMockRecorder) NetStat(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetStat", reflect.TypeOf((*MockFullNode)(nil).NetStat), arg0, arg1)
}
// NodeStatus mocks base method.
func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) {
m.ctrl.T.Helper()
+13 -156
View File
@@ -587,23 +587,11 @@ type NetStruct struct {
NetFindPeer func(p0 context.Context, p1 peer.ID) (peer.AddrInfo, error) `perm:"read"`
NetLimit func(p0 context.Context, p1 string) (NetLimit, error) `perm:"read"`
NetPeerInfo func(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) `perm:"read"`
NetPeers func(p0 context.Context) ([]peer.AddrInfo, error) `perm:"read"`
NetProtectAdd func(p0 context.Context, p1 []peer.ID) error `perm:"admin"`
NetProtectList func(p0 context.Context) ([]peer.ID, error) `perm:"read"`
NetProtectRemove func(p0 context.Context, p1 []peer.ID) error `perm:"admin"`
NetPubsubScores func(p0 context.Context) ([]PubsubScore, error) `perm:"read"`
NetSetLimit func(p0 context.Context, p1 string, p2 NetLimit) error `perm:"admin"`
NetStat func(p0 context.Context, p1 string) (NetStat, error) `perm:"read"`
}
}
@@ -645,10 +633,6 @@ type StorageMinerStruct struct {
DagstoreListShards func(p0 context.Context) ([]DagstoreShardInfo, error) `perm:"read"`
DagstoreLookupPieces func(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) `perm:"admin"`
DagstorePieceIndexSize func(p0 context.Context) (int64, error) `perm:"admin"`
DagstoreRecoverShard func(p0 context.Context, p1 string) error `perm:"write"`
DealsConsiderOfflineRetrievalDeals func(p0 context.Context) (bool, error) `perm:"admin"`
@@ -683,14 +667,8 @@ type StorageMinerStruct struct {
DealsSetPieceCidBlocklist func(p0 context.Context, p1 []cid.Cid) error `perm:"admin"`
IndexerAnnounceAllDeals func(p0 context.Context) error `perm:"admin"`
IndexerAnnounceDeal func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
MarketCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
MarketDataTransferDiagnostics func(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) `perm:"write"`
MarketDataTransferUpdates func(p0 context.Context) (<-chan DataTransferChannel, error) `perm:"write"`
MarketGetAsk func(p0 context.Context) (*storagemarket.SignedStorageAsk, error) `perm:"read"`
@@ -769,6 +747,8 @@ type StorageMinerStruct struct {
SealingSchedDiag func(p0 context.Context, p1 bool) (interface{}, error) `perm:"admin"`
SectorAbortUpgrade func(p0 context.Context, p1 abi.SectorNumber) error `perm:"admin"`
SectorAddPieceToAny func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storage.Data, p3 PieceDealInfo) (SectorOffset, error) `perm:"admin"`
SectorCommitFlush func(p0 context.Context) ([]sealiface.CommitBatchRes, error) `perm:"admin"`
@@ -827,8 +807,6 @@ type StorageMinerStruct struct {
StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageGetLocks func(p0 context.Context) (storiface.SectorLocks, error) `perm:"admin"`
StorageInfo func(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) `perm:"admin"`
StorageList func(p0 context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
@@ -3645,17 +3623,6 @@ func (s *NetStub) NetFindPeer(p0 context.Context, p1 peer.ID) (peer.AddrInfo, er
return *new(peer.AddrInfo), ErrNotSupported
}
func (s *NetStruct) NetLimit(p0 context.Context, p1 string) (NetLimit, error) {
if s.Internal.NetLimit == nil {
return *new(NetLimit), ErrNotSupported
}
return s.Internal.NetLimit(p0, p1)
}
func (s *NetStub) NetLimit(p0 context.Context, p1 string) (NetLimit, error) {
return *new(NetLimit), ErrNotSupported
}
func (s *NetStruct) NetPeerInfo(p0 context.Context, p1 peer.ID) (*ExtendedPeerInfo, error) {
if s.Internal.NetPeerInfo == nil {
return nil, ErrNotSupported
@@ -3678,39 +3645,6 @@ func (s *NetStub) NetPeers(p0 context.Context) ([]peer.AddrInfo, error) {
return *new([]peer.AddrInfo), ErrNotSupported
}
func (s *NetStruct) NetProtectAdd(p0 context.Context, p1 []peer.ID) error {
if s.Internal.NetProtectAdd == nil {
return ErrNotSupported
}
return s.Internal.NetProtectAdd(p0, p1)
}
func (s *NetStub) NetProtectAdd(p0 context.Context, p1 []peer.ID) error {
return ErrNotSupported
}
func (s *NetStruct) NetProtectList(p0 context.Context) ([]peer.ID, error) {
if s.Internal.NetProtectList == nil {
return *new([]peer.ID), ErrNotSupported
}
return s.Internal.NetProtectList(p0)
}
func (s *NetStub) NetProtectList(p0 context.Context) ([]peer.ID, error) {
return *new([]peer.ID), ErrNotSupported
}
func (s *NetStruct) NetProtectRemove(p0 context.Context, p1 []peer.ID) error {
if s.Internal.NetProtectRemove == nil {
return ErrNotSupported
}
return s.Internal.NetProtectRemove(p0, p1)
}
func (s *NetStub) NetProtectRemove(p0 context.Context, p1 []peer.ID) error {
return ErrNotSupported
}
func (s *NetStruct) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) {
if s.Internal.NetPubsubScores == nil {
return *new([]PubsubScore), ErrNotSupported
@@ -3722,28 +3656,6 @@ func (s *NetStub) NetPubsubScores(p0 context.Context) ([]PubsubScore, error) {
return *new([]PubsubScore), ErrNotSupported
}
func (s *NetStruct) NetSetLimit(p0 context.Context, p1 string, p2 NetLimit) error {
if s.Internal.NetSetLimit == nil {
return ErrNotSupported
}
return s.Internal.NetSetLimit(p0, p1, p2)
}
func (s *NetStub) NetSetLimit(p0 context.Context, p1 string, p2 NetLimit) error {
return ErrNotSupported
}
func (s *NetStruct) NetStat(p0 context.Context, p1 string) (NetStat, error) {
if s.Internal.NetStat == nil {
return *new(NetStat), ErrNotSupported
}
return s.Internal.NetStat(p0, p1)
}
func (s *NetStub) NetStat(p0 context.Context, p1 string) (NetStat, error) {
return *new(NetStat), ErrNotSupported
}
func (s *SignableStruct) Sign(p0 context.Context, p1 SignFunc) error {
if s.Internal.Sign == nil {
return ErrNotSupported
@@ -3865,28 +3777,6 @@ func (s *StorageMinerStub) DagstoreListShards(p0 context.Context) ([]DagstoreSha
return *new([]DagstoreShardInfo), ErrNotSupported
}
func (s *StorageMinerStruct) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) {
if s.Internal.DagstoreLookupPieces == nil {
return *new([]DagstoreShardInfo), ErrNotSupported
}
return s.Internal.DagstoreLookupPieces(p0, p1)
}
func (s *StorageMinerStub) DagstoreLookupPieces(p0 context.Context, p1 cid.Cid) ([]DagstoreShardInfo, error) {
return *new([]DagstoreShardInfo), ErrNotSupported
}
func (s *StorageMinerStruct) DagstorePieceIndexSize(p0 context.Context) (int64, error) {
if s.Internal.DagstorePieceIndexSize == nil {
return 0, ErrNotSupported
}
return s.Internal.DagstorePieceIndexSize(p0)
}
func (s *StorageMinerStub) DagstorePieceIndexSize(p0 context.Context) (int64, error) {
return 0, ErrNotSupported
}
func (s *StorageMinerStruct) DagstoreRecoverShard(p0 context.Context, p1 string) error {
if s.Internal.DagstoreRecoverShard == nil {
return ErrNotSupported
@@ -4074,28 +3964,6 @@ func (s *StorageMinerStub) DealsSetPieceCidBlocklist(p0 context.Context, p1 []ci
return ErrNotSupported
}
func (s *StorageMinerStruct) IndexerAnnounceAllDeals(p0 context.Context) error {
if s.Internal.IndexerAnnounceAllDeals == nil {
return ErrNotSupported
}
return s.Internal.IndexerAnnounceAllDeals(p0)
}
func (s *StorageMinerStub) IndexerAnnounceAllDeals(p0 context.Context) error {
return ErrNotSupported
}
func (s *StorageMinerStruct) IndexerAnnounceDeal(p0 context.Context, p1 cid.Cid) error {
if s.Internal.IndexerAnnounceDeal == nil {
return ErrNotSupported
}
return s.Internal.IndexerAnnounceDeal(p0, p1)
}
func (s *StorageMinerStub) IndexerAnnounceDeal(p0 context.Context, p1 cid.Cid) error {
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
@@ -4107,17 +3975,6 @@ func (s *StorageMinerStub) MarketCancelDataTransfer(p0 context.Context, p1 datat
return ErrNotSupported
}
func (s *StorageMinerStruct) MarketDataTransferDiagnostics(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) {
if s.Internal.MarketDataTransferDiagnostics == nil {
return nil, ErrNotSupported
}
return s.Internal.MarketDataTransferDiagnostics(p0, p1)
}
func (s *StorageMinerStub) MarketDataTransferDiagnostics(p0 context.Context, p1 peer.ID) (*TransferDiagnostics, error) {
return nil, ErrNotSupported
}
func (s *StorageMinerStruct) MarketDataTransferUpdates(p0 context.Context) (<-chan DataTransferChannel, error) {
if s.Internal.MarketDataTransferUpdates == nil {
return nil, ErrNotSupported
@@ -4547,6 +4404,17 @@ func (s *StorageMinerStub) SealingSchedDiag(p0 context.Context, p1 bool) (interf
return nil, ErrNotSupported
}
func (s *StorageMinerStruct) SectorAbortUpgrade(p0 context.Context, p1 abi.SectorNumber) error {
if s.Internal.SectorAbortUpgrade == nil {
return ErrNotSupported
}
return s.Internal.SectorAbortUpgrade(p0, p1)
}
func (s *StorageMinerStub) SectorAbortUpgrade(p0 context.Context, p1 abi.SectorNumber) error {
return 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
@@ -4866,17 +4734,6 @@ func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID
return *new([]stores.SectorStorageInfo), ErrNotSupported
}
func (s *StorageMinerStruct) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
if s.Internal.StorageGetLocks == nil {
return *new(storiface.SectorLocks), ErrNotSupported
}
return s.Internal.StorageGetLocks(p0)
}
func (s *StorageMinerStub) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
return *new(storiface.SectorLocks), ErrNotSupported
}
func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) {
if s.Internal.StorageInfo == nil {
return *new(stores.StorageInfo), ErrNotSupported
-48
View File
@@ -10,9 +10,7 @@ import (
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-graphsync"
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
pubsub "github.com/libp2p/go-libp2p-pubsub"
ma "github.com/multiformats/go-multiaddr"
@@ -55,30 +53,6 @@ type MessageSendSpec struct {
MaxFee abi.TokenAmount
}
// GraphSyncDataTransfer provides diagnostics on a data transfer happening over graphsync
type GraphSyncDataTransfer struct {
// GraphSync request id for this transfer
RequestID graphsync.RequestID
// Graphsync state for this transfer
RequestState string
// If a channel ID is present, indicates whether this is the current graphsync request for this channel
// (could have changed in a restart)
IsCurrentChannelRequest bool
// Data transfer channel ID for this transfer
ChannelID *datatransfer.ChannelID
// Data transfer state for this transfer
ChannelState *DataTransferChannel
// Diagnostic information about this request -- and unexpected inconsistencies in
// request state
Diagnostics []string
}
// TransferDiagnostics give current information about transfers going over graphsync that may be helpful for debugging
type TransferDiagnostics struct {
ReceivingTransfers []*GraphSyncDataTransfer
SendingTransfers []*GraphSyncDataTransfer
}
type DataTransferChannel struct {
TransferID datatransfer.TransferID
Status datatransfer.Status
@@ -130,28 +104,6 @@ type NetBlockList struct {
IPSubnets []string
}
type NetStat struct {
System *network.ScopeStat `json:",omitempty"`
Transient *network.ScopeStat `json:",omitempty"`
Services map[string]network.ScopeStat `json:",omitempty"`
Protocols map[string]network.ScopeStat `json:",omitempty"`
Peers map[string]network.ScopeStat `json:",omitempty"`
}
type NetLimit struct {
Dynamic bool `json:",omitempty"`
// set if Dynamic is false
Memory int64 `json:",omitempty"`
// set if Dynamic is true
MemoryFraction float64 `json:",omitempty"`
MinMemory int64 `json:",omitempty"`
MaxMemory int64 `json:",omitempty"`
Streams, StreamsInbound, StreamsOutbound int
Conns, ConnsInbound, ConnsOutbound int
FD int
}
type ExtendedPeerInfo struct {
ID peer.ID
Agent string
-87
View File
@@ -1724,21 +1724,6 @@ func (mr *MockFullNodeMockRecorder) NetFindPeer(arg0, arg1 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetFindPeer", reflect.TypeOf((*MockFullNode)(nil).NetFindPeer), arg0, arg1)
}
// NetLimit mocks base method.
func (m *MockFullNode) NetLimit(arg0 context.Context, arg1 string) (api.NetLimit, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetLimit", arg0, arg1)
ret0, _ := ret[0].(api.NetLimit)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetLimit indicates an expected call of NetLimit.
func (mr *MockFullNodeMockRecorder) NetLimit(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetLimit", reflect.TypeOf((*MockFullNode)(nil).NetLimit), arg0, arg1)
}
// NetPeerInfo mocks base method.
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
m.ctrl.T.Helper()
@@ -1769,49 +1754,6 @@ func (mr *MockFullNodeMockRecorder) NetPeers(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPeers", reflect.TypeOf((*MockFullNode)(nil).NetPeers), arg0)
}
// NetProtectAdd mocks base method.
func (m *MockFullNode) NetProtectAdd(arg0 context.Context, arg1 []peer.ID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectAdd", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// NetProtectAdd indicates an expected call of NetProtectAdd.
func (mr *MockFullNodeMockRecorder) NetProtectAdd(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectAdd", reflect.TypeOf((*MockFullNode)(nil).NetProtectAdd), arg0, arg1)
}
// NetProtectList mocks base method.
func (m *MockFullNode) NetProtectList(arg0 context.Context) ([]peer.ID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectList", arg0)
ret0, _ := ret[0].([]peer.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetProtectList indicates an expected call of NetProtectList.
func (mr *MockFullNodeMockRecorder) NetProtectList(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectList", reflect.TypeOf((*MockFullNode)(nil).NetProtectList), arg0)
}
// NetProtectRemove mocks base method.
func (m *MockFullNode) NetProtectRemove(arg0 context.Context, arg1 []peer.ID) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetProtectRemove", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// NetProtectRemove indicates an expected call of NetProtectRemove.
func (mr *MockFullNodeMockRecorder) NetProtectRemove(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetProtectRemove", reflect.TypeOf((*MockFullNode)(nil).NetProtectRemove), arg0, arg1)
}
// NetPubsubScores mocks base method.
func (m *MockFullNode) NetPubsubScores(arg0 context.Context) ([]api.PubsubScore, error) {
m.ctrl.T.Helper()
@@ -1827,35 +1769,6 @@ func (mr *MockFullNodeMockRecorder) NetPubsubScores(arg0 interface{}) *gomock.Ca
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetPubsubScores", reflect.TypeOf((*MockFullNode)(nil).NetPubsubScores), arg0)
}
// NetSetLimit mocks base method.
func (m *MockFullNode) NetSetLimit(arg0 context.Context, arg1 string, arg2 api.NetLimit) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetSetLimit", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
return ret0
}
// NetSetLimit indicates an expected call of NetSetLimit.
func (mr *MockFullNodeMockRecorder) NetSetLimit(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetSetLimit", reflect.TypeOf((*MockFullNode)(nil).NetSetLimit), arg0, arg1, arg2)
}
// NetStat mocks base method.
func (m *MockFullNode) NetStat(arg0 context.Context, arg1 string) (api.NetStat, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetStat", arg0, arg1)
ret0, _ := ret[0].(api.NetStat)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetStat indicates an expected call of NetStat.
func (mr *MockFullNodeMockRecorder) NetStat(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetStat", reflect.TypeOf((*MockFullNode)(nil).NetStat), arg0, arg1)
}
// PaychAllocateLane mocks base method.
func (m *MockFullNode) PaychAllocateLane(arg0 context.Context, arg1 address.Address) (uint64, error) {
m.ctrl.T.Helper()
+9 -9
View File
@@ -25,35 +25,35 @@ func NewAPIBlockstore(cio ChainIO) Blockstore {
return Adapt(bs) // return an adapted blockstore.
}
func (a *apiBlockstore) DeleteBlock(context.Context, cid.Cid) error {
func (a *apiBlockstore) DeleteBlock(cid.Cid) error {
return xerrors.New("not supported")
}
func (a *apiBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
return a.api.ChainHasObj(ctx, c)
func (a *apiBlockstore) Has(c cid.Cid) (bool, error) {
return a.api.ChainHasObj(context.TODO(), c)
}
func (a *apiBlockstore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
bb, err := a.api.ChainReadObj(ctx, c)
func (a *apiBlockstore) Get(c cid.Cid) (blocks.Block, error) {
bb, err := a.api.ChainReadObj(context.TODO(), c)
if err != nil {
return nil, err
}
return blocks.NewBlockWithCid(bb, c)
}
func (a *apiBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
bb, err := a.api.ChainReadObj(ctx, c)
func (a *apiBlockstore) GetSize(c cid.Cid) (int, error) {
bb, err := a.api.ChainReadObj(context.TODO(), c)
if err != nil {
return 0, err
}
return len(bb), nil
}
func (a *apiBlockstore) Put(context.Context, blocks.Block) error {
func (a *apiBlockstore) Put(blocks.Block) error {
return xerrors.New("not supported")
}
func (a *apiBlockstore) PutMany(context.Context, []blocks.Block) error {
func (a *apiBlockstore) PutMany([]blocks.Block) error {
return xerrors.New("not supported")
}
+21 -21
View File
@@ -64,7 +64,7 @@ func NewAutobatch(ctx context.Context, backingBs Blockstore, bufferCapacity int)
return bs
}
func (bs *AutobatchBlockstore) Put(ctx context.Context, blk block.Block) error {
func (bs *AutobatchBlockstore) Put(blk block.Block) error {
bs.stateLock.Lock()
defer bs.stateLock.Unlock()
@@ -94,19 +94,19 @@ func (bs *AutobatchBlockstore) flushWorker(ctx context.Context) {
case <-bs.flushCh:
// TODO: check if we _should_ actually flush. We could get a spurious wakeup
// here.
putErr := bs.doFlush(ctx, false)
putErr := bs.doFlush(false)
for putErr != nil {
select {
case <-ctx.Done():
return
case <-time.After(bs.flushRetryDelay):
autolog.Errorf("FLUSH ERRORED: %w, retrying after %v", putErr, bs.flushRetryDelay)
putErr = bs.doFlush(ctx, true)
putErr = bs.doFlush(true)
}
}
case <-ctx.Done():
// Do one last flush.
_ = bs.doFlush(ctx, false)
_ = bs.doFlush(false)
return
}
}
@@ -114,13 +114,13 @@ func (bs *AutobatchBlockstore) flushWorker(ctx context.Context) {
// caller must NOT hold stateLock
// set retryOnly to true to only retry a failed flush and not flush anything new.
func (bs *AutobatchBlockstore) doFlush(ctx context.Context, retryOnly bool) error {
func (bs *AutobatchBlockstore) doFlush(retryOnly bool) error {
bs.doFlushLock.Lock()
defer bs.doFlushLock.Unlock()
// If we failed to flush last time, try flushing again.
if bs.flushErr != nil {
bs.flushErr = bs.backingBs.PutMany(ctx, bs.flushingBatch.blockList)
bs.flushErr = bs.backingBs.PutMany(bs.flushingBatch.blockList)
}
// If we failed, or we're _only_ retrying, bail.
@@ -137,7 +137,7 @@ func (bs *AutobatchBlockstore) doFlush(ctx context.Context, retryOnly bool) erro
bs.stateLock.Unlock()
// And try to flush it.
bs.flushErr = bs.backingBs.PutMany(ctx, bs.flushingBatch.blockList)
bs.flushErr = bs.backingBs.PutMany(bs.flushingBatch.blockList)
// If we succeeded, reset the batch. Otherwise, we'll try again next time.
if bs.flushErr == nil {
@@ -151,7 +151,7 @@ func (bs *AutobatchBlockstore) doFlush(ctx context.Context, retryOnly bool) erro
// caller must NOT hold stateLock
func (bs *AutobatchBlockstore) Flush(ctx context.Context) error {
return bs.doFlush(ctx, false)
return bs.doFlush(false)
}
func (bs *AutobatchBlockstore) Shutdown(ctx context.Context) error {
@@ -169,9 +169,9 @@ func (bs *AutobatchBlockstore) Shutdown(ctx context.Context) error {
return bs.flushErr
}
func (bs *AutobatchBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block, error) {
func (bs *AutobatchBlockstore) Get(c cid.Cid) (block.Block, error) {
// may seem backward to check the backingBs first, but that is the likeliest case
blk, err := bs.backingBs.Get(ctx, c)
blk, err := bs.backingBs.Get(c)
if err == nil {
return blk, nil
}
@@ -192,10 +192,10 @@ func (bs *AutobatchBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block,
return v, nil
}
return bs.Get(ctx, c)
return bs.Get(c)
}
func (bs *AutobatchBlockstore) DeleteBlock(context.Context, cid.Cid) error {
func (bs *AutobatchBlockstore) DeleteBlock(cid.Cid) error {
// if we wanted to support this, we would have to:
// - flush
// - delete from the backingBs (if present)
@@ -204,13 +204,13 @@ func (bs *AutobatchBlockstore) DeleteBlock(context.Context, cid.Cid) error {
return xerrors.New("deletion is unsupported")
}
func (bs *AutobatchBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
func (bs *AutobatchBlockstore) DeleteMany(cids []cid.Cid) error {
// see note in DeleteBlock()
return xerrors.New("deletion is unsupported")
}
func (bs *AutobatchBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
_, err := bs.Get(ctx, c)
func (bs *AutobatchBlockstore) Has(c cid.Cid) (bool, error) {
_, err := bs.Get(c)
if err == nil {
return true, nil
}
@@ -221,8 +221,8 @@ func (bs *AutobatchBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error)
return false, err
}
func (bs *AutobatchBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
blk, err := bs.Get(ctx, c)
func (bs *AutobatchBlockstore) GetSize(c cid.Cid) (int, error) {
blk, err := bs.Get(c)
if err != nil {
return 0, err
}
@@ -230,9 +230,9 @@ func (bs *AutobatchBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, err
return len(blk.RawData()), nil
}
func (bs *AutobatchBlockstore) PutMany(ctx context.Context, blks []block.Block) error {
func (bs *AutobatchBlockstore) PutMany(blks []block.Block) error {
for _, blk := range blks {
if err := bs.Put(ctx, blk); err != nil {
if err := bs.Put(blk); err != nil {
return err
}
}
@@ -252,8 +252,8 @@ func (bs *AutobatchBlockstore) HashOnRead(enabled bool) {
bs.backingBs.HashOnRead(enabled)
}
func (bs *AutobatchBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error {
blk, err := bs.Get(ctx, cid)
func (bs *AutobatchBlockstore) View(cid cid.Cid, callback func([]byte) error) error {
blk, err := bs.Get(cid)
if err != nil {
return err
}
+8 -8
View File
@@ -525,7 +525,7 @@ func (b *Blockstore) Size() (int64, error) {
// View implements blockstore.Viewer, which leverages zero-copy read-only
// access to values.
func (b *Blockstore) View(ctx context.Context, cid cid.Cid, fn func([]byte) error) error {
func (b *Blockstore) View(cid cid.Cid, fn func([]byte) error) error {
if err := b.access(); err != nil {
return err
}
@@ -552,7 +552,7 @@ func (b *Blockstore) View(ctx context.Context, cid cid.Cid, fn func([]byte) erro
}
// Has implements Blockstore.Has.
func (b *Blockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
func (b *Blockstore) Has(cid cid.Cid) (bool, error) {
if err := b.access(); err != nil {
return false, err
}
@@ -582,7 +582,7 @@ func (b *Blockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
}
// Get implements Blockstore.Get.
func (b *Blockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
func (b *Blockstore) Get(cid cid.Cid) (blocks.Block, error) {
if !cid.Defined() {
return nil, blockstore.ErrNotFound
}
@@ -619,7 +619,7 @@ func (b *Blockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error)
}
// GetSize implements Blockstore.GetSize.
func (b *Blockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
func (b *Blockstore) GetSize(cid cid.Cid) (int, error) {
if err := b.access(); err != nil {
return 0, err
}
@@ -652,7 +652,7 @@ func (b *Blockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
}
// Put implements Blockstore.Put.
func (b *Blockstore) Put(ctx context.Context, block blocks.Block) error {
func (b *Blockstore) Put(block blocks.Block) error {
if err := b.access(); err != nil {
return err
}
@@ -691,7 +691,7 @@ func (b *Blockstore) Put(ctx context.Context, block blocks.Block) error {
}
// PutMany implements Blockstore.PutMany.
func (b *Blockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
func (b *Blockstore) PutMany(blocks []blocks.Block) error {
if err := b.access(); err != nil {
return err
}
@@ -755,7 +755,7 @@ func (b *Blockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
}
// DeleteBlock implements Blockstore.DeleteBlock.
func (b *Blockstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
func (b *Blockstore) DeleteBlock(cid cid.Cid) error {
if err := b.access(); err != nil {
return err
}
@@ -774,7 +774,7 @@ func (b *Blockstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
})
}
func (b *Blockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
func (b *Blockstore) DeleteMany(cids []cid.Cid) error {
if err := b.access(); err != nil {
return err
}
+6 -8
View File
@@ -2,7 +2,6 @@ package badgerbs
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"os"
@@ -99,7 +98,6 @@ func openBlockstore(optsSupplier func(path string) Options) func(tb testing.TB,
}
func testMove(t *testing.T, optsF func(string) Options) {
ctx := context.Background()
basePath, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
@@ -124,7 +122,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
// add some blocks
for i := 0; i < 10; i++ {
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
err := db.Put(ctx, blk)
err := db.Put(blk)
if err != nil {
t.Fatal(err)
}
@@ -134,7 +132,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
// delete some of them
for i := 5; i < 10; i++ {
c := have[i].Cid()
err := db.DeleteBlock(ctx, c)
err := db.DeleteBlock(c)
if err != nil {
t.Fatal(err)
}
@@ -147,7 +145,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
g.Go(func() error {
for i := 10; i < 1000; i++ {
blk := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
err := db.Put(ctx, blk)
err := db.Put(blk)
if err != nil {
return err
}
@@ -167,7 +165,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
// now check that we have all the blocks in have and none in the deleted lists
checkBlocks := func() {
for _, blk := range have {
has, err := db.Has(ctx, blk.Cid())
has, err := db.Has(blk.Cid())
if err != nil {
t.Fatal(err)
}
@@ -176,7 +174,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
t.Fatal("missing block")
}
blk2, err := db.Get(ctx, blk.Cid())
blk2, err := db.Get(blk.Cid())
if err != nil {
t.Fatal(err)
}
@@ -187,7 +185,7 @@ func testMove(t *testing.T, optsF func(string) Options) {
}
for _, c := range deleted {
has, err := db.Has(ctx, c)
has, err := db.Has(c)
if err != nil {
t.Fatal(err)
}
+24 -34
View File
@@ -44,31 +44,28 @@ func (s *Suite) RunTests(t *testing.T, prefix string) {
}
func (s *Suite) TestGetWhenKeyNotPresent(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
}
c := cid.NewCidV0(u.Hash([]byte("stuff")))
bl, err := bs.Get(ctx, c)
bl, err := bs.Get(c)
require.Nil(t, bl)
require.Equal(t, blockstore.ErrNotFound, err)
}
func (s *Suite) TestGetWhenKeyIsNil(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
}
_, err := bs.Get(ctx, cid.Undef)
_, err := bs.Get(cid.Undef)
require.Equal(t, blockstore.ErrNotFound, err)
}
func (s *Suite) TestPutThenGetBlock(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -76,16 +73,15 @@ func (s *Suite) TestPutThenGetBlock(t *testing.T) {
orig := blocks.NewBlock([]byte("some data"))
err := bs.Put(ctx, orig)
err := bs.Put(orig)
require.NoError(t, err)
fetched, err := bs.Get(ctx, orig.Cid())
fetched, err := bs.Get(orig.Cid())
require.NoError(t, err)
require.Equal(t, orig.RawData(), fetched.RawData())
}
func (s *Suite) TestHas(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -93,20 +89,19 @@ func (s *Suite) TestHas(t *testing.T) {
orig := blocks.NewBlock([]byte("some data"))
err := bs.Put(ctx, orig)
err := bs.Put(orig)
require.NoError(t, err)
ok, err := bs.Has(ctx, orig.Cid())
ok, err := bs.Has(orig.Cid())
require.NoError(t, err)
require.True(t, ok)
ok, err = bs.Has(ctx, blocks.NewBlock([]byte("another thing")).Cid())
ok, err = bs.Has(blocks.NewBlock([]byte("another thing")).Cid())
require.NoError(t, err)
require.False(t, ok)
}
func (s *Suite) TestCidv0v1(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -114,17 +109,15 @@ func (s *Suite) TestCidv0v1(t *testing.T) {
orig := blocks.NewBlock([]byte("some data"))
err := bs.Put(ctx, orig)
err := bs.Put(orig)
require.NoError(t, err)
fetched, err := bs.Get(ctx, cid.NewCidV1(cid.DagProtobuf, orig.Cid().Hash()))
fetched, err := bs.Get(cid.NewCidV1(cid.DagProtobuf, orig.Cid().Hash()))
require.NoError(t, err)
require.Equal(t, orig.RawData(), fetched.RawData())
}
func (s *Suite) TestPutThenGetSizeBlock(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -134,21 +127,21 @@ func (s *Suite) TestPutThenGetSizeBlock(t *testing.T) {
missingBlock := blocks.NewBlock([]byte("missingBlock"))
emptyBlock := blocks.NewBlock([]byte{})
err := bs.Put(ctx, block)
err := bs.Put(block)
require.NoError(t, err)
blockSize, err := bs.GetSize(ctx, block.Cid())
blockSize, err := bs.GetSize(block.Cid())
require.NoError(t, err)
require.Len(t, block.RawData(), blockSize)
err = bs.Put(ctx, emptyBlock)
err = bs.Put(emptyBlock)
require.NoError(t, err)
emptySize, err := bs.GetSize(ctx, emptyBlock.Cid())
emptySize, err := bs.GetSize(emptyBlock.Cid())
require.NoError(t, err)
require.Zero(t, emptySize)
missingSize, err := bs.GetSize(ctx, missingBlock.Cid())
missingSize, err := bs.GetSize(missingBlock.Cid())
require.Equal(t, blockstore.ErrNotFound, err)
require.Equal(t, -1, missingSize)
}
@@ -210,7 +203,6 @@ func (s *Suite) TestDoubleClose(t *testing.T) {
}
func (s *Suite) TestReopenPutGet(t *testing.T) {
ctx := context.Background()
bs, path := s.NewBlockstore(t)
c, ok := bs.(io.Closer)
if !ok {
@@ -218,7 +210,7 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
}
orig := blocks.NewBlock([]byte("some data"))
err := bs.Put(ctx, orig)
err := bs.Put(orig)
require.NoError(t, err)
err = c.Close()
@@ -227,7 +219,7 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
bs, err = s.OpenBlockstore(t, path)
require.NoError(t, err)
fetched, err := bs.Get(ctx, orig.Cid())
fetched, err := bs.Get(orig.Cid())
require.NoError(t, err)
require.Equal(t, orig.RawData(), fetched.RawData())
@@ -236,7 +228,6 @@ func (s *Suite) TestReopenPutGet(t *testing.T) {
}
func (s *Suite) TestPutMany(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -247,15 +238,15 @@ func (s *Suite) TestPutMany(t *testing.T) {
blocks.NewBlock([]byte("foo2")),
blocks.NewBlock([]byte("foo3")),
}
err := bs.PutMany(ctx, blks)
err := bs.PutMany(blks)
require.NoError(t, err)
for _, blk := range blks {
fetched, err := bs.Get(ctx, blk.Cid())
fetched, err := bs.Get(blk.Cid())
require.NoError(t, err)
require.Equal(t, blk.RawData(), fetched.RawData())
ok, err := bs.Has(ctx, blk.Cid())
ok, err := bs.Has(blk.Cid())
require.NoError(t, err)
require.True(t, ok)
}
@@ -268,7 +259,6 @@ func (s *Suite) TestPutMany(t *testing.T) {
}
func (s *Suite) TestDelete(t *testing.T) {
ctx := context.Background()
bs, _ := s.NewBlockstore(t)
if c, ok := bs.(io.Closer); ok {
defer func() { require.NoError(t, c.Close()) }()
@@ -279,10 +269,10 @@ func (s *Suite) TestDelete(t *testing.T) {
blocks.NewBlock([]byte("foo2")),
blocks.NewBlock([]byte("foo3")),
}
err := bs.PutMany(ctx, blks)
err := bs.PutMany(blks)
require.NoError(t, err)
err = bs.DeleteBlock(ctx, blks[1].Cid())
err = bs.DeleteBlock(blks[1].Cid())
require.NoError(t, err)
ch, err := bs.AllKeysChan(context.Background())
@@ -295,17 +285,17 @@ func (s *Suite) TestDelete(t *testing.T) {
cid.NewCidV1(cid.Raw, blks[2].Cid().Hash()),
})
has, err := bs.Has(ctx, blks[1].Cid())
has, err := bs.Has(blks[1].Cid())
require.NoError(t, err)
require.False(t, has)
}
func insertBlocks(t *testing.T, bs blockstore.BasicBlockstore, count int) []cid.Cid {
ctx := context.Background()
keys := make([]cid.Cid, count)
for i := 0; i < count; i++ {
block := blocks.NewBlock([]byte(fmt.Sprintf("some data %d", i)))
err := bs.Put(ctx, block)
err := bs.Put(block)
require.NoError(t, err)
// NewBlock assigns a CIDv0; we convert it to CIDv1 because that's what
// the store returns.
+5 -7
View File
@@ -1,8 +1,6 @@
package blockstore
import (
"context"
cid "github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore"
logging "github.com/ipfs/go-log/v2"
@@ -29,7 +27,7 @@ type BasicBlockstore = blockstore.Blockstore
type Viewer = blockstore.Viewer
type BatchDeleter interface {
DeleteMany(ctx context.Context, cids []cid.Cid) error
DeleteMany(cids []cid.Cid) error
}
// BlockstoreIterator is a trait for efficient iteration
@@ -95,17 +93,17 @@ type adaptedBlockstore struct {
var _ Blockstore = (*adaptedBlockstore)(nil)
func (a *adaptedBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) error {
blk, err := a.Get(ctx, cid)
func (a *adaptedBlockstore) View(cid cid.Cid, callback func([]byte) error) error {
blk, err := a.Get(cid)
if err != nil {
return err
}
return callback(blk.RawData())
}
func (a *adaptedBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
func (a *adaptedBlockstore) DeleteMany(cids []cid.Cid) error {
for _, cid := range cids {
err := a.DeleteBlock(ctx, cid)
err := a.DeleteBlock(cid)
if err != nil {
return err
}
+23 -23
View File
@@ -88,34 +88,34 @@ func (bs *BufferedBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid,
return out, nil
}
func (bs *BufferedBlockstore) DeleteBlock(ctx context.Context, c cid.Cid) error {
if err := bs.read.DeleteBlock(ctx, c); err != nil {
func (bs *BufferedBlockstore) DeleteBlock(c cid.Cid) error {
if err := bs.read.DeleteBlock(c); err != nil {
return err
}
return bs.write.DeleteBlock(ctx, c)
return bs.write.DeleteBlock(c)
}
func (bs *BufferedBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
if err := bs.read.DeleteMany(ctx, cids); err != nil {
func (bs *BufferedBlockstore) DeleteMany(cids []cid.Cid) error {
if err := bs.read.DeleteMany(cids); err != nil {
return err
}
return bs.write.DeleteMany(ctx, cids)
return bs.write.DeleteMany(cids)
}
func (bs *BufferedBlockstore) View(ctx context.Context, c cid.Cid, callback func([]byte) error) error {
func (bs *BufferedBlockstore) View(c cid.Cid, callback func([]byte) error) error {
// both stores are viewable.
if err := bs.write.View(ctx, c, callback); err == ErrNotFound {
if err := bs.write.View(c, callback); err == ErrNotFound {
// not found in write blockstore; fall through.
} else {
return err // propagate errors, or nil, i.e. found.
}
return bs.read.View(ctx, c, callback)
return bs.read.View(c, callback)
}
func (bs *BufferedBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block, error) {
if out, err := bs.write.Get(ctx, c); err != nil {
func (bs *BufferedBlockstore) Get(c cid.Cid) (block.Block, error) {
if out, err := bs.write.Get(c); err != nil {
if err != ErrNotFound {
return nil, err
}
@@ -123,20 +123,20 @@ func (bs *BufferedBlockstore) Get(ctx context.Context, c cid.Cid) (block.Block,
return out, nil
}
return bs.read.Get(ctx, c)
return bs.read.Get(c)
}
func (bs *BufferedBlockstore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
s, err := bs.read.GetSize(ctx, c)
func (bs *BufferedBlockstore) GetSize(c cid.Cid) (int, error) {
s, err := bs.read.GetSize(c)
if err == ErrNotFound || s == 0 {
return bs.write.GetSize(ctx, c)
return bs.write.GetSize(c)
}
return s, err
}
func (bs *BufferedBlockstore) Put(ctx context.Context, blk block.Block) error {
has, err := bs.read.Has(ctx, blk.Cid()) // TODO: consider dropping this check
func (bs *BufferedBlockstore) Put(blk block.Block) error {
has, err := bs.read.Has(blk.Cid()) // TODO: consider dropping this check
if err != nil {
return err
}
@@ -145,11 +145,11 @@ func (bs *BufferedBlockstore) Put(ctx context.Context, blk block.Block) error {
return nil
}
return bs.write.Put(ctx, blk)
return bs.write.Put(blk)
}
func (bs *BufferedBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error) {
has, err := bs.write.Has(ctx, c)
func (bs *BufferedBlockstore) Has(c cid.Cid) (bool, error) {
has, err := bs.write.Has(c)
if err != nil {
return false, err
}
@@ -157,7 +157,7 @@ func (bs *BufferedBlockstore) Has(ctx context.Context, c cid.Cid) (bool, error)
return true, nil
}
return bs.read.Has(ctx, c)
return bs.read.Has(c)
}
func (bs *BufferedBlockstore) HashOnRead(hor bool) {
@@ -165,8 +165,8 @@ func (bs *BufferedBlockstore) HashOnRead(hor bool) {
bs.write.HashOnRead(hor)
}
func (bs *BufferedBlockstore) PutMany(ctx context.Context, blks []block.Block) error {
return bs.write.PutMany(ctx, blks)
func (bs *BufferedBlockstore) PutMany(blks []block.Block) error {
return bs.write.PutMany(blks)
}
func (bs *BufferedBlockstore) Read() Blockstore {
+12 -12
View File
@@ -18,39 +18,39 @@ func NewDiscardStore(bs Blockstore) Blockstore {
return &discardstore{bs: bs}
}
func (b *discardstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
return b.bs.Has(ctx, cid)
func (b *discardstore) Has(cid cid.Cid) (bool, error) {
return b.bs.Has(cid)
}
func (b *discardstore) HashOnRead(hor bool) {
b.bs.HashOnRead(hor)
}
func (b *discardstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
return b.bs.Get(ctx, cid)
func (b *discardstore) Get(cid cid.Cid) (blocks.Block, error) {
return b.bs.Get(cid)
}
func (b *discardstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
return b.bs.GetSize(ctx, cid)
func (b *discardstore) GetSize(cid cid.Cid) (int, error) {
return b.bs.GetSize(cid)
}
func (b *discardstore) View(ctx context.Context, cid cid.Cid, f func([]byte) error) error {
return b.bs.View(ctx, cid, f)
func (b *discardstore) View(cid cid.Cid, f func([]byte) error) error {
return b.bs.View(cid, f)
}
func (b *discardstore) Put(ctx context.Context, blk blocks.Block) error {
func (b *discardstore) Put(blk blocks.Block) error {
return nil
}
func (b *discardstore) PutMany(ctx context.Context, blks []blocks.Block) error {
func (b *discardstore) PutMany(blks []blocks.Block) error {
return nil
}
func (b *discardstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
func (b *discardstore) DeleteBlock(cid cid.Cid) error {
return nil
}
func (b *discardstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
func (b *discardstore) DeleteMany(cids []cid.Cid) error {
return nil
}
+5 -5
View File
@@ -71,14 +71,14 @@ func (fbs *FallbackStore) getFallback(c cid.Cid) (blocks.Block, error) {
// chain bitswap puts blocks in temp blockstore which is cleaned up
// every few min (to drop any messages we fetched but don't want)
// in this case we want to keep this block around
if err := fbs.Put(ctx, b); err != nil {
if err := fbs.Put(b); err != nil {
return nil, xerrors.Errorf("persisting fallback-fetched block: %w", err)
}
return b, nil
}
func (fbs *FallbackStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
b, err := fbs.Blockstore.Get(ctx, c)
func (fbs *FallbackStore) Get(c cid.Cid) (blocks.Block, error) {
b, err := fbs.Blockstore.Get(c)
switch err {
case nil:
return b, nil
@@ -89,8 +89,8 @@ func (fbs *FallbackStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, err
}
}
func (fbs *FallbackStore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
sz, err := fbs.Blockstore.GetSize(ctx, c)
func (fbs *FallbackStore) GetSize(c cid.Cid) (int, error) {
sz, err := fbs.Blockstore.GetSize(c)
switch err {
case nil:
return sz, nil
+16 -16
View File
@@ -38,7 +38,7 @@ func decodeCid(cid cid.Cid) (inline bool, data []byte, err error) {
return false, nil, err
}
func (b *idstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
func (b *idstore) Has(cid cid.Cid) (bool, error) {
inline, _, err := decodeCid(cid)
if err != nil {
return false, xerrors.Errorf("error decoding Cid: %w", err)
@@ -48,10 +48,10 @@ func (b *idstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
return true, nil
}
return b.bs.Has(ctx, cid)
return b.bs.Has(cid)
}
func (b *idstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
func (b *idstore) Get(cid cid.Cid) (blocks.Block, error) {
inline, data, err := decodeCid(cid)
if err != nil {
return nil, xerrors.Errorf("error decoding Cid: %w", err)
@@ -61,10 +61,10 @@ func (b *idstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
return blocks.NewBlockWithCid(data, cid)
}
return b.bs.Get(ctx, cid)
return b.bs.Get(cid)
}
func (b *idstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
func (b *idstore) GetSize(cid cid.Cid) (int, error) {
inline, data, err := decodeCid(cid)
if err != nil {
return 0, xerrors.Errorf("error decoding Cid: %w", err)
@@ -74,10 +74,10 @@ func (b *idstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
return len(data), err
}
return b.bs.GetSize(ctx, cid)
return b.bs.GetSize(cid)
}
func (b *idstore) View(ctx context.Context, cid cid.Cid, cb func([]byte) error) error {
func (b *idstore) View(cid cid.Cid, cb func([]byte) error) error {
inline, data, err := decodeCid(cid)
if err != nil {
return xerrors.Errorf("error decoding Cid: %w", err)
@@ -87,10 +87,10 @@ func (b *idstore) View(ctx context.Context, cid cid.Cid, cb func([]byte) error)
return cb(data)
}
return b.bs.View(ctx, cid, cb)
return b.bs.View(cid, cb)
}
func (b *idstore) Put(ctx context.Context, blk blocks.Block) error {
func (b *idstore) Put(blk blocks.Block) error {
inline, _, err := decodeCid(blk.Cid())
if err != nil {
return xerrors.Errorf("error decoding Cid: %w", err)
@@ -100,10 +100,10 @@ func (b *idstore) Put(ctx context.Context, blk blocks.Block) error {
return nil
}
return b.bs.Put(ctx, blk)
return b.bs.Put(blk)
}
func (b *idstore) PutMany(ctx context.Context, blks []blocks.Block) error {
func (b *idstore) PutMany(blks []blocks.Block) error {
toPut := make([]blocks.Block, 0, len(blks))
for _, blk := range blks {
inline, _, err := decodeCid(blk.Cid())
@@ -118,13 +118,13 @@ func (b *idstore) PutMany(ctx context.Context, blks []blocks.Block) error {
}
if len(toPut) > 0 {
return b.bs.PutMany(ctx, toPut)
return b.bs.PutMany(toPut)
}
return nil
}
func (b *idstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
func (b *idstore) DeleteBlock(cid cid.Cid) error {
inline, _, err := decodeCid(cid)
if err != nil {
return xerrors.Errorf("error decoding Cid: %w", err)
@@ -134,10 +134,10 @@ func (b *idstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
return nil
}
return b.bs.DeleteBlock(ctx, cid)
return b.bs.DeleteBlock(cid)
}
func (b *idstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
func (b *idstore) DeleteMany(cids []cid.Cid) error {
toDelete := make([]cid.Cid, 0, len(cids))
for _, cid := range cids {
inline, _, err := decodeCid(cid)
@@ -152,7 +152,7 @@ func (b *idstore) DeleteMany(ctx context.Context, cids []cid.Cid) error {
}
if len(toDelete) > 0 {
return b.bs.DeleteMany(ctx, toDelete)
return b.bs.DeleteMany(toDelete)
}
return nil
+11 -11
View File
@@ -79,12 +79,12 @@ func NewRemoteIPFSBlockstore(ctx context.Context, maddr multiaddr.Multiaddr, onl
return Adapt(bs), nil
}
func (i *IPFSBlockstore) DeleteBlock(ctx context.Context, cid cid.Cid) error {
func (i *IPFSBlockstore) DeleteBlock(cid cid.Cid) error {
return xerrors.Errorf("not supported")
}
func (i *IPFSBlockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
_, err := i.offlineAPI.Block().Stat(ctx, path.IpldPath(cid))
func (i *IPFSBlockstore) Has(cid cid.Cid) (bool, error) {
_, err := i.offlineAPI.Block().Stat(i.ctx, path.IpldPath(cid))
if err != nil {
// The underlying client is running in Offline mode.
// Stat() will fail with an err if the block isn't in the
@@ -99,8 +99,8 @@ func (i *IPFSBlockstore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
return true, nil
}
func (i *IPFSBlockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
rd, err := i.api.Block().Get(ctx, path.IpldPath(cid))
func (i *IPFSBlockstore) Get(cid cid.Cid) (blocks.Block, error) {
rd, err := i.api.Block().Get(i.ctx, path.IpldPath(cid))
if err != nil {
return nil, xerrors.Errorf("getting ipfs block: %w", err)
}
@@ -113,8 +113,8 @@ func (i *IPFSBlockstore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, er
return blocks.NewBlockWithCid(data, cid)
}
func (i *IPFSBlockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
st, err := i.api.Block().Stat(ctx, path.IpldPath(cid))
func (i *IPFSBlockstore) GetSize(cid cid.Cid) (int, error) {
st, err := i.api.Block().Stat(i.ctx, path.IpldPath(cid))
if err != nil {
return 0, xerrors.Errorf("getting ipfs block: %w", err)
}
@@ -122,23 +122,23 @@ func (i *IPFSBlockstore) GetSize(ctx context.Context, cid cid.Cid) (int, error)
return st.Size(), nil
}
func (i *IPFSBlockstore) Put(ctx context.Context, block blocks.Block) error {
func (i *IPFSBlockstore) Put(block blocks.Block) error {
mhd, err := multihash.Decode(block.Cid().Hash())
if err != nil {
return err
}
_, err = i.api.Block().Put(ctx, bytes.NewReader(block.RawData()),
_, err = i.api.Block().Put(i.ctx, bytes.NewReader(block.RawData()),
options.Block.Hash(mhd.Code, mhd.Length),
options.Block.Format(cid.CodecToStr[block.Cid().Type()]))
return err
}
func (i *IPFSBlockstore) PutMany(ctx context.Context, blocks []blocks.Block) error {
func (i *IPFSBlockstore) PutMany(blocks []blocks.Block) error {
// TODO: could be done in parallel
for _, block := range blocks {
if err := i.Put(ctx, block); err != nil {
if err := i.Put(block); err != nil {
return err
}
}
+9 -9
View File
@@ -15,24 +15,24 @@ func NewMemory() MemBlockstore {
// MemBlockstore is a terminal blockstore that keeps blocks in memory.
type MemBlockstore map[cid.Cid]blocks.Block
func (m MemBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
func (m MemBlockstore) DeleteBlock(k cid.Cid) error {
delete(m, k)
return nil
}
func (m MemBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
func (m MemBlockstore) DeleteMany(ks []cid.Cid) error {
for _, k := range ks {
delete(m, k)
}
return nil
}
func (m MemBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
func (m MemBlockstore) Has(k cid.Cid) (bool, error) {
_, ok := m[k]
return ok, nil
}
func (m MemBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
func (m MemBlockstore) View(k cid.Cid, callback func([]byte) error) error {
b, ok := m[k]
if !ok {
return ErrNotFound
@@ -40,7 +40,7 @@ func (m MemBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte
return callback(b.RawData())
}
func (m MemBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
func (m MemBlockstore) Get(k cid.Cid) (blocks.Block, error) {
b, ok := m[k]
if !ok {
return nil, ErrNotFound
@@ -49,7 +49,7 @@ func (m MemBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error)
}
// GetSize returns the CIDs mapped BlockSize
func (m MemBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
func (m MemBlockstore) GetSize(k cid.Cid) (int, error) {
b, ok := m[k]
if !ok {
return 0, ErrNotFound
@@ -58,7 +58,7 @@ func (m MemBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
}
// Put puts a given block to the underlying datastore
func (m MemBlockstore) Put(ctx context.Context, b blocks.Block) error {
func (m MemBlockstore) Put(b blocks.Block) error {
// Convert to a basic block for safety, but try to reuse the existing
// block if it's already a basic block.
k := b.Cid()
@@ -76,9 +76,9 @@ func (m MemBlockstore) Put(ctx context.Context, b blocks.Block) error {
// PutMany puts a slice of blocks at the same time using batching
// capabilities of the underlying datastore whenever possible.
func (m MemBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
func (m MemBlockstore) PutMany(bs []blocks.Block) error {
for _, b := range bs {
_ = m.Put(ctx, b) // can't fail
_ = m.Put(b) // can't fail
}
return nil
}
+15 -3
View File
@@ -10,12 +10,20 @@ import (
var errMarkSetClosed = errors.New("markset closed")
// MarkSet is an interface for tracking CIDs during chain and object walks
// MarkSet is a utility to keep track of seen CID, and later query for them.
//
// * If the expected dataset is large, it can be backed by a datastore (e.g. bbolt).
// * If a probabilistic result is acceptable, it can be backed by a bloom filter
type MarkSet interface {
ObjectVisitor
Mark(cid.Cid) error
Has(cid.Cid) (bool, error)
Close() error
SetConcurrent()
}
type MarkSetVisitor interface {
MarkSet
ObjectVisitor
}
type MarkSetEnv interface {
@@ -23,7 +31,11 @@ type MarkSetEnv interface {
// name is a unique name for this markset, mapped to the filesystem in disk-backed environments
// sizeHint is a hint about the expected size of the markset
Create(name string, sizeHint int64) (MarkSet, error)
// Close closes the markset
// CreateVisitor is like Create, but returns a wider interface that supports atomic visits.
// It may not be supported by some markset types (e.g. bloom).
CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error)
// SupportsVisitor returns true if the marksets created by this environment support the visitor interface.
SupportsVisitor() bool
Close() error
}
+12 -1
View File
@@ -34,6 +34,7 @@ type BadgerMarkSet struct {
}
var _ MarkSet = (*BadgerMarkSet)(nil)
var _ MarkSetVisitor = (*BadgerMarkSet)(nil)
var badgerMarkSetBatchSize = 16384
@@ -47,7 +48,7 @@ func NewBadgerMarkSetEnv(path string) (MarkSetEnv, error) {
return &BadgerMarkSetEnv{path: msPath}, nil
}
func (e *BadgerMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
func (e *BadgerMarkSetEnv) create(name string, sizeHint int64) (*BadgerMarkSet, error) {
name += ".tmp"
path := filepath.Join(e.path, name)
@@ -67,6 +68,16 @@ func (e *BadgerMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error)
return ms, nil
}
func (e *BadgerMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
return e.create(name, sizeHint)
}
func (e *BadgerMarkSetEnv) CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error) {
return e.create(name, sizeHint)
}
func (e *BadgerMarkSetEnv) SupportsVisitor() bool { return true }
func (e *BadgerMarkSetEnv) Close() error {
return os.RemoveAll(e.path)
}
+34 -10
View File
@@ -13,27 +13,42 @@ var _ MarkSetEnv = (*MapMarkSetEnv)(nil)
type MapMarkSet struct {
mx sync.RWMutex
set map[string]struct{}
ts bool
}
var _ MarkSet = (*MapMarkSet)(nil)
var _ MarkSetVisitor = (*MapMarkSet)(nil)
func NewMapMarkSetEnv() (*MapMarkSetEnv, error) {
return &MapMarkSetEnv{}, nil
}
func (e *MapMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
func (e *MapMarkSetEnv) create(name string, sizeHint int64) (*MapMarkSet, error) {
return &MapMarkSet{
set: make(map[string]struct{}, sizeHint),
}, nil
}
func (e *MapMarkSetEnv) Create(name string, sizeHint int64) (MarkSet, error) {
return e.create(name, sizeHint)
}
func (e *MapMarkSetEnv) CreateVisitor(name string, sizeHint int64) (MarkSetVisitor, error) {
return e.create(name, sizeHint)
}
func (e *MapMarkSetEnv) SupportsVisitor() bool { return true }
func (e *MapMarkSetEnv) Close() error {
return nil
}
func (s *MapMarkSet) Mark(cid cid.Cid) error {
s.mx.Lock()
defer s.mx.Unlock()
if s.ts {
s.mx.Lock()
defer s.mx.Unlock()
}
if s.set == nil {
return errMarkSetClosed
@@ -44,8 +59,10 @@ func (s *MapMarkSet) Mark(cid cid.Cid) error {
}
func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
s.mx.RLock()
defer s.mx.RUnlock()
if s.ts {
s.mx.RLock()
defer s.mx.RUnlock()
}
if s.set == nil {
return false, errMarkSetClosed
@@ -56,8 +73,10 @@ func (s *MapMarkSet) Has(cid cid.Cid) (bool, error) {
}
func (s *MapMarkSet) Visit(c cid.Cid) (bool, error) {
s.mx.Lock()
defer s.mx.Unlock()
if s.ts {
s.mx.Lock()
defer s.mx.Unlock()
}
if s.set == nil {
return false, errMarkSetClosed
@@ -73,9 +92,14 @@ func (s *MapMarkSet) Visit(c cid.Cid) (bool, error) {
}
func (s *MapMarkSet) Close() error {
s.mx.Lock()
defer s.mx.Unlock()
if s.ts {
s.mx.Lock()
defer s.mx.Unlock()
}
s.set = nil
return nil
}
func (s *MapMarkSet) SetConcurrent() {
s.ts = true
}
+1 -1
View File
@@ -167,7 +167,7 @@ func testMarkSetVisitor(t *testing.T, lsType string) {
}
defer env.Close() //nolint:errcheck
visitor, err := env.Create("test", 0)
visitor, err := env.CreateVisitor("test", 0)
if err != nil {
t.Fatal(err)
}
+27 -23
View File
@@ -186,6 +186,10 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
return nil, err
}
if !markSetEnv.SupportsVisitor() {
return nil, xerrors.Errorf("markset type does not support atomic visitors")
}
// and now we can make a SplitStore
ss := &SplitStore{
cfg: cfg,
@@ -212,17 +216,17 @@ func Open(path string, ds dstore.Datastore, hot, cold bstore.Blockstore, cfg *Co
}
// Blockstore interface
func (s *SplitStore) DeleteBlock(_ context.Context, _ cid.Cid) error {
func (s *SplitStore) DeleteBlock(_ cid.Cid) error {
// afaict we don't seem to be using this method, so it's not implemented
return errors.New("DeleteBlock not implemented on SplitStore; don't do this Luke!") //nolint
}
func (s *SplitStore) DeleteMany(_ context.Context, _ []cid.Cid) error {
func (s *SplitStore) DeleteMany(_ []cid.Cid) error {
// afaict we don't seem to be using this method, so it's not implemented
return errors.New("DeleteMany not implemented on SplitStore; don't do this Luke!") //nolint
}
func (s *SplitStore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
func (s *SplitStore) Has(cid cid.Cid) (bool, error) {
if isIdentiyCid(cid) {
return true, nil
}
@@ -230,7 +234,7 @@ func (s *SplitStore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
s.txnLk.RLock()
defer s.txnLk.RUnlock()
has, err := s.hot.Has(ctx, cid)
has, err := s.hot.Has(cid)
if err != nil {
return has, err
@@ -241,10 +245,10 @@ func (s *SplitStore) Has(ctx context.Context, cid cid.Cid) (bool, error) {
return true, nil
}
return s.cold.Has(ctx, cid)
return s.cold.Has(cid)
}
func (s *SplitStore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error) {
func (s *SplitStore) Get(cid cid.Cid) (blocks.Block, error) {
if isIdentiyCid(cid) {
data, err := decodeIdentityCid(cid)
if err != nil {
@@ -257,7 +261,7 @@ func (s *SplitStore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error)
s.txnLk.RLock()
defer s.txnLk.RUnlock()
blk, err := s.hot.Get(ctx, cid)
blk, err := s.hot.Get(cid)
switch err {
case nil:
@@ -269,7 +273,7 @@ func (s *SplitStore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error)
s.debug.LogReadMiss(cid)
}
blk, err = s.cold.Get(ctx, cid)
blk, err = s.cold.Get(cid)
if err == nil {
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
@@ -281,7 +285,7 @@ func (s *SplitStore) Get(ctx context.Context, cid cid.Cid) (blocks.Block, error)
}
}
func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
func (s *SplitStore) GetSize(cid cid.Cid) (int, error) {
if isIdentiyCid(cid) {
data, err := decodeIdentityCid(cid)
if err != nil {
@@ -294,7 +298,7 @@ func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
s.txnLk.RLock()
defer s.txnLk.RUnlock()
size, err := s.hot.GetSize(ctx, cid)
size, err := s.hot.GetSize(cid)
switch err {
case nil:
@@ -306,7 +310,7 @@ func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
s.debug.LogReadMiss(cid)
}
size, err = s.cold.GetSize(ctx, cid)
size, err = s.cold.GetSize(cid)
if err == nil {
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
}
@@ -317,7 +321,7 @@ func (s *SplitStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
}
}
func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error {
func (s *SplitStore) Put(blk blocks.Block) error {
if isIdentiyCid(blk.Cid()) {
return nil
}
@@ -325,7 +329,7 @@ func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error {
s.txnLk.RLock()
defer s.txnLk.RUnlock()
err := s.hot.Put(ctx, blk)
err := s.hot.Put(blk)
if err != nil {
return err
}
@@ -336,7 +340,7 @@ func (s *SplitStore) Put(ctx context.Context, blk blocks.Block) error {
return nil
}
func (s *SplitStore) PutMany(ctx context.Context, blks []blocks.Block) error {
func (s *SplitStore) PutMany(blks []blocks.Block) error {
// filter identites
idcids := 0
for _, blk := range blks {
@@ -370,7 +374,7 @@ func (s *SplitStore) PutMany(ctx context.Context, blks []blocks.Block) error {
s.txnLk.RLock()
defer s.txnLk.RUnlock()
err := s.hot.PutMany(ctx, blks)
err := s.hot.PutMany(blks)
if err != nil {
return err
}
@@ -426,7 +430,7 @@ func (s *SplitStore) HashOnRead(enabled bool) {
s.cold.HashOnRead(enabled)
}
func (s *SplitStore) View(ctx context.Context, cid cid.Cid, cb func([]byte) error) error {
func (s *SplitStore) View(cid cid.Cid, cb func([]byte) error) error {
if isIdentiyCid(cid) {
data, err := decodeIdentityCid(cid)
if err != nil {
@@ -447,14 +451,14 @@ func (s *SplitStore) View(ctx context.Context, cid cid.Cid, cb func([]byte) erro
s.protectView(cid)
defer s.viewDone()
err := s.hot.View(ctx, cid, cb)
err := s.hot.View(cid, cb)
switch err {
case bstore.ErrNotFound:
if s.isWarm() {
s.debug.LogReadMiss(cid)
}
err = s.cold.View(ctx, cid, cb)
err = s.cold.View(cid, cb)
if err == nil {
stats.Record(s.ctx, metrics.SplitstoreMiss.M(1))
}
@@ -498,7 +502,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
// load base epoch from metadata ds
// if none, then use current epoch because it's a fresh start
bs, err := s.ds.Get(s.ctx, baseEpochKey)
bs, err := s.ds.Get(baseEpochKey)
switch err {
case nil:
s.baseEpoch = bytesToEpoch(bs)
@@ -519,7 +523,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
}
// load warmup epoch from metadata ds
bs, err = s.ds.Get(s.ctx, warmupEpochKey)
bs, err = s.ds.Get(warmupEpochKey)
switch err {
case nil:
s.warmupEpoch = bytesToEpoch(bs)
@@ -532,7 +536,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
}
// load markSetSize from metadata ds to provide a size hint for marksets
bs, err = s.ds.Get(s.ctx, markSetSizeKey)
bs, err = s.ds.Get(markSetSizeKey)
switch err {
case nil:
s.markSetSize = bytesToInt64(bs)
@@ -543,7 +547,7 @@ func (s *SplitStore) Start(chain ChainAccessor, us stmgr.UpgradeSchedule) error
}
// load compactionIndex from metadata ds to provide a hint as to when to perform moving gc
bs, err = s.ds.Get(s.ctx, compactionIndexKey)
bs, err = s.ds.Get(compactionIndexKey)
switch err {
case nil:
s.compactionIndex = bytesToInt64(bs)
@@ -605,5 +609,5 @@ func (s *SplitStore) checkClosing() error {
func (s *SplitStore) setBaseEpoch(epoch abi.ChainEpoch) error {
s.baseEpoch = epoch
return s.ds.Put(s.ctx, baseEpochKey, epochToBytes(epoch))
return s.ds.Put(baseEpochKey, epochToBytes(epoch))
}
+8 -13
View File
@@ -4,7 +4,6 @@ import (
"fmt"
"os"
"path/filepath"
"sync"
"sync/atomic"
"time"
@@ -68,10 +67,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
}
defer output.Close() //nolint:errcheck
var mx sync.Mutex
write := func(format string, args ...interface{}) {
mx.Lock()
defer mx.Unlock()
_, err := fmt.Fprintf(output, format+"\n", args...)
if err != nil {
log.Warnf("error writing check output: %s", err)
@@ -86,10 +82,9 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
write("compaction index: %d", s.compactionIndex)
write("--")
coldCnt := new(int64)
missingCnt := new(int64)
var coldCnt, missingCnt int64
visitor, err := s.markSetEnv.Create("check", 0)
visitor, err := s.markSetEnv.CreateVisitor("check", 0)
if err != nil {
return xerrors.Errorf("error creating visitor: %w", err)
}
@@ -101,7 +96,7 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
return errStopWalk
}
has, err := s.hot.Has(s.ctx, c)
has, err := s.hot.Has(c)
if err != nil {
return xerrors.Errorf("error checking hotstore: %w", err)
}
@@ -110,16 +105,16 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
return nil
}
has, err = s.cold.Has(s.ctx, c)
has, err = s.cold.Has(c)
if err != nil {
return xerrors.Errorf("error checking coldstore: %w", err)
}
if has {
atomic.AddInt64(coldCnt, 1)
coldCnt++
write("cold object reference: %s", c)
} else {
atomic.AddInt64(missingCnt, 1)
missingCnt++
write("missing object reference: %s", c)
return errStopWalk
}
@@ -133,9 +128,9 @@ func (s *SplitStore) doCheck(curTs *types.TipSet) error {
return err
}
log.Infow("check done", "cold", *coldCnt, "missing", *missingCnt)
log.Infow("check done", "cold", coldCnt, "missing", missingCnt)
write("--")
write("cold: %d missing: %d", *coldCnt, *missingCnt)
write("cold: %d missing: %d", coldCnt, missingCnt)
write("DONE")
return nil
+35 -68
View File
@@ -5,7 +5,6 @@ import (
"errors"
"runtime"
"sort"
"sync"
"sync/atomic"
"time"
@@ -228,7 +227,7 @@ func (s *SplitStore) trackTxnRefMany(cids []cid.Cid) {
}
// protect all pending transactional references
func (s *SplitStore) protectTxnRefs(markSet MarkSet) error {
func (s *SplitStore) protectTxnRefs(markSet MarkSetVisitor) error {
for {
var txnRefs map[cid.Cid]struct{}
@@ -300,14 +299,14 @@ func (s *SplitStore) protectTxnRefs(markSet MarkSet) error {
// transactionally protect a reference by walking the object and marking.
// concurrent markings are short circuited by checking the markset.
func (s *SplitStore) doTxnProtect(root cid.Cid, markSet MarkSet) error {
func (s *SplitStore) doTxnProtect(root cid.Cid, markSet MarkSetVisitor) error {
if err := s.checkClosing(); err != nil {
return err
}
// Note: cold objects are deleted heaviest first, so the consituents of an object
// cannot be deleted before the object itself.
return s.walkObjectIncomplete(root, newTmpVisitor(),
return s.walkObjectIncomplete(root, tmpVisitor(),
func(c cid.Cid) error {
if isUnitaryObject(c) {
return errStopWalk
@@ -398,7 +397,7 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
log.Infow("running compaction", "currentEpoch", currentEpoch, "baseEpoch", s.baseEpoch, "boundaryEpoch", boundaryEpoch, "inclMsgsEpoch", inclMsgsEpoch, "compactionIndex", s.compactionIndex)
markSet, err := s.markSetEnv.Create("live", s.markSetSize)
markSet, err := s.markSetEnv.CreateVisitor("live", s.markSetSize)
if err != nil {
return xerrors.Errorf("error creating mark set: %w", err)
}
@@ -578,13 +577,13 @@ func (s *SplitStore) doCompact(curTs *types.TipSet) error {
return xerrors.Errorf("error saving base epoch: %w", err)
}
err = s.ds.Put(s.ctx, markSetSizeKey, int64ToBytes(s.markSetSize))
err = s.ds.Put(markSetSizeKey, int64ToBytes(s.markSetSize))
if err != nil {
return xerrors.Errorf("error saving mark set size: %w", err)
}
s.compactionIndex++
err = s.ds.Put(s.ctx, compactionIndexKey, int64ToBytes(s.compactionIndex))
err = s.ds.Put(compactionIndexKey, int64ToBytes(s.compactionIndex))
if err != nil {
return xerrors.Errorf("error saving compaction index: %w", err)
}
@@ -603,8 +602,8 @@ func (s *SplitStore) beginTxnProtect() {
s.txnMissing = make(map[cid.Cid]struct{})
}
func (s *SplitStore) beginTxnMarking(markSet MarkSet) {
log.Info("beginning transactional marking")
func (s *SplitStore) beginTxnMarking(markSet MarkSetVisitor) {
markSet.SetConcurrent()
}
func (s *SplitStore) endTxnProtect() {
@@ -622,33 +621,26 @@ func (s *SplitStore) endTxnProtect() {
func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEpoch,
visitor ObjectVisitor, f func(cid.Cid) error) error {
var walked ObjectVisitor
var mx sync.Mutex
// we copy the tipset first into a new slice, which allows us to reuse it in every epoch.
toWalk := make([]cid.Cid, len(ts.Cids()))
copy(toWalk, ts.Cids())
walkCnt := new(int64)
scanCnt := new(int64)
var walked *cid.Set
toWalk := ts.Cids()
walkCnt := 0
scanCnt := 0
stopWalk := func(_ cid.Cid) error { return errStopWalk }
walkBlock := func(c cid.Cid) error {
visit, err := walked.Visit(c)
if err != nil {
return err
}
if !visit {
if !walked.Visit(c) {
return nil
}
atomic.AddInt64(walkCnt, 1)
walkCnt++
if err := f(c); err != nil {
return err
}
var hdr types.BlockHeader
err = s.view(c, func(data []byte) error {
err := s.view(c, func(data []byte) error {
return hdr.UnmarshalCBOR(bytes.NewBuffer(data))
})
@@ -684,13 +676,11 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
if err := s.walkObject(hdr.ParentStateRoot, visitor, f); err != nil {
return xerrors.Errorf("error walking state root (cid: %s): %w", hdr.ParentStateRoot, err)
}
atomic.AddInt64(scanCnt, 1)
scanCnt++
}
if hdr.Height > 0 {
mx.Lock()
toWalk = append(toWalk, hdr.Parents...)
mx.Unlock()
}
return nil
@@ -702,43 +692,20 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
return err
}
workers := len(toWalk)
if workers > runtime.NumCPU()/2 {
workers = runtime.NumCPU() / 2
}
if workers < 2 {
workers = 2
}
// the walk is BFS, so we can reset the walked set in every iteration and avoid building up
// a set that contains all blocks (1M epochs -> 5M blocks -> 200MB worth of memory and growing
// over time)
walked = newConcurrentVisitor()
workch := make(chan cid.Cid, len(toWalk))
for _, c := range toWalk {
workch <- c
}
close(workch)
toWalk = toWalk[:0]
g := new(errgroup.Group)
for i := 0; i < workers; i++ {
g.Go(func() error {
for c := range workch {
if err := walkBlock(c); err != nil {
return xerrors.Errorf("error walking block (cid: %s): %w", c, err)
}
}
return nil
})
}
if err := g.Wait(); err != nil {
return err
walked = cid.NewSet()
walking := toWalk
toWalk = nil
for _, c := range walking {
if err := walkBlock(c); err != nil {
return xerrors.Errorf("error walking block (cid: %s): %w", c, err)
}
}
}
log.Infow("chain walk done", "walked", *walkCnt, "scanned", *scanCnt)
log.Infow("chain walk done", "walked", walkCnt, "scanned", scanCnt)
return nil
}
@@ -868,10 +835,10 @@ func (s *SplitStore) view(c cid.Cid, cb func([]byte) error) error {
return cb(data)
}
err := s.hot.View(s.ctx, c, cb)
err := s.hot.View(c, cb)
switch err {
case bstore.ErrNotFound:
return s.cold.View(s.ctx, c, cb)
return s.cold.View(c, cb)
default:
return err
@@ -883,13 +850,13 @@ func (s *SplitStore) has(c cid.Cid) (bool, error) {
return true, nil
}
has, err := s.hot.Has(s.ctx, c)
has, err := s.hot.Has(c)
if has || err != nil {
return has, err
}
return s.cold.Has(s.ctx, c)
return s.cold.Has(c)
}
func (s *SplitStore) moveColdBlocks(cold []cid.Cid) error {
@@ -900,7 +867,7 @@ func (s *SplitStore) moveColdBlocks(cold []cid.Cid) error {
return err
}
blk, err := s.hot.Get(s.ctx, c)
blk, err := s.hot.Get(c)
if err != nil {
if err == bstore.ErrNotFound {
log.Warnf("hotstore missing block %s", c)
@@ -912,7 +879,7 @@ func (s *SplitStore) moveColdBlocks(cold []cid.Cid) error {
batch = append(batch, blk)
if len(batch) == batchSize {
err = s.cold.PutMany(s.ctx, batch)
err = s.cold.PutMany(batch)
if err != nil {
return xerrors.Errorf("error putting batch to coldstore: %w", err)
}
@@ -921,7 +888,7 @@ func (s *SplitStore) moveColdBlocks(cold []cid.Cid) error {
}
if len(batch) > 0 {
err := s.cold.PutMany(s.ctx, batch)
err := s.cold.PutMany(batch)
if err != nil {
return xerrors.Errorf("error putting batch to coldstore: %w", err)
}
@@ -1044,7 +1011,7 @@ func (s *SplitStore) purgeBatch(cids []cid.Cid, deleteBatch func([]cid.Cid) erro
return nil
}
func (s *SplitStore) purge(cids []cid.Cid, markSet MarkSet) error {
func (s *SplitStore) purge(cids []cid.Cid, markSet MarkSetVisitor) error {
deadCids := make([]cid.Cid, 0, batchSize)
var purgeCnt, liveCnt int
defer func() {
@@ -1091,7 +1058,7 @@ func (s *SplitStore) purge(cids []cid.Cid, markSet MarkSet) error {
deadCids = append(deadCids, c)
}
err := s.hot.DeleteMany(s.ctx, deadCids)
err := s.hot.DeleteMany(deadCids)
if err != nil {
return xerrors.Errorf("error purging cold objects: %w", err)
}
@@ -1110,7 +1077,7 @@ func (s *SplitStore) purge(cids []cid.Cid, markSet MarkSet) error {
// have this gem[TM].
// My best guess is that they are parent message receipts or yet to be computed state roots; magik
// thinks the cause may be block validation.
func (s *SplitStore) waitForMissingRefs(markSet MarkSet) {
func (s *SplitStore) waitForMissingRefs(markSet MarkSetVisitor) {
s.txnLk.Lock()
missing := s.txnMissing
s.txnMissing = nil
@@ -1139,7 +1106,7 @@ func (s *SplitStore) waitForMissingRefs(markSet MarkSet) {
}
towalk := missing
visitor := newTmpVisitor()
visitor := tmpVisitor()
missing = make(map[cid.Cid]struct{})
for c := range towalk {
+18 -18
View File
@@ -20,28 +20,28 @@ func (s *SplitStore) Expose() bstore.Blockstore {
return &exposedSplitStore{s: s}
}
func (es *exposedSplitStore) DeleteBlock(_ context.Context, _ cid.Cid) error {
func (es *exposedSplitStore) DeleteBlock(_ cid.Cid) error {
return errors.New("DeleteBlock: operation not supported")
}
func (es *exposedSplitStore) DeleteMany(_ context.Context, _ []cid.Cid) error {
func (es *exposedSplitStore) DeleteMany(_ []cid.Cid) error {
return errors.New("DeleteMany: operation not supported")
}
func (es *exposedSplitStore) Has(ctx context.Context, c cid.Cid) (bool, error) {
func (es *exposedSplitStore) Has(c cid.Cid) (bool, error) {
if isIdentiyCid(c) {
return true, nil
}
has, err := es.s.hot.Has(ctx, c)
has, err := es.s.hot.Has(c)
if has || err != nil {
return has, err
}
return es.s.cold.Has(ctx, c)
return es.s.cold.Has(c)
}
func (es *exposedSplitStore) Get(ctx context.Context, c cid.Cid) (blocks.Block, error) {
func (es *exposedSplitStore) Get(c cid.Cid) (blocks.Block, error) {
if isIdentiyCid(c) {
data, err := decodeIdentityCid(c)
if err != nil {
@@ -51,16 +51,16 @@ func (es *exposedSplitStore) Get(ctx context.Context, c cid.Cid) (blocks.Block,
return blocks.NewBlockWithCid(data, c)
}
blk, err := es.s.hot.Get(ctx, c)
blk, err := es.s.hot.Get(c)
switch err {
case bstore.ErrNotFound:
return es.s.cold.Get(ctx, c)
return es.s.cold.Get(c)
default:
return blk, err
}
}
func (es *exposedSplitStore) GetSize(ctx context.Context, c cid.Cid) (int, error) {
func (es *exposedSplitStore) GetSize(c cid.Cid) (int, error) {
if isIdentiyCid(c) {
data, err := decodeIdentityCid(c)
if err != nil {
@@ -70,21 +70,21 @@ func (es *exposedSplitStore) GetSize(ctx context.Context, c cid.Cid) (int, error
return len(data), nil
}
size, err := es.s.hot.GetSize(ctx, c)
size, err := es.s.hot.GetSize(c)
switch err {
case bstore.ErrNotFound:
return es.s.cold.GetSize(ctx, c)
return es.s.cold.GetSize(c)
default:
return size, err
}
}
func (es *exposedSplitStore) Put(ctx context.Context, blk blocks.Block) error {
return es.s.Put(ctx, blk)
func (es *exposedSplitStore) Put(blk blocks.Block) error {
return es.s.Put(blk)
}
func (es *exposedSplitStore) PutMany(ctx context.Context, blks []blocks.Block) error {
return es.s.PutMany(ctx, blks)
func (es *exposedSplitStore) PutMany(blks []blocks.Block) error {
return es.s.PutMany(blks)
}
func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
@@ -93,7 +93,7 @@ func (es *exposedSplitStore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, e
func (es *exposedSplitStore) HashOnRead(enabled bool) {}
func (es *exposedSplitStore) View(ctx context.Context, c cid.Cid, f func([]byte) error) error {
func (es *exposedSplitStore) View(c cid.Cid, f func([]byte) error) error {
if isIdentiyCid(c) {
data, err := decodeIdentityCid(c)
if err != nil {
@@ -103,10 +103,10 @@ func (es *exposedSplitStore) View(ctx context.Context, c cid.Cid, f func([]byte)
return f(data)
}
err := es.s.hot.View(ctx, c, f)
err := es.s.hot.View(c, f)
switch err {
case bstore.ErrNotFound:
return es.s.cold.View(ctx, c, f)
return es.s.cold.View(c, f)
default:
return err
+23 -25
View File
@@ -30,7 +30,6 @@ func init() {
}
func testSplitStore(t *testing.T, cfg *Config) {
ctx := context.Background()
chain := &mockChain{t: t}
// the myriads of stores
@@ -40,7 +39,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
// this is necessary to avoid the garbage mock puts in the blocks
garbage := blocks.NewBlock([]byte{1, 2, 3})
err := cold.Put(ctx, garbage)
err := cold.Put(garbage)
if err != nil {
t.Fatal(err)
}
@@ -61,21 +60,21 @@ func testSplitStore(t *testing.T, cfg *Config) {
t.Fatal(err)
}
err = cold.Put(ctx, blk)
err = cold.Put(blk)
if err != nil {
t.Fatal(err)
}
// create a garbage block that is protected with a rgistered protector
protected := blocks.NewBlock([]byte("protected!"))
err = hot.Put(ctx, protected)
err = hot.Put(protected)
if err != nil {
t.Fatal(err)
}
// and another one that is not protected
unprotected := blocks.NewBlock([]byte("unprotected!"))
err = hot.Put(ctx, unprotected)
err = hot.Put(unprotected)
if err != nil {
t.Fatal(err)
}
@@ -110,11 +109,11 @@ func testSplitStore(t *testing.T, cfg *Config) {
if err != nil {
t.Fatal(err)
}
err = ss.Put(ctx, stateRoot)
err = ss.Put(stateRoot)
if err != nil {
t.Fatal(err)
}
err = ss.Put(ctx, sblk)
err = ss.Put(sblk)
if err != nil {
t.Fatal(err)
}
@@ -177,7 +176,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
}
// ensure our protected block is still there
has, err := hot.Has(ctx, protected.Cid())
has, err := hot.Has(protected.Cid())
if err != nil {
t.Fatal(err)
}
@@ -187,7 +186,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
}
// ensure our unprotected block is in the coldstore now
has, err = hot.Has(ctx, unprotected.Cid())
has, err = hot.Has(unprotected.Cid())
if err != nil {
t.Fatal(err)
}
@@ -196,7 +195,7 @@ func testSplitStore(t *testing.T, cfg *Config) {
t.Fatal("unprotected block is still in hotstore")
}
has, err = cold.Has(ctx, unprotected.Cid())
has, err = cold.Has(unprotected.Cid())
if err != nil {
t.Fatal(err)
}
@@ -223,7 +222,6 @@ func TestSplitStoreCompactionWithBadger(t *testing.T) {
}
func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
ctx := context.Background()
chain := &mockChain{t: t}
// the myriads of stores
@@ -233,7 +231,7 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
// this is necessary to avoid the garbage mock puts in the blocks
garbage := blocks.NewBlock([]byte{1, 2, 3})
err := cold.Put(ctx, garbage)
err := cold.Put(garbage)
if err != nil {
t.Fatal(err)
}
@@ -254,7 +252,7 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
t.Fatal(err)
}
err = cold.Put(ctx, blk)
err = cold.Put(blk)
if err != nil {
t.Fatal(err)
}
@@ -290,11 +288,11 @@ func TestSplitStoreSuppressCompactionNearUpgrade(t *testing.T) {
if err != nil {
t.Fatal(err)
}
err = ss.Put(ctx, stateRoot)
err = ss.Put(stateRoot)
if err != nil {
t.Fatal(err)
}
err = ss.Put(ctx, sblk)
err = ss.Put(sblk)
if err != nil {
t.Fatal(err)
}
@@ -433,7 +431,7 @@ func newMockStore() *mockStore {
return &mockStore{set: make(map[cid.Cid]blocks.Block)}
}
func (b *mockStore) Has(_ context.Context, cid cid.Cid) (bool, error) {
func (b *mockStore) Has(cid cid.Cid) (bool, error) {
b.mx.Lock()
defer b.mx.Unlock()
_, ok := b.set[cid]
@@ -442,7 +440,7 @@ func (b *mockStore) Has(_ context.Context, cid cid.Cid) (bool, error) {
func (b *mockStore) HashOnRead(hor bool) {}
func (b *mockStore) Get(_ context.Context, cid cid.Cid) (blocks.Block, error) {
func (b *mockStore) Get(cid cid.Cid) (blocks.Block, error) {
b.mx.Lock()
defer b.mx.Unlock()
@@ -453,8 +451,8 @@ func (b *mockStore) Get(_ context.Context, cid cid.Cid) (blocks.Block, error) {
return blk, nil
}
func (b *mockStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
blk, err := b.Get(ctx, cid)
func (b *mockStore) GetSize(cid cid.Cid) (int, error) {
blk, err := b.Get(cid)
if err != nil {
return 0, err
}
@@ -462,15 +460,15 @@ func (b *mockStore) GetSize(ctx context.Context, cid cid.Cid) (int, error) {
return len(blk.RawData()), nil
}
func (b *mockStore) View(ctx context.Context, cid cid.Cid, f func([]byte) error) error {
blk, err := b.Get(ctx, cid)
func (b *mockStore) View(cid cid.Cid, f func([]byte) error) error {
blk, err := b.Get(cid)
if err != nil {
return err
}
return f(blk.RawData())
}
func (b *mockStore) Put(_ context.Context, blk blocks.Block) error {
func (b *mockStore) Put(blk blocks.Block) error {
b.mx.Lock()
defer b.mx.Unlock()
@@ -478,7 +476,7 @@ func (b *mockStore) Put(_ context.Context, blk blocks.Block) error {
return nil
}
func (b *mockStore) PutMany(_ context.Context, blks []blocks.Block) error {
func (b *mockStore) PutMany(blks []blocks.Block) error {
b.mx.Lock()
defer b.mx.Unlock()
@@ -488,7 +486,7 @@ func (b *mockStore) PutMany(_ context.Context, blks []blocks.Block) error {
return nil
}
func (b *mockStore) DeleteBlock(_ context.Context, cid cid.Cid) error {
func (b *mockStore) DeleteBlock(cid cid.Cid) error {
b.mx.Lock()
defer b.mx.Unlock()
@@ -496,7 +494,7 @@ func (b *mockStore) DeleteBlock(_ context.Context, cid cid.Cid) error {
return nil
}
func (b *mockStore) DeleteMany(_ context.Context, cids []cid.Cid) error {
func (b *mockStore) DeleteMany(cids []cid.Cid) error {
b.mx.Lock()
defer b.mx.Unlock()
+16 -21
View File
@@ -1,7 +1,6 @@
package splitstore
import (
"sync"
"sync/atomic"
"time"
@@ -56,13 +55,12 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
if WarmupBoundary < epoch {
boundaryEpoch = epoch - WarmupBoundary
}
var mx sync.Mutex
batchHot := make([]blocks.Block, 0, batchSize)
count := new(int64)
xcount := new(int64)
missing := new(int64)
count := int64(0)
xcount := int64(0)
missing := int64(0)
visitor, err := s.markSetEnv.Create("warmup", 0)
visitor, err := s.markSetEnv.CreateVisitor("warmup", 0)
if err != nil {
return xerrors.Errorf("error creating visitor: %w", err)
}
@@ -75,9 +73,9 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
return errStopWalk
}
atomic.AddInt64(count, 1)
count++
has, err := s.hot.Has(s.ctx, c)
has, err := s.hot.Has(c)
if err != nil {
return err
}
@@ -86,28 +84,25 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
return nil
}
blk, err := s.cold.Get(s.ctx, c)
blk, err := s.cold.Get(c)
if err != nil {
if err == bstore.ErrNotFound {
atomic.AddInt64(missing, 1)
missing++
return errStopWalk
}
return err
}
atomic.AddInt64(xcount, 1)
xcount++
mx.Lock()
batchHot = append(batchHot, blk)
if len(batchHot) == batchSize {
err = s.hot.PutMany(s.ctx, batchHot)
err = s.hot.PutMany(batchHot)
if err != nil {
mx.Unlock()
return err
}
batchHot = batchHot[:0]
}
mx.Unlock()
return nil
})
@@ -117,22 +112,22 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
}
if len(batchHot) > 0 {
err = s.hot.PutMany(s.ctx, batchHot)
err = s.hot.PutMany(batchHot)
if err != nil {
return err
}
}
log.Infow("warmup stats", "visited", *count, "warm", *xcount, "missing", *missing)
log.Infow("warmup stats", "visited", count, "warm", xcount, "missing", missing)
s.markSetSize = *count + *count>>2 // overestimate a bit
err = s.ds.Put(s.ctx, markSetSizeKey, int64ToBytes(s.markSetSize))
s.markSetSize = count + count>>2 // overestimate a bit
err = s.ds.Put(markSetSizeKey, int64ToBytes(s.markSetSize))
if err != nil {
log.Warnf("error saving mark set size: %s", err)
}
// save the warmup epoch
err = s.ds.Put(s.ctx, warmupEpochKey, epochToBytes(epoch))
err = s.ds.Put(warmupEpochKey, epochToBytes(epoch))
if err != nil {
return xerrors.Errorf("error saving warm up epoch: %w", err)
}
@@ -141,7 +136,7 @@ func (s *SplitStore) doWarmup(curTs *types.TipSet) error {
s.mx.Unlock()
// also save the compactionIndex, as this is used as an indicator of warmup for upgraded nodes
err = s.ds.Put(s.ctx, compactionIndexKey, int64ToBytes(s.compactionIndex))
err = s.ds.Put(compactionIndexKey, int64ToBytes(s.compactionIndex))
if err != nil {
return xerrors.Errorf("error saving compaction index: %w", err)
}
+5 -25
View File
@@ -1,8 +1,6 @@
package splitstore
import (
"sync"
cid "github.com/ipfs/go-cid"
)
@@ -19,34 +17,16 @@ func (v *noopVisitor) Visit(_ cid.Cid) (bool, error) {
return true, nil
}
type tmpVisitor struct {
type cidSetVisitor struct {
set *cid.Set
}
var _ ObjectVisitor = (*tmpVisitor)(nil)
var _ ObjectVisitor = (*cidSetVisitor)(nil)
func (v *tmpVisitor) Visit(c cid.Cid) (bool, error) {
func (v *cidSetVisitor) Visit(c cid.Cid) (bool, error) {
return v.set.Visit(c), nil
}
func newTmpVisitor() ObjectVisitor {
return &tmpVisitor{set: cid.NewSet()}
}
type concurrentVisitor struct {
mx sync.Mutex
set *cid.Set
}
var _ ObjectVisitor = (*concurrentVisitor)(nil)
func newConcurrentVisitor() *concurrentVisitor {
return &concurrentVisitor{set: cid.NewSet()}
}
func (v *concurrentVisitor) Visit(c cid.Cid) (bool, error) {
v.mx.Lock()
defer v.mx.Unlock()
return v.set.Visit(c), nil
func tmpVisitor() ObjectVisitor {
return &cidSetVisitor{set: cid.NewSet()}
}
+16 -16
View File
@@ -20,53 +20,53 @@ type SyncBlockstore struct {
bs MemBlockstore // specifically use a memStore to save indirection overhead.
}
func (m *SyncBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
func (m *SyncBlockstore) DeleteBlock(k cid.Cid) error {
m.mu.Lock()
defer m.mu.Unlock()
return m.bs.DeleteBlock(ctx, k)
return m.bs.DeleteBlock(k)
}
func (m *SyncBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
func (m *SyncBlockstore) DeleteMany(ks []cid.Cid) error {
m.mu.Lock()
defer m.mu.Unlock()
return m.bs.DeleteMany(ctx, ks)
return m.bs.DeleteMany(ks)
}
func (m *SyncBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
func (m *SyncBlockstore) Has(k cid.Cid) (bool, error) {
m.mu.RLock()
defer m.mu.RUnlock()
return m.bs.Has(ctx, k)
return m.bs.Has(k)
}
func (m *SyncBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
func (m *SyncBlockstore) View(k cid.Cid, callback func([]byte) error) error {
m.mu.RLock()
defer m.mu.RUnlock()
return m.bs.View(ctx, k, callback)
return m.bs.View(k, callback)
}
func (m *SyncBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
func (m *SyncBlockstore) Get(k cid.Cid) (blocks.Block, error) {
m.mu.RLock()
defer m.mu.RUnlock()
return m.bs.Get(ctx, k)
return m.bs.Get(k)
}
func (m *SyncBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
func (m *SyncBlockstore) GetSize(k cid.Cid) (int, error) {
m.mu.RLock()
defer m.mu.RUnlock()
return m.bs.GetSize(ctx, k)
return m.bs.GetSize(k)
}
func (m *SyncBlockstore) Put(ctx context.Context, b blocks.Block) error {
func (m *SyncBlockstore) Put(b blocks.Block) error {
m.mu.Lock()
defer m.mu.Unlock()
return m.bs.Put(ctx, b)
return m.bs.Put(b)
}
func (m *SyncBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
func (m *SyncBlockstore) PutMany(bs []blocks.Block) error {
m.mu.Lock()
defer m.mu.Unlock()
return m.bs.PutMany(ctx, bs)
return m.bs.PutMany(bs)
}
func (m *SyncBlockstore) AllKeysChan(ctx context.Context) (<-chan cid.Cid, error) {
+20 -20
View File
@@ -92,28 +92,28 @@ func (t *TimedCacheBlockstore) rotate() {
t.mu.Unlock()
}
func (t *TimedCacheBlockstore) Put(ctx context.Context, b blocks.Block) error {
func (t *TimedCacheBlockstore) Put(b blocks.Block) error {
// Don't check the inactive set here. We want to keep this block for at
// least one interval.
t.mu.Lock()
defer t.mu.Unlock()
return t.active.Put(ctx, b)
return t.active.Put(b)
}
func (t *TimedCacheBlockstore) PutMany(ctx context.Context, bs []blocks.Block) error {
func (t *TimedCacheBlockstore) PutMany(bs []blocks.Block) error {
t.mu.Lock()
defer t.mu.Unlock()
return t.active.PutMany(ctx, bs)
return t.active.PutMany(bs)
}
func (t *TimedCacheBlockstore) View(ctx context.Context, k cid.Cid, callback func([]byte) error) error {
func (t *TimedCacheBlockstore) View(k cid.Cid, callback func([]byte) error) error {
// The underlying blockstore is always a "mem" blockstore so there's no difference,
// from a performance perspective, between view & get. So we call Get to avoid
// calling an arbitrary callback while holding a lock.
t.mu.RLock()
block, err := t.active.Get(ctx, k)
block, err := t.active.Get(k)
if err == ErrNotFound {
block, err = t.inactive.Get(ctx, k)
block, err = t.inactive.Get(k)
}
t.mu.RUnlock()
@@ -123,51 +123,51 @@ func (t *TimedCacheBlockstore) View(ctx context.Context, k cid.Cid, callback fun
return callback(block.RawData())
}
func (t *TimedCacheBlockstore) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
func (t *TimedCacheBlockstore) Get(k cid.Cid) (blocks.Block, error) {
t.mu.RLock()
defer t.mu.RUnlock()
b, err := t.active.Get(ctx, k)
b, err := t.active.Get(k)
if err == ErrNotFound {
b, err = t.inactive.Get(ctx, k)
b, err = t.inactive.Get(k)
}
return b, err
}
func (t *TimedCacheBlockstore) GetSize(ctx context.Context, k cid.Cid) (int, error) {
func (t *TimedCacheBlockstore) GetSize(k cid.Cid) (int, error) {
t.mu.RLock()
defer t.mu.RUnlock()
size, err := t.active.GetSize(ctx, k)
size, err := t.active.GetSize(k)
if err == ErrNotFound {
size, err = t.inactive.GetSize(ctx, k)
size, err = t.inactive.GetSize(k)
}
return size, err
}
func (t *TimedCacheBlockstore) Has(ctx context.Context, k cid.Cid) (bool, error) {
func (t *TimedCacheBlockstore) Has(k cid.Cid) (bool, error) {
t.mu.RLock()
defer t.mu.RUnlock()
if has, err := t.active.Has(ctx, k); err != nil {
if has, err := t.active.Has(k); err != nil {
return false, err
} else if has {
return true, nil
}
return t.inactive.Has(ctx, k)
return t.inactive.Has(k)
}
func (t *TimedCacheBlockstore) HashOnRead(_ bool) {
// no-op
}
func (t *TimedCacheBlockstore) DeleteBlock(ctx context.Context, k cid.Cid) error {
func (t *TimedCacheBlockstore) DeleteBlock(k cid.Cid) error {
t.mu.Lock()
defer t.mu.Unlock()
return multierr.Combine(t.active.DeleteBlock(ctx, k), t.inactive.DeleteBlock(ctx, k))
return multierr.Combine(t.active.DeleteBlock(k), t.inactive.DeleteBlock(k))
}
func (t *TimedCacheBlockstore) DeleteMany(ctx context.Context, ks []cid.Cid) error {
func (t *TimedCacheBlockstore) DeleteMany(ks []cid.Cid) error {
t.mu.Lock()
defer t.mu.Unlock()
return multierr.Combine(t.active.DeleteMany(ctx, ks), t.inactive.DeleteMany(ctx, ks))
return multierr.Combine(t.active.DeleteMany(ks), t.inactive.DeleteMany(ks))
}
func (t *TimedCacheBlockstore) AllKeysChan(_ context.Context) (<-chan cid.Cid, error) {
+11 -13
View File
@@ -19,8 +19,6 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
tc.clock = mClock
tc.doneRotatingCh = make(chan struct{})
ctx := context.Background()
_ = tc.Start(context.Background())
mClock.Add(1) // IDK why it is needed but it makes it work
@@ -29,18 +27,18 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
}()
b1 := blocks.NewBlock([]byte("foo"))
require.NoError(t, tc.Put(ctx, b1))
require.NoError(t, tc.Put(b1))
b2 := blocks.NewBlock([]byte("bar"))
require.NoError(t, tc.Put(ctx, b2))
require.NoError(t, tc.Put(b2))
b3 := blocks.NewBlock([]byte("baz"))
b1out, err := tc.Get(ctx, b1.Cid())
b1out, err := tc.Get(b1.Cid())
require.NoError(t, err)
require.Equal(t, b1.RawData(), b1out.RawData())
has, err := tc.Has(ctx, b1.Cid())
has, err := tc.Has(b1.Cid())
require.NoError(t, err)
require.True(t, has)
@@ -48,17 +46,17 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
<-tc.doneRotatingCh
// We should still have everything.
has, err = tc.Has(ctx, b1.Cid())
has, err = tc.Has(b1.Cid())
require.NoError(t, err)
require.True(t, has)
has, err = tc.Has(ctx, b2.Cid())
has, err = tc.Has(b2.Cid())
require.NoError(t, err)
require.True(t, has)
// extend b2, add b3.
require.NoError(t, tc.Put(ctx, b2))
require.NoError(t, tc.Put(ctx, b3))
require.NoError(t, tc.Put(b2))
require.NoError(t, tc.Put(b3))
// all keys once.
allKeys, err := tc.AllKeysChan(context.Background())
@@ -73,15 +71,15 @@ func TestTimedCacheBlockstoreSimple(t *testing.T) {
<-tc.doneRotatingCh
// should still have b2, and b3, but not b1
has, err = tc.Has(ctx, b1.Cid())
has, err = tc.Has(b1.Cid())
require.NoError(t, err)
require.False(t, has)
has, err = tc.Has(ctx, b2.Cid())
has, err = tc.Has(b2.Cid())
require.NoError(t, err)
require.True(t, has)
has, err = tc.Has(ctx, b3.Cid())
has, err = tc.Has(b3.Cid())
require.NoError(t, err)
require.True(t, has)
}
+16 -16
View File
@@ -19,72 +19,72 @@ func Union(stores ...Blockstore) Blockstore {
return unionBlockstore(stores)
}
func (m unionBlockstore) Has(ctx context.Context, cid cid.Cid) (has bool, err error) {
func (m unionBlockstore) Has(cid cid.Cid) (has bool, err error) {
for _, bs := range m {
if has, err = bs.Has(ctx, cid); has || err != nil {
if has, err = bs.Has(cid); has || err != nil {
break
}
}
return has, err
}
func (m unionBlockstore) Get(ctx context.Context, cid cid.Cid) (blk blocks.Block, err error) {
func (m unionBlockstore) Get(cid cid.Cid) (blk blocks.Block, err error) {
for _, bs := range m {
if blk, err = bs.Get(ctx, cid); err == nil || err != ErrNotFound {
if blk, err = bs.Get(cid); err == nil || err != ErrNotFound {
break
}
}
return blk, err
}
func (m unionBlockstore) View(ctx context.Context, cid cid.Cid, callback func([]byte) error) (err error) {
func (m unionBlockstore) View(cid cid.Cid, callback func([]byte) error) (err error) {
for _, bs := range m {
if err = bs.View(ctx, cid, callback); err == nil || err != ErrNotFound {
if err = bs.View(cid, callback); err == nil || err != ErrNotFound {
break
}
}
return err
}
func (m unionBlockstore) GetSize(ctx context.Context, cid cid.Cid) (size int, err error) {
func (m unionBlockstore) GetSize(cid cid.Cid) (size int, err error) {
for _, bs := range m {
if size, err = bs.GetSize(ctx, cid); err == nil || err != ErrNotFound {
if size, err = bs.GetSize(cid); err == nil || err != ErrNotFound {
break
}
}
return size, err
}
func (m unionBlockstore) Put(ctx context.Context, block blocks.Block) (err error) {
func (m unionBlockstore) Put(block blocks.Block) (err error) {
for _, bs := range m {
if err = bs.Put(ctx, block); err != nil {
if err = bs.Put(block); err != nil {
break
}
}
return err
}
func (m unionBlockstore) PutMany(ctx context.Context, blks []blocks.Block) (err error) {
func (m unionBlockstore) PutMany(blks []blocks.Block) (err error) {
for _, bs := range m {
if err = bs.PutMany(ctx, blks); err != nil {
if err = bs.PutMany(blks); err != nil {
break
}
}
return err
}
func (m unionBlockstore) DeleteBlock(ctx context.Context, cid cid.Cid) (err error) {
func (m unionBlockstore) DeleteBlock(cid cid.Cid) (err error) {
for _, bs := range m {
if err = bs.DeleteBlock(ctx, cid); err != nil {
if err = bs.DeleteBlock(cid); err != nil {
break
}
}
return err
}
func (m unionBlockstore) DeleteMany(ctx context.Context, cids []cid.Cid) (err error) {
func (m unionBlockstore) DeleteMany(cids []cid.Cid) (err error) {
for _, bs := range m {
if err = bs.DeleteMany(ctx, cids); err != nil {
if err = bs.DeleteMany(cids); err != nil {
break
}
}
+19 -21
View File
@@ -15,81 +15,79 @@ var (
)
func TestUnionBlockstore_Get(t *testing.T) {
ctx := context.Background()
m1 := NewMemory()
m2 := NewMemory()
_ = m1.Put(ctx, b1)
_ = m2.Put(ctx, b2)
_ = m1.Put(b1)
_ = m2.Put(b2)
u := Union(m1, m2)
v1, err := u.Get(ctx, b1.Cid())
v1, err := u.Get(b1.Cid())
require.NoError(t, err)
require.Equal(t, b1.RawData(), v1.RawData())
v2, err := u.Get(ctx, b2.Cid())
v2, err := u.Get(b2.Cid())
require.NoError(t, err)
require.Equal(t, b2.RawData(), v2.RawData())
}
func TestUnionBlockstore_Put_PutMany_Delete_AllKeysChan(t *testing.T) {
ctx := context.Background()
m1 := NewMemory()
m2 := NewMemory()
u := Union(m1, m2)
err := u.Put(ctx, b0)
err := u.Put(b0)
require.NoError(t, err)
var has bool
// write was broadcasted to all stores.
has, _ = m1.Has(ctx, b0.Cid())
has, _ = m1.Has(b0.Cid())
require.True(t, has)
has, _ = m2.Has(ctx, b0.Cid())
has, _ = m2.Has(b0.Cid())
require.True(t, has)
has, _ = u.Has(ctx, b0.Cid())
has, _ = u.Has(b0.Cid())
require.True(t, has)
// put many.
err = u.PutMany(ctx, []blocks.Block{b1, b2})
err = u.PutMany([]blocks.Block{b1, b2})
require.NoError(t, err)
// write was broadcasted to all stores.
has, _ = m1.Has(ctx, b1.Cid())
has, _ = m1.Has(b1.Cid())
require.True(t, has)
has, _ = m1.Has(ctx, b2.Cid())
has, _ = m1.Has(b2.Cid())
require.True(t, has)
has, _ = m2.Has(ctx, b1.Cid())
has, _ = m2.Has(b1.Cid())
require.True(t, has)
has, _ = m2.Has(ctx, b2.Cid())
has, _ = m2.Has(b2.Cid())
require.True(t, has)
// also in the union store.
has, _ = u.Has(ctx, b1.Cid())
has, _ = u.Has(b1.Cid())
require.True(t, has)
has, _ = u.Has(ctx, b2.Cid())
has, _ = u.Has(b2.Cid())
require.True(t, has)
// deleted from all stores.
err = u.DeleteBlock(ctx, b1.Cid())
err = u.DeleteBlock(b1.Cid())
require.NoError(t, err)
has, _ = u.Has(ctx, b1.Cid())
has, _ = u.Has(b1.Cid())
require.False(t, has)
has, _ = m1.Has(ctx, b1.Cid())
has, _ = m1.Has(b1.Cid())
require.False(t, has)
has, _ = m2.Has(ctx, b1.Cid())
has, _ = m2.Has(b1.Cid())
require.False(t, has)
// check that AllKeysChan returns b0 and b2, twice (once per backing store)
Binary file not shown.
Binary file not shown.
Binary file not shown.
-11
View File
@@ -13,17 +13,6 @@ import (
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
func IndexerIngestTopic(netName dtypes.NetworkName) string {
nn := string(netName)
// The network name testnetnet is here for historical reasons.
// Going forward we aim to use the name `mainnet` where possible.
if nn == "testnetnet" {
nn = "mainnet"
}
return "/indexer/ingest/" + nn
}
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
return protocol.ID("/fil/kad/" + string(netName))
}
+50
View File
@@ -1,4 +1,54 @@
{
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-61fa69f38b9cc771ba27b670124714b4ea77fbeae05e377fb859c4a43b73a30c.params": {
"cid": "Qma5WL6abSqYg9uUQAZ3EHS286bsNsha7oAGsJBD48Bq2q",
"digest": "c3ad7bb549470b82ad52ed070aebb4f4",
"sector_size": 536870912
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-61fa69f38b9cc771ba27b670124714b4ea77fbeae05e377fb859c4a43b73a30c.vk": {
"cid": "QmUa7f9JtJMsqJJ3s3ZXk6WyF4xJLE8FiqYskZGgk8GCDv",
"digest": "994c5b7d450ca9da348c910689f2dc7f",
"sector_size": 536870912
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-92180959e1918d26350b8e6cfe217bbdd0a2d8de51ebec269078b364b715ad63.params": {
"cid": "QmQiT4qBGodrVNEgVTDXxBNDdPbaD8Ag7Sx3ZTq1zHX79S",
"digest": "5aedd2cf3e5c0a15623d56a1b43110ad",
"sector_size": 8388608
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-92180959e1918d26350b8e6cfe217bbdd0a2d8de51ebec269078b364b715ad63.vk": {
"cid": "QmdcpKUQvHM8RFRVKbk1yHfEqMcBzhtFWKRp9SNEmWq37i",
"digest": "abd80269054d391a734febdac0d2e687",
"sector_size": 8388608
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-fb9e095bebdd77511c0269b967b4d87ba8b8a525edaa0e165de23ba454510194.params": {
"cid": "QmYM6Hg7mjmvA3ZHTsqkss1fkdyDju5dDmLiBZGJ5pz9y9",
"digest": "311f92a3e75036ced01b1c0025f1fa0c",
"sector_size": 2048
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-0-0-fb9e095bebdd77511c0269b967b4d87ba8b8a525edaa0e165de23ba454510194.vk": {
"cid": "QmaQsTLL3nc5dw6wAvaioJSBfd1jhQrA2o6ucFf7XeV74P",
"digest": "eadad9784969890d30f2749708c79771",
"sector_size": 2048
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-8-0-3b7f44a9362e3985369454947bc94022e118211e49fd672d52bec1cbfd599d18.params": {
"cid": "QmeNqDvsvyam4vqwCkstbxgb9S7RZEUeBDrJvBWKcpFKr6",
"digest": "532b53883ed4f794cb9d0db583d0df59",
"sector_size": 34359738368
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-8-0-3b7f44a9362e3985369454947bc94022e118211e49fd672d52bec1cbfd599d18.vk": {
"cid": "QmdLWr6moLUPScJZwoBckWqAeJkrBPAJPNLz8mWAfTdmXH",
"digest": "46990eb1bf5159c394a10309f269c1b6",
"sector_size": 34359738368
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-8-2-102e1444a7e9a97ebf1e3d6855dcc77e66c011ea66f936d9b2c508f87f2f83a7.params": {
"cid": "QmdQsi9uFhxK9cGwuK4rHuwKQoHkz6upYTCz4UdLiy1vA2",
"digest": "4223c63dbd94de1538006a14f37179e3",
"sector_size": 68719476736
},
"v28-empty-sector-update-merkletree-poseidon_hasher-8-8-2-102e1444a7e9a97ebf1e3d6855dcc77e66c011ea66f936d9b2c508f87f2f83a7.vk": {
"cid": "QmPirFX9wX99iMGA6zFY2CvcrdcDkj73X4MP6DLduvpbk9",
"digest": "ce39b614d788d3aef26bac1b28521d94",
"sector_size": 68719476736
},
"v28-proof-of-spacetime-fallback-merkletree-poseidon_hasher-8-0-0-0170db1f394b35d995252228ee359194b13199d259380541dc529fb0099096b0.params": {
"cid": "QmVxjFRyhmyQaZEtCh7nk2abc7LhFkzhnRX4rcHqCCpikR",
"digest": "7610b9f82bfc88405b7a832b651ce2f6",
+1 -1
View File
@@ -37,7 +37,7 @@ func BuildTypeString() string {
}
// BuildVersion is the local build version
const BuildVersion = "1.15.0-dev"
const BuildVersion = "1.14.0-rc4"
func UserVersion() string {
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
+4 -4
View File
@@ -13,7 +13,7 @@ func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) e
return xerrors.Errorf("called with empty tsk")
}
ts, err := syncer.ChainStore().LoadTipSet(ctx, tsk)
ts, err := syncer.ChainStore().LoadTipSet(tsk)
if err != nil {
tss, err := syncer.Exchange.GetBlocks(ctx, tsk, 1)
if err != nil {
@@ -28,7 +28,7 @@ func (syncer *Syncer) SyncCheckpoint(ctx context.Context, tsk types.TipSetKey) e
return xerrors.Errorf("failed to switch chain when syncing checkpoint: %w", err)
}
if err := syncer.ChainStore().SetCheckpoint(ctx, ts); err != nil {
if err := syncer.ChainStore().SetCheckpoint(ts); err != nil {
return xerrors.Errorf("failed to set the chain checkpoint: %w", err)
}
@@ -41,7 +41,7 @@ func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error {
return nil
}
if anc, err := syncer.store.IsAncestorOf(ctx, ts, hts); err == nil && anc {
if anc, err := syncer.store.IsAncestorOf(ts, hts); err == nil && anc {
return nil
}
@@ -50,7 +50,7 @@ func (syncer *Syncer) switchChain(ctx context.Context, ts *types.TipSet) error {
return xerrors.Errorf("failed to collect chain for checkpoint: %w", err)
}
if err := syncer.ChainStore().SetHead(ctx, ts); err != nil {
if err := syncer.ChainStore().SetHead(ts); err != nil {
return xerrors.Errorf("failed to set the chain head: %w", err)
}
return nil
+34 -28
View File
@@ -92,16 +92,16 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
partDone()
}()
makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (*vm.VM, error) {
makeVmWithBaseState := func(base cid.Cid) (*vm.VM, error) {
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: e,
Epoch: epoch,
Rand: r,
Bstore: sm.ChainStore().StateBlockstore(),
Actors: NewActorRegistry(),
Syscalls: sm.Syscalls,
CircSupplyCalc: sm.GetVMCirculatingSupply,
NetworkVersion: sm.GetNetworkVersion(ctx, e),
NtwkVersion: sm.GetNtwkVersion,
BaseFee: baseFee,
LookbackState: stmgr.LookbackStateGetterForTipset(sm, ts),
}
@@ -109,7 +109,12 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
return sm.VMConstructor()(ctx, vmopt)
}
runCron := func(vmCron *vm.VM, epoch abi.ChainEpoch) error {
vmi, err := makeVmWithBaseState(pstate)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
runCron := func(epoch abi.ChainEpoch) error {
cronMsg := &types.Message{
To: cron.Address,
From: builtin.SystemActorAddr,
@@ -121,58 +126,59 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
Method: cron.Methods.EpochTick,
Params: nil,
}
ret, err := vmCron.ApplyImplicitMessage(ctx, cronMsg)
ret, err := vmi.ApplyImplicitMessage(ctx, cronMsg)
if err != nil {
return xerrors.Errorf("running cron: %w", err)
return err
}
if em != nil {
if err := em.MessageApplied(ctx, ts, cronMsg.Cid(), cronMsg, ret, true); err != nil {
return xerrors.Errorf("callback failed on cron message: %w", err)
}
}
if ret.ExitCode != 0 {
return xerrors.Errorf("cron exit was non-zero: %d", ret.ExitCode)
return xerrors.Errorf("CheckProofSubmissions exit was non-zero: %d", ret.ExitCode)
}
return nil
}
for i := parentEpoch; i < epoch; i++ {
var err error
if i > parentEpoch {
vmCron, err := makeVmWithBaseStateAndEpoch(pstate, i)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making cron vm: %w", err)
}
// run cron for null rounds if any
if err = runCron(vmCron, i); err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("running cron: %w", err)
if err := runCron(i); err != nil {
return cid.Undef, cid.Undef, err
}
pstate, err = vmCron.Flush(ctx)
pstate, err = vmi.Flush(ctx)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("flushing cron vm: %w", err)
return cid.Undef, cid.Undef, xerrors.Errorf("flushing vm: %w", err)
}
}
// handle state forks
// XXX: The state tree
pstate, err = sm.HandleStateForks(ctx, pstate, i, em, ts)
newState, err := sm.HandleStateForks(ctx, pstate, i, em, ts)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("error handling state forks: %w", err)
}
if pstate != newState {
vmi, err = makeVmWithBaseState(newState)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
}
if err = vmi.SetBlockHeight(ctx, i+1); err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("error advancing vm an epoch: %w", err)
}
pstate = newState
}
partDone()
partDone = metrics.Timer(ctx, metrics.VMApplyMessages)
vmi, err := makeVmWithBaseStateAndEpoch(pstate, epoch)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
}
var receipts []cbg.CBORMarshaler
processedMsgs := make(map[cid.Cid]struct{})
for _, b := range bms {
@@ -240,7 +246,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, sm *stmgr.StateManager
partDone()
partDone = metrics.Timer(ctx, metrics.VMApplyCron)
if err := runCron(vmi, epoch); err != nil {
if err := runCron(epoch); err != nil {
return cid.Cid{}, cid.Cid{}, err
}
@@ -288,7 +294,7 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, sm *stmgr.StateManag
var parentEpoch abi.ChainEpoch
pstate := blks[0].ParentStateRoot
if blks[0].Height > 0 {
parent, err := sm.ChainStore().GetBlock(ctx, blks[0].Parents[0])
parent, err := sm.ChainStore().GetBlock(blks[0].Parents[0])
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("getting parent block: %w", err)
}
@@ -296,9 +302,9 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, sm *stmgr.StateManag
parentEpoch = parent.Height
}
r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon(), sm.GetNetworkVersion)
r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon())
blkmsgs, err := sm.ChainStore().BlockMsgsForTipset(ctx, ts)
blkmsgs, err := sm.ChainStore().BlockMsgsForTipset(ts)
if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("getting block messages for tipset: %w", err)
}
+17 -23
View File
@@ -90,19 +90,19 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
h := b.Header
baseTs, err := filec.store.LoadTipSet(ctx, types.NewTipSetKey(h.Parents...))
baseTs, err := filec.store.LoadTipSet(types.NewTipSetKey(h.Parents...))
if err != nil {
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
}
winPoStNv := filec.sm.GetNetworkVersion(ctx, baseTs.Height())
winPoStNv := filec.sm.GetNtwkVersion(ctx, baseTs.Height())
lbts, lbst, err := stmgr.GetLookbackTipSetForRound(ctx, filec.sm, baseTs, h.Height)
if err != nil {
return xerrors.Errorf("failed to get lookback tipset for block: %w", err)
}
prevBeacon, err := filec.store.GetLatestBeaconEntry(ctx, baseTs)
prevBeacon, err := filec.store.GetLatestBeaconEntry(baseTs)
if err != nil {
return xerrors.Errorf("failed to get latest beacon entry: %w", err)
}
@@ -171,7 +171,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
}
if stateroot != h.ParentStateRoot {
msgs, err := filec.store.MessagesForTipset(ctx, baseTs)
msgs, err := filec.store.MessagesForTipset(baseTs)
if err != nil {
log.Error("failed to load messages for tipset during tipset state mismatch error: ", err)
} else {
@@ -182,7 +182,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
}
}
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", h.ParentStateRoot, stateroot)
return xerrors.Errorf("parent state root did not match computed state (%s != %s)", stateroot, h.ParentStateRoot)
}
if precp != h.ParentMessageReceipts {
@@ -458,7 +458,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
stateroot, _, err := filec.sm.TipSetState(ctx, baseTs)
if err != nil {
return xerrors.Errorf("failed to compute tipsettate for %s: %w", baseTs.Key(), err)
return err
}
st, err := state.LoadStateTree(filec.store.ActorStore(ctx), stateroot)
@@ -466,7 +466,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
return xerrors.Errorf("failed to load base state tree: %w", err)
}
nv := filec.sm.GetNetworkVersion(ctx, b.Header.Height)
nv := filec.sm.GetNtwkVersion(ctx, b.Header.Height)
pl := vm.PricelistByEpoch(baseTs.Height())
var sumGasLimit int64
checkMsg := func(msg types.ChainMsg) error {
@@ -475,7 +475,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
// Phase 1: syntactic validation, as defined in the spec
minGas := pl.OnChainMessage(msg.ChainLength())
if err := m.ValidForBlockInclusion(minGas.Total(), nv); err != nil {
return xerrors.Errorf("msg %s invalid for block inclusion: %w", m.Cid(), err)
return err
}
// ValidForBlockInclusion checks if any single message does not exceed BlockGasLimit
@@ -488,10 +488,10 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
// Phase 2: (Partial) semantic validation:
// the sender exists and is an account actor, and the nonces make sense
var sender address.Address
if filec.sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version13 {
if filec.sm.GetNtwkVersion(ctx, b.Header.Height) >= network.Version13 {
sender, err = st.LookupID(m.From)
if err != nil {
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
return err
}
} else {
sender = m.From
@@ -528,7 +528,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
c, err := store.PutMessage(tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
@@ -541,7 +541,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
smArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.SecpkMessages {
if filec.sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version14 {
if filec.sm.GetNtwkVersion(ctx, b.Header.Height) >= network.Version14 {
if m.Signature.Type != crypto.SigTypeSecp256k1 {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
@@ -562,7 +562,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
c, err := store.PutMessage(tmpbs, m)
if err != nil {
return xerrors.Errorf("failed to store message %s: %w", m.Cid(), err)
}
@@ -574,13 +574,12 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
bmroot, err := bmArr.Root()
if err != nil {
return xerrors.Errorf("failed to root bls msgs: %w", err)
return err
}
smroot, err := smArr.Root()
if err != nil {
return xerrors.Errorf("failed to root secp msgs: %w", err)
return err
}
mrcid, err := tmpstore.Put(ctx, &types.MsgMeta{
@@ -588,7 +587,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
SecpkMessages: smroot,
})
if err != nil {
return xerrors.Errorf("failed to put msg meta: %w", err)
return err
}
if b.Header.Messages != mrcid {
@@ -596,12 +595,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
}
// Finally, flush.
err = vm.Copy(ctx, tmpbs, filec.store.ChainBlockstore(), mrcid)
if err != nil {
return xerrors.Errorf("failed to flush:%w", err)
}
return nil
return vm.Copy(ctx, tmpbs, filec.store.ChainBlockstore(), mrcid)
}
func (filec *FilecoinEC) IsEpochBeyondCurrMax(epoch abi.ChainEpoch) bool {
+3 -3
View File
@@ -15,7 +15,7 @@ import (
)
func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.BlockTemplate) (*types.FullBlock, error) {
pts, err := filec.sm.ChainStore().LoadTipSet(ctx, bt.Parents)
pts, err := filec.sm.ChainStore().LoadTipSet(bt.Parents)
if err != nil {
return nil, xerrors.Errorf("failed to load parent tipset: %w", err)
}
@@ -59,14 +59,14 @@ func (filec *FilecoinEC) CreateBlock(ctx context.Context, w api.Wallet, bt *api.
blsSigs = append(blsSigs, msg.Signature)
blsMessages = append(blsMessages, &msg.Message)
c, err := filec.sm.ChainStore().PutMessage(ctx, &msg.Message)
c, err := filec.sm.ChainStore().PutMessage(&msg.Message)
if err != nil {
return nil, err
}
blsMsgCids = append(blsMsgCids, c)
} else if msg.Signature.Type == crypto.SigTypeSecp256k1 {
c, err := filec.sm.ChainStore().PutMessage(ctx, msg)
c, err := filec.sm.ChainStore().PutMessage(msg)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -644,7 +644,7 @@ func splitGenesisMultisig0(ctx context.Context, em stmgr.ExecMonitor, addr addre
// TODO: After the Liftoff epoch, refactor this to use resetMultisigVesting
func resetGenesisMsigs0(ctx context.Context, sm *stmgr.StateManager, store adt0.Store, tree *state.StateTree, startEpoch abi.ChainEpoch) error {
gb, err := sm.ChainStore().GetGenesis(ctx)
gb, err := sm.ChainStore().GetGenesis()
if err != nil {
return xerrors.Errorf("getting genesis block: %w", err)
}
+1 -1
View File
@@ -87,7 +87,7 @@ func (fcs *fakeCS) ChainGetPath(ctx context.Context, from, to types.TipSetKey) (
}
// copied from the chainstore
revert, apply, err := store.ReorgOps(ctx, func(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
revert, apply, err := store.ReorgOps(func(tsk types.TipSetKey) (*types.TipSet, error) {
return fcs.ChainGetTipSet(ctx, tsk)
}, fromTs, toTs)
if err != nil {
+2 -2
View File
@@ -27,11 +27,11 @@ func NewMockAPI(bs blockstore.Blockstore) *MockAPI {
}
func (m *MockAPI) ChainHasObj(ctx context.Context, c cid.Cid) (bool, error) {
return m.bs.Has(ctx, c)
return m.bs.Has(c)
}
func (m *MockAPI) ChainReadObj(ctx context.Context, c cid.Cid) ([]byte, error) {
blk, err := m.bs.Get(ctx, c)
blk, err := m.bs.Get(c)
if err != nil {
return nil, xerrors.Errorf("blockstore get: %w", err)
}
+8 -8
View File
@@ -136,7 +136,7 @@ func (s *server) serviceRequest(ctx context.Context, req *validatedRequest) (*Re
_, span := trace.StartSpan(ctx, "chainxchg.ServiceRequest")
defer span.End()
chain, err := collectChainSegment(ctx, s.cs, req)
chain, err := collectChainSegment(s.cs, req)
if err != nil {
log.Warn("block sync request: collectChainSegment failed: ", err)
return &Response{
@@ -156,13 +156,13 @@ func (s *server) serviceRequest(ctx context.Context, req *validatedRequest) (*Re
}, nil
}
func collectChainSegment(ctx context.Context, cs *store.ChainStore, req *validatedRequest) ([]*BSTipSet, error) {
func collectChainSegment(cs *store.ChainStore, req *validatedRequest) ([]*BSTipSet, error) {
var bstips []*BSTipSet
cur := req.head
for {
var bst BSTipSet
ts, err := cs.LoadTipSet(ctx, cur)
ts, err := cs.LoadTipSet(cur)
if err != nil {
return nil, xerrors.Errorf("failed loading tipset %s: %w", cur, err)
}
@@ -172,7 +172,7 @@ func collectChainSegment(ctx context.Context, cs *store.ChainStore, req *validat
}
if req.options.IncludeMessages {
bmsgs, bmincl, smsgs, smincl, err := gatherMessages(ctx, cs, ts)
bmsgs, bmincl, smsgs, smincl, err := gatherMessages(cs, ts)
if err != nil {
return nil, xerrors.Errorf("gather messages failed: %w", err)
}
@@ -197,14 +197,14 @@ func collectChainSegment(ctx context.Context, cs *store.ChainStore, req *validat
}
}
func gatherMessages(ctx context.Context, cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [][]uint64, []*types.SignedMessage, [][]uint64, error) {
func gatherMessages(cs *store.ChainStore, ts *types.TipSet) ([]*types.Message, [][]uint64, []*types.SignedMessage, [][]uint64, error) {
blsmsgmap := make(map[cid.Cid]uint64)
secpkmsgmap := make(map[cid.Cid]uint64)
var secpkincl, blsincl [][]uint64
var blscids, secpkcids []cid.Cid
for _, block := range ts.Blocks() {
bc, sc, err := cs.ReadMsgMetaCids(ctx, block.Messages)
bc, sc, err := cs.ReadMsgMetaCids(block.Messages)
if err != nil {
return nil, nil, nil, nil, err
}
@@ -237,12 +237,12 @@ func gatherMessages(ctx context.Context, cs *store.ChainStore, ts *types.TipSet)
secpkincl = append(secpkincl, smi)
}
blsmsgs, err := cs.LoadMessagesFromCids(ctx, blscids)
blsmsgs, err := cs.LoadMessagesFromCids(blscids)
if err != nil {
return nil, nil, nil, nil, err
}
secpkmsgs, err := cs.LoadSignedMessagesFromCids(ctx, secpkcids)
secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids)
if err != nil {
return nil, nil, nil, nil, err
}
+2 -2
View File
@@ -241,7 +241,7 @@ func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeS
genfb := &types.FullBlock{Header: genb.Genesis}
gents := store.NewFullTipSet([]*types.FullBlock{genfb})
if err := cs.SetGenesis(context.TODO(), genb.Genesis); err != nil {
if err := cs.SetGenesis(genb.Genesis); err != nil {
return nil, xerrors.Errorf("set genesis failed: %w", err)
}
@@ -471,7 +471,7 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessagesAndNulls(base *types.TipSet,
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
}
if err := cg.cs.PersistBlockHeaders(context.TODO(), fblk.Header); err != nil {
if err := cg.cs.PersistBlockHeaders(fblk.Header); err != nil {
return nil, xerrors.Errorf("chainstore AddBlock: %w", err)
}
+7 -5
View File
@@ -491,8 +491,10 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, sys vm.Sysca
Actors: filcns.NewActorRegistry(),
Syscalls: mkFakedSigSyscalls(sys),
CircSupplyCalc: csc,
NetworkVersion: nv,
BaseFee: types.NewInt(0),
NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version {
return nv
},
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(ctx, &vmopt)
if err != nil {
@@ -593,7 +595,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
if err != nil {
return nil, xerrors.Errorf("serializing msgmeta failed: %w", err)
}
if err := bs.Put(ctx, mmb); err != nil {
if err := bs.Put(mmb); err != nil {
return nil, xerrors.Errorf("putting msgmeta block to blockstore: %w", err)
}
@@ -623,7 +625,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
return nil, xerrors.Errorf("filecoinGenesisCid != gblk.Cid")
}
if err := bs.Put(ctx, gblk); err != nil {
if err := bs.Put(gblk); err != nil {
return nil, xerrors.Errorf("failed writing filecoin genesis block to blockstore: %w", err)
}
@@ -654,7 +656,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
return nil, xerrors.Errorf("serializing block header failed: %w", err)
}
if err := bs.Put(ctx, sb); err != nil {
if err := bs.Put(sb); err != nil {
return nil, xerrors.Errorf("putting header to blockstore: %w", err)
}
+24 -4
View File
@@ -94,8 +94,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
Actors: filcns.NewActorRegistry(),
Syscalls: mkFakedSigSyscalls(sys),
CircSupplyCalc: csc,
NetworkVersion: nv,
BaseFee: types.NewInt(0),
NtwkVersion: func(_ context.Context, _ abi.ChainEpoch) network.Version {
return nv
},
BaseFee: types.NewInt(0),
}
vm, err := vm.NewVM(ctx, vmopt)
@@ -508,13 +510,31 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
// TODO: copied from actors test harness, deduplicate or remove from here
type fakeRand struct{}
func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (fr *fakeRand) GetChainRandomnessV2(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (fr *fakeRand) GetChainRandomnessV1(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomnessV3(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomnessV2(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomnessV1(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
return out, nil
+10 -11
View File
@@ -1,7 +1,6 @@
package slashfilter
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/build"
@@ -28,7 +27,7 @@ func New(dstore ds.Batching) *SlashFilter {
}
}
func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, parentEpoch abi.ChainEpoch) error {
func (f *SlashFilter) MinedBlock(bh *types.BlockHeader, parentEpoch abi.ChainEpoch) error {
if build.IsNearUpgrade(bh.Height, build.UpgradeOrangeHeight) {
return nil
}
@@ -36,7 +35,7 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
epochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, bh.Height))
{
// double-fork mining (2 blocks at one epoch)
if err := checkFault(ctx, f.byEpoch, epochKey, bh, "double-fork mining faults"); err != nil {
if err := checkFault(f.byEpoch, epochKey, bh, "double-fork mining faults"); err != nil {
return err
}
}
@@ -44,7 +43,7 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
parentsKey := ds.NewKey(fmt.Sprintf("/%s/%x", bh.Miner, types.NewTipSetKey(bh.Parents...).Bytes()))
{
// time-offset mining faults (2 blocks with the same parents)
if err := checkFault(ctx, f.byParents, parentsKey, bh, "time-offset mining faults"); err != nil {
if err := checkFault(f.byParents, parentsKey, bh, "time-offset mining faults"); err != nil {
return err
}
}
@@ -54,14 +53,14 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
// First check if we have mined a block on the parent epoch
parentEpochKey := ds.NewKey(fmt.Sprintf("/%s/%d", bh.Miner, parentEpoch))
have, err := f.byEpoch.Has(ctx, parentEpochKey)
have, err := f.byEpoch.Has(parentEpochKey)
if err != nil {
return err
}
if have {
// If we had, make sure it's in our parent tipset
cidb, err := f.byEpoch.Get(ctx, parentEpochKey)
cidb, err := f.byEpoch.Get(parentEpochKey)
if err != nil {
return xerrors.Errorf("getting other block cid: %w", err)
}
@@ -84,25 +83,25 @@ func (f *SlashFilter) MinedBlock(ctx context.Context, bh *types.BlockHeader, par
}
}
if err := f.byParents.Put(ctx, parentsKey, bh.Cid().Bytes()); err != nil {
if err := f.byParents.Put(parentsKey, bh.Cid().Bytes()); err != nil {
return xerrors.Errorf("putting byEpoch entry: %w", err)
}
if err := f.byEpoch.Put(ctx, epochKey, bh.Cid().Bytes()); err != nil {
if err := f.byEpoch.Put(epochKey, bh.Cid().Bytes()); err != nil {
return xerrors.Errorf("putting byEpoch entry: %w", err)
}
return nil
}
func checkFault(ctx context.Context, t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) error {
fault, err := t.Has(ctx, key)
func checkFault(t ds.Datastore, key ds.Key, bh *types.BlockHeader, faultType string) error {
fault, err := t.Has(key)
if err != nil {
return err
}
if fault {
cidb, err := t.Get(ctx, key)
cidb, err := t.Get(key)
if err != nil {
return xerrors.Errorf("getting other block cid: %w", err)
}
+2 -2
View File
@@ -89,7 +89,7 @@ func (fm *FundManager) Start() error {
// - in State() only load addresses with in-progress messages
// - load the others just-in-time from getFundedAddress
// - delete(fm.fundedAddrs, addr) when the queue has been processed
return fm.str.forEach(fm.ctx, func(state *FundedAddressState) {
return fm.str.forEach(func(state *FundedAddressState) {
fa := newFundedAddress(fm, state.Addr)
fa.state = state
fm.fundedAddrs[fa.state.Addr] = fa
@@ -322,7 +322,7 @@ func (a *fundedAddress) clearWaitState() {
// Save state to datastore
func (a *fundedAddress) saveState() {
// Not much we can do if saving to the datastore fails, just log
err := a.str.save(a.ctx, a.state)
err := a.str.save(a.state)
if err != nil {
log.Errorf("saving state to store for addr %s: %v", a.state.Addr, err)
}
+6 -7
View File
@@ -2,7 +2,6 @@ package market
import (
"bytes"
"context"
cborrpc "github.com/filecoin-project/go-cbor-util"
"github.com/ipfs/go-datastore"
@@ -28,7 +27,7 @@ func newStore(ds dtypes.MetadataDS) *Store {
}
// save the state to the datastore
func (ps *Store) save(ctx context.Context, state *FundedAddressState) error {
func (ps *Store) save(state *FundedAddressState) error {
k := dskeyForAddr(state.Addr)
b, err := cborrpc.Dump(state)
@@ -36,14 +35,14 @@ func (ps *Store) save(ctx context.Context, state *FundedAddressState) error {
return err
}
return ps.ds.Put(ctx, k, b)
return ps.ds.Put(k, b)
}
// get the state for the given address
func (ps *Store) get(ctx context.Context, addr address.Address) (*FundedAddressState, error) {
func (ps *Store) get(addr address.Address) (*FundedAddressState, error) {
k := dskeyForAddr(addr)
data, err := ps.ds.Get(ctx, k)
data, err := ps.ds.Get(k)
if err != nil {
return nil, err
}
@@ -57,8 +56,8 @@ func (ps *Store) get(ctx context.Context, addr address.Address) (*FundedAddressS
}
// forEach calls iter with each address in the datastore
func (ps *Store) forEach(ctx context.Context, iter func(*FundedAddressState)) error {
res, err := ps.ds.Query(ctx, dsq.Query{Prefix: dsKeyAddr})
func (ps *Store) forEach(iter func(*FundedAddressState)) error {
res, err := ps.ds.Query(dsq.Query{Prefix: dsKeyAddr})
if err != nil {
return err
}
+7 -8
View File
@@ -1,7 +1,6 @@
package messagepool
import (
"context"
"encoding/json"
"fmt"
"time"
@@ -21,8 +20,8 @@ var (
ConfigKey = datastore.NewKey("/mpool/config")
)
func loadConfig(ctx context.Context, ds dtypes.MetadataDS) (*types.MpoolConfig, error) {
haveCfg, err := ds.Has(ctx, ConfigKey)
func loadConfig(ds dtypes.MetadataDS) (*types.MpoolConfig, error) {
haveCfg, err := ds.Has(ConfigKey)
if err != nil {
return nil, err
}
@@ -31,7 +30,7 @@ func loadConfig(ctx context.Context, ds dtypes.MetadataDS) (*types.MpoolConfig,
return DefaultConfig(), nil
}
cfgBytes, err := ds.Get(ctx, ConfigKey)
cfgBytes, err := ds.Get(ConfigKey)
if err != nil {
return nil, err
}
@@ -40,12 +39,12 @@ func loadConfig(ctx context.Context, ds dtypes.MetadataDS) (*types.MpoolConfig,
return cfg, err
}
func saveConfig(ctx context.Context, cfg *types.MpoolConfig, ds dtypes.MetadataDS) error {
func saveConfig(cfg *types.MpoolConfig, ds dtypes.MetadataDS) error {
cfgBytes, err := json.Marshal(cfg)
if err != nil {
return err
}
return ds.Put(ctx, ConfigKey, cfgBytes)
return ds.Put(ConfigKey, cfgBytes)
}
func (mp *MessagePool) GetConfig() *types.MpoolConfig {
@@ -69,7 +68,7 @@ func validateConfg(cfg *types.MpoolConfig) error {
return nil
}
func (mp *MessagePool) SetConfig(ctx context.Context, cfg *types.MpoolConfig) error {
func (mp *MessagePool) SetConfig(cfg *types.MpoolConfig) error {
if err := validateConfg(cfg); err != nil {
return err
}
@@ -77,7 +76,7 @@ func (mp *MessagePool) SetConfig(ctx context.Context, cfg *types.MpoolConfig) er
mp.cfgLk.Lock()
mp.cfg = cfg
err := saveConfig(ctx, cfg, mp.ds)
err := saveConfig(cfg, mp.ds)
if err != nil {
log.Warnf("error persisting mpool config: %s", err)
}
+19 -40
View File
@@ -173,17 +173,10 @@ type MessagePool struct {
sigValCache *lru.TwoQueueCache
nonceCache *lru.Cache
evtTypes [3]journal.EventType
journal journal.Journal
}
type nonceCacheKey struct {
tsk types.TipSetKey
addr address.Address
}
type msgSet struct {
msgs map[uint64]*types.SignedMessage
nextNonce uint64
@@ -203,10 +196,10 @@ func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
return types.BigAdd(minPrice, types.NewInt(1))
}
func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, sendSpec *api.MessageSendSpec) {
func CapGasFee(mff dtypes.DefaultMaxFeeFunc, msg *types.Message, sendSepc *api.MessageSendSpec) {
var maxFee abi.TokenAmount
if sendSpec != nil {
maxFee = sendSpec.MaxFee
if sendSepc != nil {
maxFee = sendSepc.MaxFee
}
if maxFee.Int == nil || maxFee.Equals(big.Zero()) {
mf, err := mff()
@@ -365,12 +358,11 @@ func (ms *msgSet) toSlice() []*types.SignedMessage {
return set
}
func New(ctx context.Context, api Provider, ds dtypes.MetadataDS, us stmgr.UpgradeSchedule, netName dtypes.NetworkName, j journal.Journal) (*MessagePool, error) {
func New(api Provider, ds dtypes.MetadataDS, us stmgr.UpgradeSchedule, netName dtypes.NetworkName, j journal.Journal) (*MessagePool, error) {
cache, _ := lru.New2Q(build.BlsSignatureCacheSize)
verifcache, _ := lru.New2Q(build.VerifSigCacheSize)
noncecache, _ := lru.New(256)
cfg, err := loadConfig(ctx, ds)
cfg, err := loadConfig(ds)
if err != nil {
return nil, xerrors.Errorf("error loading mpool config: %w", err)
}
@@ -394,7 +386,6 @@ func New(ctx context.Context, api Provider, ds dtypes.MetadataDS, us stmgr.Upgra
pruneCooldown: make(chan struct{}, 1),
blsSigCache: cache,
sigValCache: verifcache,
nonceCache: noncecache,
changes: lps.New(50),
localMsgs: namespace.Wrap(ds, datastore.NewKey(localMsgsDs)),
api: api,
@@ -610,7 +601,7 @@ func (mp *MessagePool) addLocal(ctx context.Context, m *types.SignedMessage) err
return xerrors.Errorf("error serializing message: %w", err)
}
if err := mp.localMsgs.Put(ctx, datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil {
if err := mp.localMsgs.Put(datastore.NewKey(string(m.Cid().Bytes())), msgb); err != nil {
return xerrors.Errorf("persisting local message: %w", err)
}
@@ -918,12 +909,12 @@ func (mp *MessagePool) addLocked(ctx context.Context, m *types.SignedMessage, st
mp.blsSigCache.Add(m.Cid(), m.Signature)
}
if _, err := mp.api.PutMessage(ctx, m); err != nil {
if _, err := mp.api.PutMessage(m); err != nil {
log.Warnf("mpooladd cs.PutMessage failed: %s", err)
return err
}
if _, err := mp.api.PutMessage(ctx, &m.Message); err != nil {
if _, err := mp.api.PutMessage(&m.Message); err != nil {
log.Warnf("mpooladd cs.PutMessage failed: %s", err)
return err
}
@@ -1025,23 +1016,11 @@ func (mp *MessagePool) getStateNonce(ctx context.Context, addr address.Address,
done := metrics.Timer(ctx, metrics.MpoolGetNonceDuration)
defer done()
nk := nonceCacheKey{
tsk: ts.Key(),
addr: addr,
}
n, ok := mp.nonceCache.Get(nk)
if ok {
return n.(uint64), nil
}
act, err := mp.api.GetActorAfter(addr, ts)
if err != nil {
return 0, err
}
mp.nonceCache.Add(nk, act.Nonce)
return act.Nonce, nil
}
@@ -1228,7 +1207,7 @@ func (mp *MessagePool) HeadChange(ctx context.Context, revert []*types.TipSet, a
var merr error
for _, ts := range revert {
pts, err := mp.api.LoadTipSet(ctx, ts.Parents())
pts, err := mp.api.LoadTipSet(ts.Parents())
if err != nil {
log.Errorf("error loading reverted tipset parent: %s", err)
merr = multierror.Append(merr, err)
@@ -1237,7 +1216,7 @@ func (mp *MessagePool) HeadChange(ctx context.Context, revert []*types.TipSet, a
mp.curTs = pts
msgs, err := mp.MessagesForBlocks(ctx, ts.Blocks())
msgs, err := mp.MessagesForBlocks(ts.Blocks())
if err != nil {
log.Errorf("error retrieving messages for reverted block: %s", err)
merr = multierror.Append(merr, err)
@@ -1253,7 +1232,7 @@ func (mp *MessagePool) HeadChange(ctx context.Context, revert []*types.TipSet, a
mp.curTs = ts
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := mp.api.MessagesForBlock(ctx, b)
bmsgs, smsgs, err := mp.api.MessagesForBlock(b)
if err != nil {
xerr := xerrors.Errorf("failed to get messages for apply block %s(height %d) (msgroot = %s): %w", b.Cid(), b.Height, b.Messages, err)
log.Errorf("error retrieving messages for block: %s", xerr)
@@ -1359,7 +1338,7 @@ func (mp *MessagePool) HeadChange(ctx context.Context, revert []*types.TipSet, a
return merr
}
func (mp *MessagePool) runHeadChange(ctx context.Context, from *types.TipSet, to *types.TipSet, rmsgs map[address.Address]map[uint64]*types.SignedMessage) error {
func (mp *MessagePool) runHeadChange(from *types.TipSet, to *types.TipSet, rmsgs map[address.Address]map[uint64]*types.SignedMessage) error {
add := func(m *types.SignedMessage) {
s, ok := rmsgs[m.Message.From]
if !ok {
@@ -1381,7 +1360,7 @@ func (mp *MessagePool) runHeadChange(ctx context.Context, from *types.TipSet, to
}
revert, apply, err := store.ReorgOps(ctx, mp.api.LoadTipSet, from, to)
revert, apply, err := store.ReorgOps(mp.api.LoadTipSet, from, to)
if err != nil {
return xerrors.Errorf("failed to compute reorg ops for mpool pending messages: %w", err)
}
@@ -1389,7 +1368,7 @@ func (mp *MessagePool) runHeadChange(ctx context.Context, from *types.TipSet, to
var merr error
for _, ts := range revert {
msgs, err := mp.MessagesForBlocks(ctx, ts.Blocks())
msgs, err := mp.MessagesForBlocks(ts.Blocks())
if err != nil {
log.Errorf("error retrieving messages for reverted block: %s", err)
merr = multierror.Append(merr, err)
@@ -1403,7 +1382,7 @@ func (mp *MessagePool) runHeadChange(ctx context.Context, from *types.TipSet, to
for _, ts := range apply {
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := mp.api.MessagesForBlock(ctx, b)
bmsgs, smsgs, err := mp.api.MessagesForBlock(b)
if err != nil {
xerr := xerrors.Errorf("failed to get messages for apply block %s(height %d) (msgroot = %s): %w", b.Cid(), b.Height, b.Messages, err)
log.Errorf("error retrieving messages for block: %s", xerr)
@@ -1428,11 +1407,11 @@ type statBucket struct {
msgs map[uint64]*types.SignedMessage
}
func (mp *MessagePool) MessagesForBlocks(ctx context.Context, blks []*types.BlockHeader) ([]*types.SignedMessage, error) {
func (mp *MessagePool) MessagesForBlocks(blks []*types.BlockHeader) ([]*types.SignedMessage, error) {
out := make([]*types.SignedMessage, 0)
for _, b := range blks {
bmsgs, smsgs, err := mp.api.MessagesForBlock(ctx, b)
bmsgs, smsgs, err := mp.api.MessagesForBlock(b)
if err != nil {
return nil, xerrors.Errorf("failed to get messages for apply block %s(height %d) (msgroot = %s): %w", b.Cid(), b.Height, b.Messages, err)
}
@@ -1498,7 +1477,7 @@ func (mp *MessagePool) Updates(ctx context.Context) (<-chan api.MpoolUpdate, err
}
func (mp *MessagePool) loadLocal(ctx context.Context) error {
res, err := mp.localMsgs.Query(ctx, query.Query{})
res, err := mp.localMsgs.Query(query.Query{})
if err != nil {
return xerrors.Errorf("query local messages: %w", err)
}
@@ -1546,7 +1525,7 @@ func (mp *MessagePool) Clear(ctx context.Context, local bool) {
if ok {
for _, m := range mset.msgs {
err := mp.localMsgs.Delete(ctx, datastore.NewKey(string(m.Cid().Bytes())))
err := mp.localMsgs.Delete(datastore.NewKey(string(m.Cid().Bytes())))
if err != nil {
log.Warnf("error deleting local message: %s", err)
}
+15 -30
View File
@@ -1,4 +1,3 @@
//stm: #unit
package messagepool
import (
@@ -104,7 +103,7 @@ func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet)
return tma.tipsets[0]
}
func (tma *testMpoolAPI) PutMessage(ctx context.Context, m types.ChainMsg) (cid.Cid, error) {
func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) {
return cid.Undef, nil
}
@@ -165,16 +164,16 @@ func (tma *testMpoolAPI) StateAccountKeyAtFinality(ctx context.Context, addr add
return addr, nil
}
func (tma *testMpoolAPI) MessagesForBlock(ctx context.Context, h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
func (tma *testMpoolAPI) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return nil, tma.bmsgs[h.Cid()], nil
}
func (tma *testMpoolAPI) MessagesForTipset(ctx context.Context, ts *types.TipSet) ([]types.ChainMsg, error) {
func (tma *testMpoolAPI) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
if len(ts.Blocks()) != 1 {
panic("cant deal with multiblock tipsets in this test")
}
bm, sm, err := tma.MessagesForBlock(ctx, ts.Blocks()[0])
bm, sm, err := tma.MessagesForBlock(ts.Blocks()[0])
if err != nil {
return nil, err
}
@@ -191,7 +190,7 @@ func (tma *testMpoolAPI) MessagesForTipset(ctx context.Context, ts *types.TipSet
return out, nil
}
func (tma *testMpoolAPI) LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
for _, ts := range tma.tipsets {
if types.CidArrsEqual(tsk.Cids(), ts.Cids()) {
return ts, nil
@@ -207,7 +206,6 @@ func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipS
func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) {
t.Helper()
//stm: @CHAIN_MEMPOOL_GET_NONCE_001
n, err := mp.GetNonce(context.TODO(), addr, types.EmptyTSK)
if err != nil {
t.Fatal(err)
@@ -235,7 +233,7 @@ func TestMessagePool(t *testing.T) {
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -279,7 +277,7 @@ func TestCheckMessageBig(t *testing.T) {
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
assert.NoError(t, err)
to := mock.Address(1001)
@@ -342,7 +340,7 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -368,10 +366,8 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
tma.applyBlock(t, a)
tsa := mock.TipSet(a)
//stm: @CHAIN_MEMPOOL_PENDING_001
_, _ = mp.Pending(context.TODO())
//stm: @CHAIN_MEMPOOL_SELECT_001
selm, _ := mp.SelectMessages(context.Background(), tsa, 1)
if len(selm) == 0 {
t.Fatal("should have returned the rest of the messages")
@@ -393,7 +389,7 @@ func TestRevertMessages(t *testing.T) {
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -432,7 +428,6 @@ func TestRevertMessages(t *testing.T) {
assertNonce(t, mp, sender, 4)
//stm: @CHAIN_MEMPOOL_PENDING_001
p, _ := mp.Pending(context.TODO())
fmt.Printf("%+v\n", p)
if len(p) != 3 {
@@ -457,7 +452,7 @@ func TestPruningSimple(t *testing.T) {
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -491,7 +486,6 @@ func TestPruningSimple(t *testing.T) {
mp.Prune()
//stm: @CHAIN_MEMPOOL_PENDING_001
msgs, _ := mp.Pending(context.TODO())
if len(msgs) != 5 {
t.Fatal("expected only 5 messages in pool, got: ", len(msgs))
@@ -502,7 +496,7 @@ func TestLoadLocal(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -534,7 +528,6 @@ func TestLoadLocal(t *testing.T) {
msgs := make(map[cid.Cid]struct{})
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
cid, err := mp.Push(context.TODO(), m)
if err != nil {
t.Fatal(err)
@@ -546,12 +539,11 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err)
}
mp, err = New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err = New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
//stm: @CHAIN_MEMPOOL_PENDING_001
pmsgs, _ := mp.Pending(context.TODO())
if len(msgs) != len(pmsgs) {
t.Fatalf("expected %d messages, but got %d", len(msgs), len(pmsgs))
@@ -576,7 +568,7 @@ func TestClearAll(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -607,7 +599,6 @@ func TestClearAll(t *testing.T) {
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m)
if err != nil {
t.Fatal(err)
@@ -619,10 +610,8 @@ func TestClearAll(t *testing.T) {
mustAdd(t, mp, m)
}
//stm: @CHAIN_MEMPOOL_CLEAR_001
mp.Clear(context.Background(), true)
//stm: @CHAIN_MEMPOOL_PENDING_001
pending, _ := mp.Pending(context.TODO())
if len(pending) > 0 {
t.Fatalf("cleared the mpool, but got %d pending messages", len(pending))
@@ -633,7 +622,7 @@ func TestClearNonLocal(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -665,7 +654,6 @@ func TestClearNonLocal(t *testing.T) {
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m)
if err != nil {
t.Fatal(err)
@@ -677,10 +665,8 @@ func TestClearNonLocal(t *testing.T) {
mustAdd(t, mp, m)
}
//stm: @CHAIN_MEMPOOL_CLEAR_001
mp.Clear(context.Background(), false)
//stm: @CHAIN_MEMPOOL_PENDING_001
pending, _ := mp.Pending(context.TODO())
if len(pending) != 10 {
t.Fatalf("expected 10 pending messages, but got %d instead", len(pending))
@@ -697,7 +683,7 @@ func TestUpdates(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
@@ -738,7 +724,6 @@ func TestUpdates(t *testing.T) {
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m)
if err != nil {
t.Fatal(err)
+12 -12
View File
@@ -23,13 +23,13 @@ var (
type Provider interface {
SubscribeHeadChanges(func(rev, app []*types.TipSet) error) *types.TipSet
PutMessage(ctx context.Context, m types.ChainMsg) (cid.Cid, error)
PutMessage(m types.ChainMsg) (cid.Cid, error)
PubSubPublish(string, []byte) error
GetActorAfter(address.Address, *types.TipSet) (*types.Actor, error)
StateAccountKeyAtFinality(context.Context, address.Address, *types.TipSet) (address.Address, error)
MessagesForBlock(context.Context, *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(context.Context, *types.TipSet) ([]types.ChainMsg, error)
LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
MessagesForBlock(*types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(*types.TipSet) ([]types.ChainMsg, error)
LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error)
ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error)
IsLite() bool
}
@@ -66,8 +66,8 @@ func (mpp *mpoolProvider) SubscribeHeadChanges(cb func(rev, app []*types.TipSet)
return mpp.sm.ChainStore().GetHeaviestTipSet()
}
func (mpp *mpoolProvider) PutMessage(ctx context.Context, m types.ChainMsg) (cid.Cid, error) {
return mpp.sm.ChainStore().PutMessage(ctx, m)
func (mpp *mpoolProvider) PutMessage(m types.ChainMsg) (cid.Cid, error) {
return mpp.sm.ChainStore().PutMessage(m)
}
func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
@@ -103,16 +103,16 @@ func (mpp *mpoolProvider) StateAccountKeyAtFinality(ctx context.Context, addr ad
return mpp.sm.ResolveToKeyAddressAtFinality(ctx, addr, ts)
}
func (mpp *mpoolProvider) MessagesForBlock(ctx context.Context, h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return mpp.sm.ChainStore().MessagesForBlock(ctx, h)
func (mpp *mpoolProvider) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
return mpp.sm.ChainStore().MessagesForBlock(h)
}
func (mpp *mpoolProvider) MessagesForTipset(ctx context.Context, ts *types.TipSet) ([]types.ChainMsg, error) {
return mpp.sm.ChainStore().MessagesForTipset(ctx, ts)
func (mpp *mpoolProvider) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
return mpp.sm.ChainStore().MessagesForTipset(ts)
}
func (mpp *mpoolProvider) LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
return mpp.sm.ChainStore().LoadTipSet(ctx, tsk)
func (mpp *mpoolProvider) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
return mpp.sm.ChainStore().LoadTipSet(tsk)
}
func (mpp *mpoolProvider) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
+1 -1
View File
@@ -49,7 +49,7 @@ func (mp *MessagePool) pruneMessages(ctx context.Context, ts *types.TipSet) erro
}
baseFeeLowerBound := getBaseFeeLowerBound(baseFee, baseFeeLowerBoundFactor)
pending, _ := mp.getPendingMessages(ctx, ts, ts)
pending, _ := mp.getPendingMessages(ts, ts)
// protected actors -- not pruned
protected := make(map[address.Address]struct{})
+1 -1
View File
@@ -25,7 +25,7 @@ func TestRepubMessages(t *testing.T) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "mptest", nil)
if err != nil {
t.Fatal(err)
}
+4 -4
View File
@@ -210,7 +210,7 @@ func (mp *MessagePool) selectMessagesOptimal(ctx context.Context, curTs, ts *typ
// 0. Load messages from the target tipset; if it is the same as the current tipset in
// the mpool, then this is just the pending messages
pending, err := mp.getPendingMessages(ctx, curTs, ts)
pending, err := mp.getPendingMessages(curTs, ts)
if err != nil {
return nil, err
}
@@ -458,7 +458,7 @@ func (mp *MessagePool) selectMessagesGreedy(ctx context.Context, curTs, ts *type
// 0. Load messages for the target tipset; if it is the same as the current tipset in the mpool
// then this is just the pending messages
pending, err := mp.getPendingMessages(ctx, curTs, ts)
pending, err := mp.getPendingMessages(curTs, ts)
if err != nil {
return nil, err
}
@@ -695,7 +695,7 @@ tailLoop:
return result
}
func (mp *MessagePool) getPendingMessages(ctx context.Context, curTs, ts *types.TipSet) (map[address.Address]map[uint64]*types.SignedMessage, error) {
func (mp *MessagePool) getPendingMessages(curTs, ts *types.TipSet) (map[address.Address]map[uint64]*types.SignedMessage, error) {
start := time.Now()
result := make(map[address.Address]map[uint64]*types.SignedMessage)
@@ -731,7 +731,7 @@ func (mp *MessagePool) getPendingMessages(ctx context.Context, curTs, ts *types.
return result, nil
}
if err := mp.runHeadChange(ctx, curTs, ts, result); err != nil {
if err := mp.runHeadChange(curTs, ts, result); err != nil {
return nil, xerrors.Errorf("failed to process difference between mpool head and given head: %w", err)
}
+1 -1
View File
@@ -65,7 +65,7 @@ func makeTestMessage(w *wallet.LocalWallet, from, to address.Address, nonce uint
func makeTestMpool() (*MessagePool, *testMpoolAPI) {
tma := newTestMpoolAPI()
ds := datastore.NewMapDatastore()
mp, err := New(context.Background(), tma, ds, filcns.DefaultUpgradeSchedule(), "test", nil)
mp, err := New(tma, ds, filcns.DefaultUpgradeSchedule(), "test", nil)
if err != nil {
panic(err)
}
+4 -4
View File
@@ -84,7 +84,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, cb
}
// If the callback executed successfully, write the nonce to the datastore
if err := ms.saveNonce(ctx, msg.From, nonce); err != nil {
if err := ms.saveNonce(msg.From, nonce); err != nil {
return nil, xerrors.Errorf("failed to save nonce: %w", err)
}
@@ -105,7 +105,7 @@ func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (u
// Get the next nonce for this address from the datastore
addrNonceKey := ms.dstoreKey(addr)
dsNonceBytes, err := ms.ds.Get(ctx, addrNonceKey)
dsNonceBytes, err := ms.ds.Get(addrNonceKey)
switch {
case xerrors.Is(err, datastore.ErrNotFound):
@@ -139,7 +139,7 @@ func (ms *MessageSigner) nextNonce(ctx context.Context, addr address.Address) (u
// saveNonce increments the nonce for this address and writes it to the
// datastore
func (ms *MessageSigner) saveNonce(ctx context.Context, addr address.Address, nonce uint64) error {
func (ms *MessageSigner) saveNonce(addr address.Address, nonce uint64) error {
// Increment the nonce
nonce++
@@ -150,7 +150,7 @@ func (ms *MessageSigner) saveNonce(ctx context.Context, addr address.Address, no
if err != nil {
return xerrors.Errorf("failed to marshall nonce: %w", err)
}
err = ms.ds.Put(ctx, addrNonceKey, buf.Bytes())
err = ms.ds.Put(addrNonceKey, buf.Bytes())
if err != nil {
return xerrors.Errorf("failed to write nonce to datastore: %w", err)
}
@@ -1,4 +1,3 @@
//stm: #unit
package messagesigner
import (
@@ -61,7 +60,6 @@ func TestMessageSignerSignMessage(t *testing.T) {
to2, err := w.WalletNew(ctx, types.KTSecp256k1)
require.NoError(t, err)
//stm: @CHAIN_MESSAGE_SIGNER_NEW_SIGNER_001, @CHAIN_MESSAGE_SIGNER_SIGN_MESSAGE_001, @CHAIN_MESSAGE_SIGNER_SIGN_MESSAGE_005
type msgSpec struct {
msg *types.Message
mpoolNonce [1]uint64
+27 -45
View File
@@ -4,8 +4,6 @@ import (
"context"
"encoding/binary"
"github.com/filecoin-project/go-state-types/network"
logging "github.com/ipfs/go-log/v2"
"github.com/filecoin-project/lotus/chain/beacon"
@@ -50,7 +48,7 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...))
ts, err := sr.cs.LoadTipSet(types.NewTipSetKey(sr.blks...))
if err != nil {
return nil, err
}
@@ -72,12 +70,12 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch
return randTs, nil
}
func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...))
ts, err := sr.cs.LoadTipSet(types.NewTipSetKey(sr.blks...))
if err != nil {
return nil, err
}
@@ -103,32 +101,38 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainS
return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy)
}
type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
type stateRand struct {
cs *store.ChainStore
blks []cid.Cid
beacon beacon.Schedule
networkVersionGetter NetworkVersionGetter
cs *store.ChainStore
blks []cid.Cid
beacon beacon.Schedule
}
func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) vm.Rand {
func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule) vm.Rand {
return &stateRand{
cs: cs,
blks: blks,
beacon: b,
networkVersionGetter: networkVersionGetter,
cs: cs,
blks: blks,
beacon: b,
}
}
// network v0-12
func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (sr *stateRand) GetChainRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return sr.GetChainRandomness(ctx, pers, round, entropy, true)
}
// network v13 and on
func (sr *stateRand) GetChainRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return sr.GetChainRandomness(ctx, pers, round, entropy, false)
}
// network v0-12
func (sr *stateRand) GetBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true)
if err != nil {
return nil, err
}
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
be, err := sr.cs.GetLatestBeaconEntry(randTs)
if err != nil {
return nil, err
}
@@ -139,13 +143,13 @@ func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.Doma
}
// network v13
func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (sr *stateRand) GetBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false)
if err != nil {
return nil, err
}
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
be, err := sr.cs.GetLatestBeaconEntry(randTs)
if err != nil {
return nil, err
}
@@ -156,9 +160,9 @@ func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.Doma
}
// network v14 and on
func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (sr *stateRand) GetBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
if filecoinEpoch < 0 {
return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
return sr.GetBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
}
be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch)
@@ -170,28 +174,6 @@ func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.Doma
return DrawRandomness(be.Data, pers, filecoinEpoch, entropy)
}
func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
nv := sr.networkVersionGetter(ctx, filecoinEpoch)
if nv >= network.Version13 {
return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, false)
}
return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, true)
}
func (sr *stateRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
nv := sr.networkVersionGetter(ctx, filecoinEpoch)
if nv >= network.Version14 {
return sr.getBeaconRandomnessV3(ctx, pers, filecoinEpoch, entropy)
} else if nv == network.Version13 {
return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
} else {
return sr.getBeaconRandomnessV1(ctx, pers, filecoinEpoch, entropy)
}
}
func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpoch abi.ChainEpoch) (*types.BeaconEntry, error) {
randTs, err := sr.GetBeaconRandomnessTipset(ctx, filecoinEpoch, false)
if err != nil {
@@ -208,7 +190,7 @@ func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpo
}
}
next, err := sr.cs.LoadTipSet(ctx, randTs.Parents())
next, err := sr.cs.LoadTipSet(randTs.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load parents when searching back for beacon entry: %w", err)
}
-10
View File
@@ -1,4 +1,3 @@
//stm:#unit
package rand_test
import (
@@ -56,13 +55,11 @@ func TestNullRandomnessV1(t *testing.T) {
randEpoch := ts.TipSet.TipSet().Height() - 2
//stm: @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_V1_01, @BLOCKCHAIN_RAND_EXTRACT_BEACON_ENTRY_FOR_EPOCH_01, @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_TIPSET_02
rand1, err := cg.StateManager().GetRandomnessFromBeacon(ctx, pers, randEpoch, entropy, ts.TipSet.TipSet().Key())
if err != nil {
t.Fatal(err)
}
//stm: @BLOCKCHAIN_BEACON_GET_BEACON_FOR_EPOCH_01
bch := cg.BeaconSchedule().BeaconForEpoch(randEpoch).Entry(ctx, uint64(beforeNullHeight)+offset)
select {
@@ -71,7 +68,6 @@ func TestNullRandomnessV1(t *testing.T) {
t.Fatal(resp.Err)
}
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
if err != nil {
t.Fatal(err)
@@ -135,13 +131,11 @@ func TestNullRandomnessV2(t *testing.T) {
randEpoch := ts.TipSet.TipSet().Height() - 2
//stm: @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_V2_01
rand1, err := cg.StateManager().GetRandomnessFromBeacon(ctx, pers, randEpoch, entropy, ts.TipSet.TipSet().Key())
if err != nil {
t.Fatal(err)
}
//stm: @BLOCKCHAIN_BEACON_GET_BEACON_FOR_EPOCH_01
bch := cg.BeaconSchedule().BeaconForEpoch(randEpoch).Entry(ctx, uint64(ts.TipSet.TipSet().Height())+offset)
select {
@@ -150,7 +144,6 @@ func TestNullRandomnessV2(t *testing.T) {
t.Fatal(resp.Err)
}
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01, @BLOCKCHAIN_RAND_EXTRACT_BEACON_ENTRY_FOR_EPOCH_01, @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_TIPSET_03
// note that the randEpoch passed to DrawRandomness is still randEpoch (not the latest ts height)
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
if err != nil {
@@ -219,13 +212,11 @@ func TestNullRandomnessV3(t *testing.T) {
randEpoch := ts.TipSet.TipSet().Height() - 2
//stm: @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_V3_01, @BLOCKCHAIN_RAND_EXTRACT_BEACON_ENTRY_FOR_EPOCH_01
rand1, err := cg.StateManager().GetRandomnessFromBeacon(ctx, pers, randEpoch, entropy, ts.TipSet.TipSet().Key())
if err != nil {
t.Fatal(err)
}
//stm: @BLOCKCHAIN_BEACON_GET_BEACON_FOR_EPOCH_01
bch := cg.BeaconSchedule().BeaconForEpoch(randEpoch).Entry(ctx, uint64(randEpoch)+offset)
select {
@@ -234,7 +225,6 @@ func TestNullRandomnessV3(t *testing.T) {
t.Fatal(resp.Err)
}
//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
if err != nil {
t.Fatal(err)
+4 -5
View File
@@ -14,7 +14,6 @@ import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
cid "github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api"
@@ -302,12 +301,12 @@ func ListMinerActors(ctx context.Context, sm *StateManager, ts *types.TipSet) ([
}
func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) {
ts, err := sm.ChainStore().LoadTipSet(ctx, tsk)
ts, err := sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err)
}
prev, err := sm.ChainStore().GetLatestBeaconEntry(ctx, ts)
prev, err := sm.ChainStore().GetLatestBeaconEntry(ts)
if err != nil {
if os.Getenv("LOTUS_IGNORE_DRAND") != "_yes_" {
return nil, xerrors.Errorf("failed to get latest beacon entry: %w", err)
@@ -359,7 +358,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
}
nv := sm.GetNetworkVersion(ctx, ts.Height())
nv := sm.GetNtwkVersion(ctx, ts.Height())
sectors, err := GetSectorsForWinningPoSt(ctx, nv, pv, sm, lbst, maddr, prand)
if err != nil {
@@ -421,7 +420,7 @@ func MinerEligibleToMine(ctx context.Context, sm *StateManager, addr address.Add
hmp, err := minerHasMinPower(ctx, sm, addr, lookbackTs)
// TODO: We're blurring the lines between a "runtime network version" and a "Lotus upgrade epoch", is that unavoidable?
if sm.GetNetworkVersion(ctx, baseTs.Height()) <= network.Version3 {
if sm.GetNtwkVersion(ctx, baseTs.Height()) <= network.Version3 {
return hmp, err
}
+8 -8
View File
@@ -40,7 +40,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
ts = sm.cs.GetHeaviestTipSet()
// Search back till we find a height with no fork, or we reach the beginning.
for ts.Height() > 0 {
pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents())
pts, err := sm.cs.GetTipSetFromKey(ts.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err)
}
@@ -51,7 +51,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
ts = pts
}
} else if ts.Height() > 0 {
pts, err := sm.cs.LoadTipSet(ctx, ts.Parents())
pts, err := sm.cs.LoadTipSet(ts.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load parent tipset: %w", err)
}
@@ -75,12 +75,12 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
vmopt := &vm.VMOpts{
StateBase: bstate,
Epoch: pheight + 1,
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion),
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon),
Bstore: sm.cs.StateBlockstore(),
Actors: sm.tsExec.NewActorRegistry(),
Syscalls: sm.Syscalls,
CircSupplyCalc: sm.GetVMCirculatingSupply,
NetworkVersion: sm.GetNetworkVersion(ctx, pheight+1),
NtwkVersion: sm.GetNtwkVersion,
BaseFee: types.NewInt(0),
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
@@ -155,7 +155,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
// height to have no fork, because we'll run it inside this
// function before executing the given message.
for ts.Height() > 0 {
pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents())
pts, err := sm.cs.GetTipSetFromKey(ts.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err)
}
@@ -166,7 +166,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
ts = pts
}
} else if ts.Height() > 0 {
pts, err := sm.cs.GetTipSetFromKey(ctx, ts.Parents())
pts, err := sm.cs.GetTipSetFromKey(ts.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to find a non-forking epoch: %w", err)
}
@@ -186,7 +186,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
return nil, fmt.Errorf("failed to handle fork: %w", err)
}
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion)
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon)
if span.IsRecordingEvents() {
span.AddAttributes(
@@ -204,7 +204,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
Actors: sm.tsExec.NewActorRegistry(),
Syscalls: sm.Syscalls,
CircSupplyCalc: sm.GetVMCirculatingSupply,
NetworkVersion: sm.GetNetworkVersion(ctx, ts.Height()+1),
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
+4 -4
View File
@@ -13,8 +13,8 @@ import (
"github.com/filecoin-project/lotus/chain/types"
)
func (sm *StateManager) ParentStateTsk(ctx context.Context, tsk types.TipSetKey) (*state.StateTree, error) {
ts, err := sm.cs.GetTipSetFromKey(ctx, tsk)
func (sm *StateManager) ParentStateTsk(tsk types.TipSetKey) (*state.StateTree, error) {
ts, err := sm.cs.GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
@@ -57,8 +57,8 @@ func (sm *StateManager) LoadActor(_ context.Context, addr address.Address, ts *t
return state.GetActor(addr)
}
func (sm *StateManager) LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
state, err := sm.ParentStateTsk(ctx, tsk)
func (sm *StateManager) LoadActorTsk(_ context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error) {
state, err := sm.ParentStateTsk(tsk)
if err != nil {
return nil, err
}
+11 -11
View File
@@ -20,7 +20,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
ctx, cancel := context.WithCancel(ctx)
defer cancel()
msg, err := sm.cs.GetCMessage(ctx, mcid)
msg, err := sm.cs.GetCMessage(mcid)
if err != nil {
return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err)
}
@@ -40,7 +40,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
return nil, nil, cid.Undef, fmt.Errorf("expected current head on SHC stream (got %s)", head[0].Type)
}
r, foundMsg, err := sm.tipsetExecutedMessage(ctx, head[0].Val, mcid, msg.VMMessage(), allowReplaced)
r, foundMsg, err := sm.tipsetExecutedMessage(head[0].Val, mcid, msg.VMMessage(), allowReplaced)
if err != nil {
return nil, nil, cid.Undef, err
}
@@ -93,7 +93,7 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
if candidateTs != nil && val.Val.Height() >= candidateTs.Height()+abi.ChainEpoch(confidence) {
return candidateTs, candidateRcp, candidateFm, nil
}
r, foundMsg, err := sm.tipsetExecutedMessage(ctx, val.Val, mcid, msg.VMMessage(), allowReplaced)
r, foundMsg, err := sm.tipsetExecutedMessage(val.Val, mcid, msg.VMMessage(), allowReplaced)
if err != nil {
return nil, nil, cid.Undef, err
}
@@ -130,12 +130,12 @@ func (sm *StateManager) WaitForMessage(ctx context.Context, mcid cid.Cid, confid
}
func (sm *StateManager) SearchForMessage(ctx context.Context, head *types.TipSet, mcid cid.Cid, lookbackLimit abi.ChainEpoch, allowReplaced bool) (*types.TipSet, *types.MessageReceipt, cid.Cid, error) {
msg, err := sm.cs.GetCMessage(ctx, mcid)
msg, err := sm.cs.GetCMessage(mcid)
if err != nil {
return nil, nil, cid.Undef, fmt.Errorf("failed to load message: %w", err)
}
r, foundMsg, err := sm.tipsetExecutedMessage(ctx, head, mcid, msg.VMMessage(), allowReplaced)
r, foundMsg, err := sm.tipsetExecutedMessage(head, mcid, msg.VMMessage(), allowReplaced)
if err != nil {
return nil, nil, cid.Undef, err
}
@@ -201,7 +201,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
return nil, nil, cid.Undef, nil
}
pts, err := sm.cs.LoadTipSet(ctx, cur.Parents())
pts, err := sm.cs.LoadTipSet(cur.Parents())
if err != nil {
return nil, nil, cid.Undef, xerrors.Errorf("failed to load tipset during msg wait searchback: %w", err)
}
@@ -214,7 +214,7 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
// check that between cur and parent tipset the nonce fell into range of our message
if actorNoExist || (curActor.Nonce > mNonce && act.Nonce <= mNonce) {
r, foundMsg, err := sm.tipsetExecutedMessage(ctx, cur, m.Cid(), m.VMMessage(), allowReplaced)
r, foundMsg, err := sm.tipsetExecutedMessage(cur, m.Cid(), m.VMMessage(), allowReplaced)
if err != nil {
return nil, nil, cid.Undef, xerrors.Errorf("checking for message execution during lookback: %w", err)
}
@@ -229,18 +229,18 @@ func (sm *StateManager) searchBackForMsg(ctx context.Context, from *types.TipSet
}
}
func (sm *StateManager) tipsetExecutedMessage(ctx context.Context, ts *types.TipSet, msg cid.Cid, vmm *types.Message, allowReplaced bool) (*types.MessageReceipt, cid.Cid, error) {
func (sm *StateManager) tipsetExecutedMessage(ts *types.TipSet, msg cid.Cid, vmm *types.Message, allowReplaced bool) (*types.MessageReceipt, cid.Cid, error) {
// The genesis block did not execute any messages
if ts.Height() == 0 {
return nil, cid.Undef, nil
}
pts, err := sm.cs.LoadTipSet(ctx, ts.Parents())
pts, err := sm.cs.LoadTipSet(ts.Parents())
if err != nil {
return nil, cid.Undef, err
}
cm, err := sm.cs.MessagesForTipset(ctx, pts)
cm, err := sm.cs.MessagesForTipset(pts)
if err != nil {
return nil, cid.Undef, err
}
@@ -267,7 +267,7 @@ func (sm *StateManager) tipsetExecutedMessage(ctx context.Context, ts *types.Tip
}
}
pr, err := sm.cs.GetParentReceipt(ctx, ts.Blocks()[0], i)
pr, err := sm.cs.GetParentReceipt(ts.Blocks()[0], i)
if err != nil {
return nil, cid.Undef, err
}
+2 -2
View File
@@ -75,7 +75,7 @@ func TestSearchForMessageReplacements(t *testing.T) {
t.Fatal(err)
}
err = cg.Blockstore().Put(ctx, rmb)
err = cg.Blockstore().Put(rmb)
if err != nil {
t.Fatal(err)
}
@@ -117,7 +117,7 @@ func TestSearchForMessageReplacements(t *testing.T) {
t.Fatal(err)
}
err = cg.Blockstore().Put(ctx, nrmb)
err = cg.Blockstore().Put(nrmb)
if err != nil {
t.Fatal(err)
}
+20 -8
View File
@@ -321,7 +321,7 @@ func (sm *StateManager) LookupID(ctx context.Context, addr address.Address, ts *
func (sm *StateManager) ValidateChain(ctx context.Context, ts *types.TipSet) error {
tschain := []*types.TipSet{ts}
for ts.Height() != 0 {
next, err := sm.cs.LoadTipSet(ctx, ts.Parents())
next, err := sm.cs.LoadTipSet(ts.Parents())
if err != nil {
return err
}
@@ -357,7 +357,7 @@ func (sm *StateManager) VMConstructor() func(context.Context, *vm.VMOpts) (*vm.V
}
}
func (sm *StateManager) GetNetworkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {
// The epochs here are the _last_ epoch for every version, or -1 if the
// version is disabled.
for _, spec := range sm.networkVersions {
@@ -373,24 +373,36 @@ func (sm *StateManager) VMSys() vm.SyscallBuilder {
}
func (sm *StateManager) GetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) {
pts, err := sm.ChainStore().GetTipSetFromKey(ctx, tsk)
pts, err := sm.ChainStore().GetTipSetFromKey(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon)
rnv := sm.GetNtwkVersion(ctx, randEpoch)
return r.GetBeaconRandomness(ctx, personalization, randEpoch, entropy)
if rnv >= network.Version14 {
return r.GetBeaconRandomnessV3(ctx, personalization, randEpoch, entropy)
} else if rnv == network.Version13 {
return r.GetBeaconRandomnessV2(ctx, personalization, randEpoch, entropy)
}
return r.GetBeaconRandomnessV1(ctx, personalization, randEpoch, entropy)
}
func (sm *StateManager) GetRandomnessFromTickets(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) {
pts, err := sm.ChainStore().LoadTipSet(ctx, tsk)
pts, err := sm.ChainStore().LoadTipSet(tsk)
if err != nil {
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon)
rnv := sm.GetNtwkVersion(ctx, randEpoch)
return r.GetChainRandomness(ctx, personalization, randEpoch, entropy)
if rnv >= network.Version13 {
return r.GetChainRandomnessV2(ctx, personalization, randEpoch, entropy)
}
return r.GetChainRandomnessV1(ctx, personalization, randEpoch, entropy)
}
+1 -1
View File
@@ -31,7 +31,7 @@ import (
// sets up information about the vesting schedule
func (sm *StateManager) setupGenesisVestingSchedule(ctx context.Context) error {
gb, err := sm.cs.GetGenesis(ctx)
gb, err := sm.cs.GetGenesis()
if err != nil {
return xerrors.Errorf("getting genesis block: %w", err)
}
+4 -4
View File
@@ -79,7 +79,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
// future. It's not guaranteed to be accurate... but that's fine.
}
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion)
r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon)
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: height,
@@ -88,7 +88,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
Actors: sm.tsExec.NewActorRegistry(),
Syscalls: sm.Syscalls,
CircSupplyCalc: sm.GetVMCirculatingSupply,
NetworkVersion: sm.GetNetworkVersion(ctx, height),
NtwkVersion: sm.GetNtwkVersion,
BaseFee: ts.Blocks()[0].ParentBaseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts),
}
@@ -128,7 +128,7 @@ func LookbackStateGetterForTipset(sm *StateManager, ts *types.TipSet) vm.Lookbac
func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.TipSet, round abi.ChainEpoch) (*types.TipSet, cid.Cid, error) {
var lbr abi.ChainEpoch
lb := policy.GetWinningPoStSectorSetLookback(sm.GetNetworkVersion(ctx, round))
lb := policy.GetWinningPoStSectorSetLookback(sm.GetNtwkVersion(ctx, round))
if round > lb {
lbr = round - lb
}
@@ -155,7 +155,7 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types.
}
lbts, err := sm.ChainStore().GetTipSetFromKey(ctx, nextTs.Parents())
lbts, err := sm.ChainStore().GetTipSetFromKey(nextTs.Parents())
if err != nil {
return nil, cid.Undef, xerrors.Errorf("failed to resolve lookback tipset: %w", err)
}
+1 -1
View File
@@ -58,7 +58,7 @@ func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi
seen := make(map[cid.Cid]struct{})
for _, b := range ts.Blocks() {
msg1, msg2, err := cs.MessagesForBlock(ctx, b)
msg1, msg2, err := cs.MessagesForBlock(b)
if err != nil {
return zero, xerrors.Errorf("error getting messages for: %s: %w", b.Cid(), err)
}
+8 -10
View File
@@ -10,8 +10,6 @@ import (
)
func TestChainCheckpoint(t *testing.T) {
ctx := context.Background()
cg, err := gen.NewGenerator()
if err != nil {
t.Fatal(err)
@@ -29,11 +27,11 @@ func TestChainCheckpoint(t *testing.T) {
cs := cg.ChainStore()
checkpoint := last
checkpointParents, err := cs.GetTipSetFromKey(ctx, checkpoint.Parents())
checkpointParents, err := cs.GetTipSetFromKey(checkpoint.Parents())
require.NoError(t, err)
// Set the head to the block before the checkpoint.
err = cs.SetHead(ctx, checkpointParents)
err = cs.SetHead(checkpointParents)
require.NoError(t, err)
// Verify it worked.
@@ -41,11 +39,11 @@ func TestChainCheckpoint(t *testing.T) {
require.True(t, head.Equals(checkpointParents))
// Try to set the checkpoint in the future, it should fail.
err = cs.SetCheckpoint(ctx, checkpoint)
err = cs.SetCheckpoint(checkpoint)
require.Error(t, err)
// Then move the head back.
err = cs.SetHead(ctx, checkpoint)
err = cs.SetHead(checkpoint)
require.NoError(t, err)
// Verify it worked.
@@ -53,7 +51,7 @@ func TestChainCheckpoint(t *testing.T) {
require.True(t, head.Equals(checkpoint))
// And checkpoint it.
err = cs.SetCheckpoint(ctx, checkpoint)
err = cs.SetCheckpoint(checkpoint)
require.NoError(t, err)
// Let the second miner miner mine a fork
@@ -72,7 +70,7 @@ func TestChainCheckpoint(t *testing.T) {
require.True(t, head.Equals(checkpoint))
// Remove the checkpoint.
err = cs.RemoveCheckpoint(ctx)
err = cs.RemoveCheckpoint()
require.NoError(t, err)
// Now switch to the other fork.
@@ -82,10 +80,10 @@ func TestChainCheckpoint(t *testing.T) {
require.True(t, head.Equals(last))
// Setting a checkpoint on the other fork should fail.
err = cs.SetCheckpoint(ctx, checkpoint)
err = cs.SetCheckpoint(checkpoint)
require.Error(t, err)
// Setting a checkpoint on this fork should succeed.
err = cs.SetCheckpoint(ctx, checkpointParents)
err = cs.SetCheckpoint(checkpointParents)
require.NoError(t, err)
}
+16 -16
View File
@@ -31,7 +31,7 @@ type ChainIndex struct {
skipLength abi.ChainEpoch
}
type loadTipSetFunc func(context.Context, types.TipSetKey) (*types.TipSet, error)
type loadTipSetFunc func(types.TipSetKey) (*types.TipSet, error)
func NewChainIndex(lts loadTipSetFunc) *ChainIndex {
sc, _ := lru.NewARC(DefaultChainIndexCacheSize)
@@ -49,12 +49,12 @@ type lbEntry struct {
target types.TipSetKey
}
func (ci *ChainIndex) GetTipsetByHeight(ctx context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
func (ci *ChainIndex) GetTipsetByHeight(_ context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
if from.Height()-to <= ci.skipLength {
return ci.walkBack(ctx, from, to)
return ci.walkBack(from, to)
}
rounded, err := ci.roundDown(ctx, from)
rounded, err := ci.roundDown(from)
if err != nil {
return nil, err
}
@@ -63,7 +63,7 @@ func (ci *ChainIndex) GetTipsetByHeight(ctx context.Context, from *types.TipSet,
for {
cval, ok := ci.skipCache.Get(cur)
if !ok {
fc, err := ci.fillCache(ctx, cur)
fc, err := ci.fillCache(cur)
if err != nil {
return nil, err
}
@@ -74,19 +74,19 @@ func (ci *ChainIndex) GetTipsetByHeight(ctx context.Context, from *types.TipSet,
if lbe.ts.Height() == to || lbe.parentHeight < to {
return lbe.ts, nil
} else if to > lbe.targetHeight {
return ci.walkBack(ctx, lbe.ts, to)
return ci.walkBack(lbe.ts, to)
}
cur = lbe.target
}
}
func (ci *ChainIndex) GetTipsetByHeightWithoutCache(ctx context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
return ci.walkBack(ctx, from, to)
func (ci *ChainIndex) GetTipsetByHeightWithoutCache(from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
return ci.walkBack(from, to)
}
func (ci *ChainIndex) fillCache(ctx context.Context, tsk types.TipSetKey) (*lbEntry, error) {
ts, err := ci.loadTipSet(ctx, tsk)
func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) {
ts, err := ci.loadTipSet(tsk)
if err != nil {
return nil, err
}
@@ -101,7 +101,7 @@ func (ci *ChainIndex) fillCache(ctx context.Context, tsk types.TipSetKey) (*lbEn
// will either be equal to ts.Height, or at least > ts.Parent.Height()
rheight := ci.roundHeight(ts.Height())
parent, err := ci.loadTipSet(ctx, ts.Parents())
parent, err := ci.loadTipSet(ts.Parents())
if err != nil {
return nil, err
}
@@ -115,7 +115,7 @@ func (ci *ChainIndex) fillCache(ctx context.Context, tsk types.TipSetKey) (*lbEn
if parent.Height() < rheight {
skipTarget = parent
} else {
skipTarget, err = ci.walkBack(ctx, parent, rheight)
skipTarget, err = ci.walkBack(parent, rheight)
if err != nil {
return nil, xerrors.Errorf("fillCache walkback: %w", err)
}
@@ -137,10 +137,10 @@ func (ci *ChainIndex) roundHeight(h abi.ChainEpoch) abi.ChainEpoch {
return (h / ci.skipLength) * ci.skipLength
}
func (ci *ChainIndex) roundDown(ctx context.Context, ts *types.TipSet) (*types.TipSet, error) {
func (ci *ChainIndex) roundDown(ts *types.TipSet) (*types.TipSet, error) {
target := ci.roundHeight(ts.Height())
rounded, err := ci.walkBack(ctx, ts, target)
rounded, err := ci.walkBack(ts, target)
if err != nil {
return nil, err
}
@@ -148,7 +148,7 @@ func (ci *ChainIndex) roundDown(ctx context.Context, ts *types.TipSet) (*types.T
return rounded, nil
}
func (ci *ChainIndex) walkBack(ctx context.Context, from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
func (ci *ChainIndex) walkBack(from *types.TipSet, to abi.ChainEpoch) (*types.TipSet, error) {
if to > from.Height() {
return nil, xerrors.Errorf("looking for tipset with height greater than start point")
}
@@ -160,7 +160,7 @@ func (ci *ChainIndex) walkBack(ctx context.Context, from *types.TipSet, to abi.C
ts := from
for {
pts, err := ci.loadTipSet(ctx, ts.Parents())
pts, err := ci.loadTipSet(ts.Parents())
if err != nil {
return nil, err
}
+2 -2
View File
@@ -35,7 +35,7 @@ func TestIndexSeeks(t *testing.T) {
cs := store.NewChainStore(nbs, nbs, syncds.MutexWrap(datastore.NewMapDatastore()), filcns.Weight, nil)
defer cs.Close() //nolint:errcheck
_, err = cs.Import(ctx, bytes.NewReader(gencar))
_, err = cs.Import(bytes.NewReader(gencar))
if err != nil {
t.Fatal(err)
}
@@ -44,7 +44,7 @@ func TestIndexSeeks(t *testing.T) {
if err := cs.PutTipSet(ctx, mock.TipSet(gen)); err != nil {
t.Fatal(err)
}
assert.NoError(t, cs.SetGenesis(ctx, gen))
assert.NoError(t, cs.SetGenesis(gen))
// Put 113 blocks from genesis
for i := 0; i < 113; i++ {
+27 -26
View File
@@ -23,25 +23,25 @@ type storable interface {
ToStorageBlock() (block.Block, error)
}
func PutMessage(ctx context.Context, bs bstore.Blockstore, m storable) (cid.Cid, error) {
func PutMessage(bs bstore.Blockstore, m storable) (cid.Cid, error) {
b, err := m.ToStorageBlock()
if err != nil {
return cid.Undef, err
}
if err := bs.Put(ctx, b); err != nil {
if err := bs.Put(b); err != nil {
return cid.Undef, err
}
return b.Cid(), nil
}
func (cs *ChainStore) PutMessage(ctx context.Context, m storable) (cid.Cid, error) {
return PutMessage(ctx, cs.chainBlockstore, m)
func (cs *ChainStore) PutMessage(m storable) (cid.Cid, error) {
return PutMessage(cs.chainBlockstore, m)
}
func (cs *ChainStore) GetCMessage(ctx context.Context, c cid.Cid) (types.ChainMsg, error) {
m, err := cs.GetMessage(ctx, c)
func (cs *ChainStore) GetCMessage(c cid.Cid) (types.ChainMsg, error) {
m, err := cs.GetMessage(c)
if err == nil {
return m, nil
}
@@ -49,21 +49,21 @@ func (cs *ChainStore) GetCMessage(ctx context.Context, c cid.Cid) (types.ChainMs
log.Warnf("GetCMessage: unexpected error getting unsigned message: %s", err)
}
return cs.GetSignedMessage(ctx, c)
return cs.GetSignedMessage(c)
}
func (cs *ChainStore) GetMessage(ctx context.Context, c cid.Cid) (*types.Message, error) {
func (cs *ChainStore) GetMessage(c cid.Cid) (*types.Message, error) {
var msg *types.Message
err := cs.chainLocalBlockstore.View(ctx, c, func(b []byte) (err error) {
err := cs.chainLocalBlockstore.View(c, func(b []byte) (err error) {
msg, err = types.DecodeMessage(b)
return err
})
return msg, err
}
func (cs *ChainStore) GetSignedMessage(ctx context.Context, c cid.Cid) (*types.SignedMessage, error) {
func (cs *ChainStore) GetSignedMessage(c cid.Cid) (*types.SignedMessage, error) {
var msg *types.SignedMessage
err := cs.chainLocalBlockstore.View(ctx, c, func(b []byte) (err error) {
err := cs.chainLocalBlockstore.View(c, func(b []byte) (err error) {
msg, err = types.DecodeSignedMessage(b)
return err
})
@@ -103,7 +103,7 @@ type BlockMessages struct {
SecpkMessages []types.ChainMsg
}
func (cs *ChainStore) BlockMsgsForTipset(ctx context.Context, ts *types.TipSet) ([]BlockMessages, error) {
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
// returned BlockMessages match block order in tipset
applied := make(map[address.Address]uint64)
@@ -142,7 +142,7 @@ func (cs *ChainStore) BlockMsgsForTipset(ctx context.Context, ts *types.TipSet)
var out []BlockMessages
for _, b := range ts.Blocks() {
bms, sms, err := cs.MessagesForBlock(ctx, b)
bms, sms, err := cs.MessagesForBlock(b)
if err != nil {
return nil, xerrors.Errorf("failed to get messages for block: %w", err)
}
@@ -181,8 +181,8 @@ func (cs *ChainStore) BlockMsgsForTipset(ctx context.Context, ts *types.TipSet)
return out, nil
}
func (cs *ChainStore) MessagesForTipset(ctx context.Context, ts *types.TipSet) ([]types.ChainMsg, error) {
bmsgs, err := cs.BlockMsgsForTipset(ctx, ts)
func (cs *ChainStore) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) {
bmsgs, err := cs.BlockMsgsForTipset(ts)
if err != nil {
return nil, err
}
@@ -206,7 +206,7 @@ type mmCids struct {
secpk []cid.Cid
}
func (cs *ChainStore) ReadMsgMetaCids(ctx context.Context, mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) {
func (cs *ChainStore) ReadMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) {
o, ok := cs.mmCache.Get(mmc)
if ok {
mmcids := o.(*mmCids)
@@ -215,7 +215,7 @@ func (cs *ChainStore) ReadMsgMetaCids(ctx context.Context, mmc cid.Cid) ([]cid.C
cst := cbor.NewCborStore(cs.chainLocalBlockstore)
var msgmeta types.MsgMeta
if err := cst.Get(ctx, mmc, &msgmeta); err != nil {
if err := cst.Get(context.TODO(), mmc, &msgmeta); err != nil {
return nil, nil, xerrors.Errorf("failed to load msgmeta (%s): %w", mmc, err)
}
@@ -237,18 +237,18 @@ func (cs *ChainStore) ReadMsgMetaCids(ctx context.Context, mmc cid.Cid) ([]cid.C
return blscids, secpkcids, nil
}
func (cs *ChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
blscids, secpkcids, err := cs.ReadMsgMetaCids(ctx, b.Messages)
func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) {
blscids, secpkcids, err := cs.ReadMsgMetaCids(b.Messages)
if err != nil {
return nil, nil, err
}
blsmsgs, err := cs.LoadMessagesFromCids(ctx, blscids)
blsmsgs, err := cs.LoadMessagesFromCids(blscids)
if err != nil {
return nil, nil, xerrors.Errorf("loading bls messages for block: %w", err)
}
secpkmsgs, err := cs.LoadSignedMessagesFromCids(ctx, secpkcids)
secpkmsgs, err := cs.LoadSignedMessagesFromCids(secpkcids)
if err != nil {
return nil, nil, xerrors.Errorf("loading secpk messages for block: %w", err)
}
@@ -256,7 +256,8 @@ func (cs *ChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader
return blsmsgs, secpkmsgs, nil
}
func (cs *ChainStore) GetParentReceipt(ctx context.Context, b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
func (cs *ChainStore) GetParentReceipt(b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
ctx := context.TODO()
// block headers use adt0, for now.
a, err := blockadt.AsArray(cs.ActorStore(ctx), b.ParentMessageReceipts)
if err != nil {
@@ -273,10 +274,10 @@ func (cs *ChainStore) GetParentReceipt(ctx context.Context, b *types.BlockHeader
return &r, nil
}
func (cs *ChainStore) LoadMessagesFromCids(ctx context.Context, cids []cid.Cid) ([]*types.Message, error) {
func (cs *ChainStore) LoadMessagesFromCids(cids []cid.Cid) ([]*types.Message, error) {
msgs := make([]*types.Message, 0, len(cids))
for i, c := range cids {
m, err := cs.GetMessage(ctx, c)
m, err := cs.GetMessage(c)
if err != nil {
return nil, xerrors.Errorf("failed to get message: (%s):%d: %w", c, i, err)
}
@@ -287,10 +288,10 @@ func (cs *ChainStore) LoadMessagesFromCids(ctx context.Context, cids []cid.Cid)
return msgs, nil
}
func (cs *ChainStore) LoadSignedMessagesFromCids(ctx context.Context, cids []cid.Cid) ([]*types.SignedMessage, error) {
func (cs *ChainStore) LoadSignedMessagesFromCids(cids []cid.Cid) ([]*types.SignedMessage, error) {
msgs := make([]*types.SignedMessage, 0, len(cids))
for i, c := range cids {
m, err := cs.GetSignedMessage(ctx, c)
m, err := cs.GetSignedMessage(c)
if err != nil {
return nil, xerrors.Errorf("failed to get message: (%s):%d: %w", c, i, err)
}
+10 -10
View File
@@ -30,7 +30,7 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
unionBs := bstore.Union(cs.stateBlockstore, cs.chainBlockstore)
return cs.WalkSnapshot(ctx, ts, inclRecentRoots, skipOldMsgs, true, func(c cid.Cid) error {
blk, err := unionBs.Get(ctx, c)
blk, err := unionBs.Get(c)
if err != nil {
return xerrors.Errorf("writing object to car, bs.Get: %w", err)
}
@@ -43,18 +43,18 @@ func (cs *ChainStore) Export(ctx context.Context, ts *types.TipSet, inclRecentRo
})
}
func (cs *ChainStore) Import(ctx context.Context, r io.Reader) (*types.TipSet, error) {
func (cs *ChainStore) Import(r io.Reader) (*types.TipSet, error) {
// TODO: writing only to the state blockstore is incorrect.
// At this time, both the state and chain blockstores are backed by the
// universal store. When we physically segregate the stores, we will need
// to route state objects to the state blockstore, and chain objects to
// the chain blockstore.
header, err := car.LoadCar(ctx, cs.StateBlockstore(), r)
header, err := car.LoadCar(cs.StateBlockstore(), r)
if err != nil {
return nil, xerrors.Errorf("loadcar failed: %w", err)
}
root, err := cs.LoadTipSet(ctx, types.NewTipSetKey(header.Roots...))
root, err := cs.LoadTipSet(types.NewTipSetKey(header.Roots...))
if err != nil {
return nil, xerrors.Errorf("failed to load root tipset from chainfile: %w", err)
}
@@ -82,7 +82,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
return err
}
data, err := cs.chainBlockstore.Get(ctx, blk)
data, err := cs.chainBlockstore.Get(blk)
if err != nil {
return xerrors.Errorf("getting block: %w", err)
}
@@ -102,7 +102,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
var cids []cid.Cid
if !skipOldMsgs || b.Height > ts.Height()-inclRecentRoots {
if walked.Visit(b.Messages) {
mcids, err := recurseLinks(ctx, cs.chainBlockstore, walked, b.Messages, []cid.Cid{b.Messages})
mcids, err := recurseLinks(cs.chainBlockstore, walked, b.Messages, []cid.Cid{b.Messages})
if err != nil {
return xerrors.Errorf("recursing messages failed: %w", err)
}
@@ -123,7 +123,7 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
if b.Height == 0 || b.Height > ts.Height()-inclRecentRoots {
if walked.Visit(b.ParentStateRoot) {
cids, err := recurseLinks(ctx, cs.stateBlockstore, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
cids, err := recurseLinks(cs.stateBlockstore, walked, b.ParentStateRoot, []cid.Cid{b.ParentStateRoot})
if err != nil {
return xerrors.Errorf("recursing genesis state failed: %w", err)
}
@@ -168,12 +168,12 @@ func (cs *ChainStore) WalkSnapshot(ctx context.Context, ts *types.TipSet, inclRe
return nil
}
func recurseLinks(ctx context.Context, bs bstore.Blockstore, walked *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) {
func recurseLinks(bs bstore.Blockstore, walked *cid.Set, root cid.Cid, in []cid.Cid) ([]cid.Cid, error) {
if root.Prefix().Codec != cid.DagCBOR {
return in, nil
}
data, err := bs.Get(ctx, root)
data, err := bs.Get(root)
if err != nil {
return nil, xerrors.Errorf("recurse links get (%s) failed: %w", root, err)
}
@@ -192,7 +192,7 @@ func recurseLinks(ctx context.Context, bs bstore.Blockstore, walked *cid.Set, ro
in = append(in, c)
var err error
in, err = recurseLinks(ctx, bs, walked, c, in)
in, err = recurseLinks(bs, walked, c, in)
if err != nil {
rerr = err
}
+82 -82
View File
@@ -207,17 +207,17 @@ func (cs *ChainStore) Close() error {
return nil
}
func (cs *ChainStore) Load(ctx context.Context) error {
if err := cs.loadHead(ctx); err != nil {
func (cs *ChainStore) Load() error {
if err := cs.loadHead(); err != nil {
return err
}
if err := cs.loadCheckpoint(ctx); err != nil {
if err := cs.loadCheckpoint(); err != nil {
return err
}
return nil
}
func (cs *ChainStore) loadHead(ctx context.Context) error {
head, err := cs.metadataDs.Get(ctx, chainHeadKey)
func (cs *ChainStore) loadHead() error {
head, err := cs.metadataDs.Get(chainHeadKey)
if err == dstore.ErrNotFound {
log.Warn("no previous chain state found")
return nil
@@ -231,7 +231,7 @@ func (cs *ChainStore) loadHead(ctx context.Context) error {
return xerrors.Errorf("failed to unmarshal stored chain head: %w", err)
}
ts, err := cs.LoadTipSet(ctx, types.NewTipSetKey(tscids...))
ts, err := cs.LoadTipSet(types.NewTipSetKey(tscids...))
if err != nil {
return xerrors.Errorf("loading tipset: %w", err)
}
@@ -241,8 +241,8 @@ func (cs *ChainStore) loadHead(ctx context.Context) error {
return nil
}
func (cs *ChainStore) loadCheckpoint(ctx context.Context) error {
tskBytes, err := cs.metadataDs.Get(ctx, checkpointKey)
func (cs *ChainStore) loadCheckpoint() error {
tskBytes, err := cs.metadataDs.Get(checkpointKey)
if err == dstore.ErrNotFound {
return nil
}
@@ -256,7 +256,7 @@ func (cs *ChainStore) loadCheckpoint(ctx context.Context) error {
return err
}
ts, err := cs.LoadTipSet(ctx, tsk)
ts, err := cs.LoadTipSet(tsk)
if err != nil {
return xerrors.Errorf("loading tipset: %w", err)
}
@@ -266,13 +266,13 @@ func (cs *ChainStore) loadCheckpoint(ctx context.Context) error {
return nil
}
func (cs *ChainStore) writeHead(ctx context.Context, ts *types.TipSet) error {
func (cs *ChainStore) writeHead(ts *types.TipSet) error {
data, err := json.Marshal(ts.Cids())
if err != nil {
return xerrors.Errorf("failed to marshal tipset: %w", err)
}
if err := cs.metadataDs.Put(ctx, chainHeadKey, data); err != nil {
if err := cs.metadataDs.Put(chainHeadKey, data); err != nil {
return xerrors.Errorf("failed to write chain head to datastore: %w", err)
}
@@ -341,13 +341,13 @@ func (cs *ChainStore) SubscribeHeadChanges(f ReorgNotifee) {
func (cs *ChainStore) IsBlockValidated(ctx context.Context, blkid cid.Cid) (bool, error) {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
return cs.metadataDs.Has(ctx, key)
return cs.metadataDs.Has(key)
}
func (cs *ChainStore) MarkBlockAsValidated(ctx context.Context, blkid cid.Cid) error {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
if err := cs.metadataDs.Put(ctx, key, []byte{0}); err != nil {
if err := cs.metadataDs.Put(key, []byte{0}); err != nil {
return xerrors.Errorf("cache block validation: %w", err)
}
@@ -357,34 +357,34 @@ func (cs *ChainStore) MarkBlockAsValidated(ctx context.Context, blkid cid.Cid) e
func (cs *ChainStore) UnmarkBlockAsValidated(ctx context.Context, blkid cid.Cid) error {
key := blockValidationCacheKeyPrefix.Instance(blkid.String())
if err := cs.metadataDs.Delete(ctx, key); err != nil {
if err := cs.metadataDs.Delete(key); err != nil {
return xerrors.Errorf("removing from valid block cache: %w", err)
}
return nil
}
func (cs *ChainStore) SetGenesis(ctx context.Context, b *types.BlockHeader) error {
func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
ts, err := types.NewTipSet([]*types.BlockHeader{b})
if err != nil {
return err
}
if err := cs.PutTipSet(ctx, ts); err != nil {
if err := cs.PutTipSet(context.TODO(), ts); err != nil {
return err
}
return cs.metadataDs.Put(ctx, dstore.NewKey("0"), b.Cid().Bytes())
return cs.metadataDs.Put(dstore.NewKey("0"), b.Cid().Bytes())
}
func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
for _, b := range ts.Blocks() {
if err := cs.PersistBlockHeaders(ctx, b); err != nil {
if err := cs.PersistBlockHeaders(b); err != nil {
return err
}
}
expanded, err := cs.expandTipset(ctx, ts.Blocks()[0])
expanded, err := cs.expandTipset(ts.Blocks()[0])
if err != nil {
return xerrors.Errorf("errored while expanding tipset: %w", err)
}
@@ -435,7 +435,7 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
// difference between 'bootstrap sync' and 'caught up' sync, we need
// some other heuristic.
exceeds, err := cs.exceedsForkLength(ctx, cs.heaviest, ts)
exceeds, err := cs.exceedsForkLength(cs.heaviest, ts)
if err != nil {
return err
}
@@ -458,7 +458,7 @@ func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipS
// FIXME: We may want to replace some of the logic in `syncFork()` with this.
// `syncFork()` counts the length on both sides of the fork at the moment (we
// need to settle on that) but here we just enforce it on the `synced` side.
func (cs *ChainStore) exceedsForkLength(ctx context.Context, synced, external *types.TipSet) (bool, error) {
func (cs *ChainStore) exceedsForkLength(synced, external *types.TipSet) (bool, error) {
if synced == nil || external == nil {
// FIXME: If `cs.heaviest` is nil we should just bypass the entire
// `MaybeTakeHeavierTipSet` logic (instead of each of the called
@@ -482,7 +482,7 @@ func (cs *ChainStore) exceedsForkLength(ctx context.Context, synced, external *t
// length).
return true, nil
}
external, err = cs.LoadTipSet(ctx, external.Parents())
external, err = cs.LoadTipSet(external.Parents())
if err != nil {
return false, xerrors.Errorf("failed to load parent tipset in external chain: %w", err)
}
@@ -505,7 +505,7 @@ func (cs *ChainStore) exceedsForkLength(ctx context.Context, synced, external *t
// there is no common ancestor.
return true, nil
}
synced, err = cs.LoadTipSet(ctx, synced.Parents())
synced, err = cs.LoadTipSet(synced.Parents())
if err != nil {
return false, xerrors.Errorf("failed to load parent tipset in synced chain: %w", err)
}
@@ -521,17 +521,17 @@ func (cs *ChainStore) exceedsForkLength(ctx context.Context, synced, external *t
// CAUTION: Use it only for testing, such as to teleport the chain to a
// particular tipset to carry out a benchmark, verification, etc. on a chain
// segment.
func (cs *ChainStore) ForceHeadSilent(ctx context.Context, ts *types.TipSet) error {
func (cs *ChainStore) ForceHeadSilent(_ context.Context, ts *types.TipSet) error {
log.Warnf("(!!!) forcing a new head silently; new head: %s", ts)
cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock()
if err := cs.removeCheckpoint(ctx); err != nil {
if err := cs.removeCheckpoint(); err != nil {
return err
}
cs.heaviest = ts
err := cs.writeHead(ctx, ts)
err := cs.writeHead(ts)
if err != nil {
err = xerrors.Errorf("failed to write chain head: %s", err)
}
@@ -561,7 +561,7 @@ func (cs *ChainStore) reorgWorker(ctx context.Context, initialNotifees []ReorgNo
notifees = append(notifees, n)
case r := <-out:
revert, apply, err := cs.ReorgOps(ctx, r.old, r.new)
revert, apply, err := cs.ReorgOps(r.old, r.new)
if err != nil {
log.Error("computing reorg ops failed: ", err)
continue
@@ -646,7 +646,7 @@ func (cs *ChainStore) takeHeaviestTipSet(ctx context.Context, ts *types.TipSet)
log.Infof("New heaviest tipset! %s (height=%d)", ts.Cids(), ts.Height())
cs.heaviest = ts
if err := cs.writeHead(ctx, ts); err != nil {
if err := cs.writeHead(ts); err != nil {
log.Errorf("failed to write chain head: %s", err)
return nil
}
@@ -656,14 +656,14 @@ func (cs *ChainStore) takeHeaviestTipSet(ctx context.Context, ts *types.TipSet)
// FlushValidationCache removes all results of block validation from the
// chain metadata store. Usually the first step after a new chain import.
func (cs *ChainStore) FlushValidationCache(ctx context.Context) error {
return FlushValidationCache(ctx, cs.metadataDs)
func (cs *ChainStore) FlushValidationCache() error {
return FlushValidationCache(cs.metadataDs)
}
func FlushValidationCache(ctx context.Context, ds dstore.Batching) error {
func FlushValidationCache(ds dstore.Batching) error {
log.Infof("clearing block validation cache...")
dsWalk, err := ds.Query(ctx, query.Query{
dsWalk, err := ds.Query(query.Query{
// Potential TODO: the validation cache is not a namespace on its own
// but is rather constructed as prefixed-key `foo:bar` via .Instance(), which
// in turn does not work with the filter, which can match only on `foo/bar`
@@ -683,7 +683,7 @@ func FlushValidationCache(ctx context.Context, ds dstore.Batching) error {
return xerrors.Errorf("failed to run key listing query: %w", err)
}
batch, err := ds.Batch(ctx)
batch, err := ds.Batch()
if err != nil {
return xerrors.Errorf("failed to open a DS batch: %w", err)
}
@@ -692,11 +692,11 @@ func FlushValidationCache(ctx context.Context, ds dstore.Batching) error {
for _, k := range allKeys {
if strings.HasPrefix(k.Key, blockValidationCacheKeyPrefix.String()) {
delCnt++
batch.Delete(ctx, dstore.RawKey(k.Key)) // nolint:errcheck
batch.Delete(dstore.RawKey(k.Key)) // nolint:errcheck
}
}
if err := batch.Commit(ctx); err != nil {
if err := batch.Commit(); err != nil {
return xerrors.Errorf("failed to commit the DS batch: %w", err)
}
@@ -709,24 +709,24 @@ func FlushValidationCache(ctx context.Context, ds dstore.Batching) error {
// This should only be called if something is broken and needs fixing.
//
// This function will bypass and remove any checkpoints.
func (cs *ChainStore) SetHead(ctx context.Context, ts *types.TipSet) error {
func (cs *ChainStore) SetHead(ts *types.TipSet) error {
cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock()
if err := cs.removeCheckpoint(ctx); err != nil {
if err := cs.removeCheckpoint(); err != nil {
return err
}
return cs.takeHeaviestTipSet(context.TODO(), ts)
}
// RemoveCheckpoint removes the current checkpoint.
func (cs *ChainStore) RemoveCheckpoint(ctx context.Context) error {
func (cs *ChainStore) RemoveCheckpoint() error {
cs.heaviestLk.Lock()
defer cs.heaviestLk.Unlock()
return cs.removeCheckpoint(ctx)
return cs.removeCheckpoint()
}
func (cs *ChainStore) removeCheckpoint(ctx context.Context) error {
if err := cs.metadataDs.Delete(ctx, checkpointKey); err != nil {
func (cs *ChainStore) removeCheckpoint() error {
if err := cs.metadataDs.Delete(checkpointKey); err != nil {
return err
}
cs.checkpoint = nil
@@ -736,7 +736,7 @@ func (cs *ChainStore) removeCheckpoint(ctx context.Context) error {
// SetCheckpoint will set a checkpoint past which the chainstore will not allow forks.
//
// NOTE: Checkpoints cannot be set beyond ForkLengthThreshold epochs in the past.
func (cs *ChainStore) SetCheckpoint(ctx context.Context, ts *types.TipSet) error {
func (cs *ChainStore) SetCheckpoint(ts *types.TipSet) error {
tskBytes, err := json.Marshal(ts.Key())
if err != nil {
return err
@@ -755,7 +755,7 @@ func (cs *ChainStore) SetCheckpoint(ctx context.Context, ts *types.TipSet) error
}
if !ts.Equals(cs.heaviest) {
anc, err := cs.IsAncestorOf(ctx, ts, cs.heaviest)
anc, err := cs.IsAncestorOf(ts, cs.heaviest)
if err != nil {
return xerrors.Errorf("cannot determine whether checkpoint tipset is in main-chain: %w", err)
}
@@ -764,7 +764,7 @@ func (cs *ChainStore) SetCheckpoint(ctx context.Context, ts *types.TipSet) error
return xerrors.Errorf("cannot mark tipset as checkpoint, since it isn't in the main-chain: %w", err)
}
}
err = cs.metadataDs.Put(ctx, checkpointKey, tskBytes)
err = cs.metadataDs.Put(checkpointKey, tskBytes)
if err != nil {
return err
}
@@ -781,9 +781,9 @@ func (cs *ChainStore) GetCheckpoint() *types.TipSet {
}
// Contains returns whether our BlockStore has all blocks in the supplied TipSet.
func (cs *ChainStore) Contains(ctx context.Context, ts *types.TipSet) (bool, error) {
func (cs *ChainStore) Contains(ts *types.TipSet) (bool, error) {
for _, c := range ts.Cids() {
has, err := cs.chainBlockstore.Has(ctx, c)
has, err := cs.chainBlockstore.Has(c)
if err != nil {
return false, err
}
@@ -797,16 +797,16 @@ func (cs *ChainStore) Contains(ctx context.Context, ts *types.TipSet) (bool, err
// GetBlock fetches a BlockHeader with the supplied CID. It returns
// blockstore.ErrNotFound if the block was not found in the BlockStore.
func (cs *ChainStore) GetBlock(ctx context.Context, c cid.Cid) (*types.BlockHeader, error) {
func (cs *ChainStore) GetBlock(c cid.Cid) (*types.BlockHeader, error) {
var blk *types.BlockHeader
err := cs.chainLocalBlockstore.View(ctx, c, func(b []byte) (err error) {
err := cs.chainLocalBlockstore.View(c, func(b []byte) (err error) {
blk, err = types.DecodeBlock(b)
return err
})
return blk, err
}
func (cs *ChainStore) LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
func (cs *ChainStore) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) {
v, ok := cs.tsCache.Get(tsk)
if ok {
return v.(*types.TipSet), nil
@@ -819,7 +819,7 @@ func (cs *ChainStore) LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*typ
for i, c := range cids {
i, c := i, c
eg.Go(func() error {
b, err := cs.GetBlock(ctx, c)
b, err := cs.GetBlock(c)
if err != nil {
return xerrors.Errorf("get block %s: %w", c, err)
}
@@ -844,14 +844,14 @@ func (cs *ChainStore) LoadTipSet(ctx context.Context, tsk types.TipSetKey) (*typ
}
// IsAncestorOf returns true if 'a' is an ancestor of 'b'
func (cs *ChainStore) IsAncestorOf(ctx context.Context, a, b *types.TipSet) (bool, error) {
func (cs *ChainStore) IsAncestorOf(a, b *types.TipSet) (bool, error) {
if b.Height() <= a.Height() {
return false, nil
}
cur := b
for !a.Equals(cur) && cur.Height() > a.Height() {
next, err := cs.LoadTipSet(ctx, cur.Parents())
next, err := cs.LoadTipSet(cur.Parents())
if err != nil {
return false, err
}
@@ -862,13 +862,13 @@ func (cs *ChainStore) IsAncestorOf(ctx context.Context, a, b *types.TipSet) (boo
return cur.Equals(a), nil
}
func (cs *ChainStore) NearestCommonAncestor(ctx context.Context, a, b *types.TipSet) (*types.TipSet, error) {
l, _, err := cs.ReorgOps(ctx, a, b)
func (cs *ChainStore) NearestCommonAncestor(a, b *types.TipSet) (*types.TipSet, error) {
l, _, err := cs.ReorgOps(a, b)
if err != nil {
return nil, err
}
return cs.LoadTipSet(ctx, l[len(l)-1].Parents())
return cs.LoadTipSet(l[len(l)-1].Parents())
}
// ReorgOps takes two tipsets (which can be at different heights), and walks
@@ -879,11 +879,11 @@ func (cs *ChainStore) NearestCommonAncestor(ctx context.Context, a, b *types.Tip
// ancestor.
//
// If an error happens along the way, we return the error with nil slices.
func (cs *ChainStore) ReorgOps(ctx context.Context, a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) {
return ReorgOps(ctx, cs.LoadTipSet, a, b)
func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) {
return ReorgOps(cs.LoadTipSet, a, b)
}
func ReorgOps(ctx context.Context, lts func(ctx context.Context, _ types.TipSetKey) (*types.TipSet, error), a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) {
func ReorgOps(lts func(types.TipSetKey) (*types.TipSet, error), a, b *types.TipSet) ([]*types.TipSet, []*types.TipSet, error) {
left := a
right := b
@@ -891,7 +891,7 @@ func ReorgOps(ctx context.Context, lts func(ctx context.Context, _ types.TipSetK
for !left.Equals(right) {
if left.Height() > right.Height() {
leftChain = append(leftChain, left)
par, err := lts(ctx, left.Parents())
par, err := lts(left.Parents())
if err != nil {
return nil, nil, err
}
@@ -899,7 +899,7 @@ func ReorgOps(ctx context.Context, lts func(ctx context.Context, _ types.TipSetK
left = par
} else {
rightChain = append(rightChain, right)
par, err := lts(ctx, right.Parents())
par, err := lts(right.Parents())
if err != nil {
log.Infof("failed to fetch right.Parents: %s", err)
return nil, nil, err
@@ -921,7 +921,7 @@ func (cs *ChainStore) GetHeaviestTipSet() (ts *types.TipSet) {
return
}
func (cs *ChainStore) AddToTipSetTracker(ctx context.Context, b *types.BlockHeader) error {
func (cs *ChainStore) AddToTipSetTracker(b *types.BlockHeader) error {
cs.tstLk.Lock()
defer cs.tstLk.Unlock()
@@ -931,7 +931,7 @@ func (cs *ChainStore) AddToTipSetTracker(ctx context.Context, b *types.BlockHead
log.Debug("tried to add block to tipset tracker that was already there")
return nil
}
h, err := cs.GetBlock(ctx, oc)
h, err := cs.GetBlock(oc)
if err == nil && h != nil {
if h.Miner == b.Miner {
log.Warnf("Have multiple blocks from miner %s at height %d in our tipset cache %s-%s", b.Miner, b.Height, b.Cid(), h.Cid())
@@ -960,7 +960,7 @@ func (cs *ChainStore) AddToTipSetTracker(ctx context.Context, b *types.BlockHead
return nil
}
func (cs *ChainStore) PersistBlockHeaders(ctx context.Context, b ...*types.BlockHeader) error {
func (cs *ChainStore) PersistBlockHeaders(b ...*types.BlockHeader) error {
sbs := make([]block.Block, len(b))
for i, header := range b {
@@ -982,13 +982,13 @@ func (cs *ChainStore) PersistBlockHeaders(ctx context.Context, b ...*types.Block
end = len(b)
}
err = multierr.Append(err, cs.chainLocalBlockstore.PutMany(ctx, sbs[start:end]))
err = multierr.Append(err, cs.chainLocalBlockstore.PutMany(sbs[start:end]))
}
return err
}
func (cs *ChainStore) expandTipset(ctx context.Context, b *types.BlockHeader) (*types.TipSet, error) {
func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error) {
// Hold lock for the whole function for now, if it becomes a problem we can
// fix pretty easily
cs.tstLk.Lock()
@@ -1007,7 +1007,7 @@ func (cs *ChainStore) expandTipset(ctx context.Context, b *types.BlockHeader) (*
continue
}
h, err := cs.GetBlock(ctx, bhc)
h, err := cs.GetBlock(bhc)
if err != nil {
return nil, xerrors.Errorf("failed to load block (%s) for tipset expansion: %w", bhc, err)
}
@@ -1029,11 +1029,11 @@ func (cs *ChainStore) expandTipset(ctx context.Context, b *types.BlockHeader) (*
}
func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error {
if err := cs.PersistBlockHeaders(ctx, b); err != nil {
if err := cs.PersistBlockHeaders(b); err != nil {
return err
}
ts, err := cs.expandTipset(ctx, b)
ts, err := cs.expandTipset(b)
if err != nil {
return err
}
@@ -1045,8 +1045,8 @@ func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error
return nil
}
func (cs *ChainStore) GetGenesis(ctx context.Context) (*types.BlockHeader, error) {
data, err := cs.metadataDs.Get(ctx, dstore.NewKey("0"))
func (cs *ChainStore) GetGenesis() (*types.BlockHeader, error) {
data, err := cs.metadataDs.Get(dstore.NewKey("0"))
if err != nil {
return nil, err
}
@@ -1056,22 +1056,22 @@ func (cs *ChainStore) GetGenesis(ctx context.Context) (*types.BlockHeader, error
return nil, err
}
return cs.GetBlock(ctx, c)
return cs.GetBlock(c)
}
// GetPath returns the sequence of atomic head change operations that
// need to be applied in order to switch the head of the chain from the `from`
// tipset to the `to` tipset.
func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*api.HeadChange, error) {
fts, err := cs.LoadTipSet(ctx, from)
fts, err := cs.LoadTipSet(from)
if err != nil {
return nil, xerrors.Errorf("loading from tipset %s: %w", from, err)
}
tts, err := cs.LoadTipSet(ctx, to)
tts, err := cs.LoadTipSet(to)
if err != nil {
return nil, xerrors.Errorf("loading to tipset %s: %w", to, err)
}
revert, apply, err := cs.ReorgOps(ctx, fts, tts)
revert, apply, err := cs.ReorgOps(fts, tts)
if err != nil {
return nil, xerrors.Errorf("error getting tipset branches: %w", err)
}
@@ -1108,11 +1108,11 @@ func (cs *ChainStore) ActorStore(ctx context.Context) adt.Store {
return ActorStore(ctx, cs.stateBlockstore)
}
func (cs *ChainStore) TryFillTipSet(ctx context.Context, ts *types.TipSet) (*FullTipSet, error) {
func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
var out []*types.FullBlock
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := cs.MessagesForBlock(ctx, b)
bmsgs, smsgs, err := cs.MessagesForBlock(b)
if err != nil {
// TODO: check for 'not found' errors, and only return nil if this
// is actually a 'not found' error
@@ -1154,7 +1154,7 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
if lbts.Height() < h {
log.Warnf("chain index returned the wrong tipset at height %d, using slow retrieval", h)
lbts, err = cs.cindex.GetTipsetByHeightWithoutCache(ctx, ts, h)
lbts, err = cs.cindex.GetTipsetByHeightWithoutCache(ts, h)
if err != nil {
return nil, err
}
@@ -1164,7 +1164,7 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
return lbts, nil
}
return cs.LoadTipSet(ctx, lbts.Parents())
return cs.LoadTipSet(lbts.Parents())
}
func (cs *ChainStore) Weight(ctx context.Context, hts *types.TipSet) (types.BigInt, error) { // todo remove
@@ -1190,14 +1190,14 @@ func breakWeightTie(ts1, ts2 *types.TipSet) bool {
return false
}
func (cs *ChainStore) GetTipSetFromKey(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error) {
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {
if tsk.IsEmpty() {
return cs.GetHeaviestTipSet(), nil
}
return cs.LoadTipSet(ctx, tsk)
return cs.LoadTipSet(tsk)
}
func (cs *ChainStore) GetLatestBeaconEntry(ctx context.Context, ts *types.TipSet) (*types.BeaconEntry, error) {
func (cs *ChainStore) GetLatestBeaconEntry(ts *types.TipSet) (*types.BeaconEntry, error) {
cur := ts
for i := 0; i < 20; i++ {
cbe := cur.Blocks()[0].BeaconEntries
@@ -1209,7 +1209,7 @@ func (cs *ChainStore) GetLatestBeaconEntry(ctx context.Context, ts *types.TipSet
return nil, xerrors.Errorf("made it back to genesis block without finding beacon entry")
}
next, err := cs.LoadTipSet(ctx, cur.Parents())
next, err := cs.LoadTipSet(cur.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load parents when searching back for latest beacon entry: %w", err)
}
+3 -3
View File
@@ -109,7 +109,7 @@ func TestChainExportImport(t *testing.T) {
cs := store.NewChainStore(nbs, nbs, datastore.NewMapDatastore(), filcns.Weight, nil)
defer cs.Close() //nolint:errcheck
root, err := cs.Import(context.TODO(), buf)
root, err := cs.Import(buf)
if err != nil {
t.Fatal(err)
}
@@ -144,12 +144,12 @@ func TestChainExportImportFull(t *testing.T) {
cs := store.NewChainStore(nbs, nbs, datastore.NewMapDatastore(), filcns.Weight, nil)
defer cs.Close() //nolint:errcheck
root, err := cs.Import(context.TODO(), buf)
root, err := cs.Import(buf)
if err != nil {
t.Fatal(err)
}
err = cs.SetHead(context.Background(), last)
err = cs.SetHead(last)
if err != nil {
t.Fatal(err)
}
+4 -174
View File
@@ -1,24 +1,19 @@
package sub
import (
"bytes"
"context"
"encoding/binary"
"sync"
"fmt"
"time"
address "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-legs/dtsync"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/messagepool"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/sub/ratelimit"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/metrics"
"github.com/filecoin-project/lotus/node/impl/client"
"github.com/filecoin-project/lotus/node/impl/full"
lru "github.com/hashicorp/golang-lru"
blocks "github.com/ipfs/go-block-format"
bserv "github.com/ipfs/go-blockservice"
@@ -173,12 +168,12 @@ func fetchCids(
cidIndex := make(map[cid.Cid]int)
for i, c := range cids {
if c.Prefix() != msgCidPrefix {
return xerrors.Errorf("invalid msg CID: %s", c)
return fmt.Errorf("invalid msg CID: %s", c)
}
cidIndex[c] = i
}
if len(cids) != len(cidIndex) {
return xerrors.Errorf("duplicate CIDs in fetchCids input")
return fmt.Errorf("duplicate CIDs in fetchCids input")
}
for block := range bserv.GetBlocks(ctx, cids) {
@@ -201,7 +196,7 @@ func fetchCids(
if len(cidIndex) > 0 {
err := ctx.Err()
if err == nil {
err = xerrors.Errorf("failed to fetch %d messages for unknown reasons", len(cidIndex))
err = fmt.Errorf("failed to fetch %d messages for unknown reasons", len(cidIndex))
}
return err
}
@@ -449,168 +444,3 @@ func recordFailure(ctx context.Context, metric *stats.Int64Measure, failureType
)
stats.Record(ctx, metric.M(1))
}
type peerMsgInfo struct {
peerID peer.ID
lastCid cid.Cid
lastSeqno uint64
rateLimit *ratelimit.Window
mutex sync.Mutex
}
type IndexerMessageValidator struct {
self peer.ID
peerCache *lru.TwoQueueCache
chainApi full.ChainModuleAPI
stateApi full.StateModuleAPI
}
func NewIndexerMessageValidator(self peer.ID, chainApi full.ChainModuleAPI, stateApi full.StateModuleAPI) *IndexerMessageValidator {
peerCache, _ := lru.New2Q(8192)
return &IndexerMessageValidator{
self: self,
peerCache: peerCache,
chainApi: chainApi,
stateApi: stateApi,
}
}
func (v *IndexerMessageValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub.Message) pubsub.ValidationResult {
// This chain-node should not be publishing its own messages. These are
// relayed from market-nodes. If a node appears to be local, reject it.
if pid == v.self {
log.Debug("ignoring indexer message from self")
stats.Record(ctx, metrics.IndexerMessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
originPeer := msg.GetFrom()
if originPeer == v.self {
log.Debug("ignoring indexer message originating from self")
stats.Record(ctx, metrics.IndexerMessageValidationFailure.M(1))
return pubsub.ValidationIgnore
}
idxrMsg := dtsync.Message{}
err := idxrMsg.UnmarshalCBOR(bytes.NewBuffer(msg.Data))
if err != nil {
log.Errorw("Could not decode indexer pubsub message", "err", err)
return pubsub.ValidationReject
}
if len(idxrMsg.ExtraData) == 0 {
log.Debugw("ignoring messsage missing miner id", "peer", originPeer)
return pubsub.ValidationIgnore
}
// Get miner info from lotus
minerAddr, err := address.NewFromBytes(idxrMsg.ExtraData)
if err != nil {
log.Warnw("cannot parse extra data as miner address", "err", err, "extraData", idxrMsg.ExtraData)
return pubsub.ValidationReject
}
minerID := minerAddr.String()
msgCid := idxrMsg.Cid
var msgInfo *peerMsgInfo
val, ok := v.peerCache.Get(minerID)
if !ok {
msgInfo = &peerMsgInfo{}
} else {
msgInfo = val.(*peerMsgInfo)
}
// Lock this peer's message info.
msgInfo.mutex.Lock()
defer msgInfo.mutex.Unlock()
if ok {
// Reject replayed messages.
seqno := binary.BigEndian.Uint64(msg.Message.GetSeqno())
if seqno <= msgInfo.lastSeqno {
log.Debugf("ignoring replayed indexer message")
return pubsub.ValidationIgnore
}
msgInfo.lastSeqno = seqno
}
if !ok || originPeer != msgInfo.peerID {
// Check that the miner ID maps to the peer that sent the message.
err = v.authenticateMessage(ctx, minerAddr, originPeer)
if err != nil {
log.Warnw("cannot authenticate messsage", "err", err, "peer", originPeer, "minerID", minerID)
stats.Record(ctx, metrics.IndexerMessageValidationFailure.M(1))
return pubsub.ValidationReject
}
msgInfo.peerID = originPeer
if !ok {
// Add msgInfo to cache only after being authenticated. If two
// messages from the same peer are handled concurrently, there is a
// small chance that one msgInfo could replace the other here when
// the info is first cached. This is OK, so no need to prevent it.
v.peerCache.Add(minerID, msgInfo)
}
}
// See if message needs to be ignored due to rate limiting.
if v.rateLimitPeer(msgInfo, msgCid) {
return pubsub.ValidationIgnore
}
stats.Record(ctx, metrics.IndexerMessageValidationSuccess.M(1))
return pubsub.ValidationAccept
}
func (v *IndexerMessageValidator) rateLimitPeer(msgInfo *peerMsgInfo, msgCid cid.Cid) bool {
const (
msgLimit = 5
msgTimeLimit = 10 * time.Second
repeatTimeLimit = 2 * time.Hour
)
timeWindow := msgInfo.rateLimit
// Check overall message rate.
if timeWindow == nil {
timeWindow = ratelimit.NewWindow(msgLimit, msgTimeLimit)
msgInfo.rateLimit = timeWindow
} else if msgInfo.lastCid == msgCid {
// Check if this is a repeat of the previous message data.
if time.Since(timeWindow.Newest()) < repeatTimeLimit {
log.Warnw("ignoring repeated indexer message", "sender", msgInfo.peerID)
return true
}
}
err := timeWindow.Add()
if err != nil {
log.Warnw("ignoring indexer message", "sender", msgInfo.peerID, "err", err)
return true
}
msgInfo.lastCid = msgCid
return false
}
func (v *IndexerMessageValidator) authenticateMessage(ctx context.Context, minerAddress address.Address, peerID peer.ID) error {
ts, err := v.chainApi.ChainHead(ctx)
if err != nil {
return err
}
minerInfo, err := v.stateApi.StateMinerInfo(ctx, minerAddress, ts.Key())
if err != nil {
return err
}
if minerInfo.PeerId == nil {
return xerrors.New("no peer id for miner")
}
if *minerInfo.PeerId != peerID {
return xerrors.New("miner id does not map to peer that sent message")
}
return nil
}
+1 -72
View File
@@ -1,21 +1,13 @@
//stm: #unit
package sub
import (
"bytes"
"context"
"testing"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-legs/dtsync"
"github.com/filecoin-project/lotus/api/mocks"
address "github.com/filecoin-project/go-address"
"github.com/filecoin-project/lotus/chain/types"
"github.com/golang/mock/gomock"
blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pb "github.com/libp2p/go-libp2p-pubsub/pb"
)
type getter struct {
@@ -57,7 +49,6 @@ func TestFetchCidsWithDedup(t *testing.T) {
}
g := &getter{msgs}
//stm: @CHAIN_INCOMING_FETCH_MESSAGES_BY_CID_001
// the cids have a duplicate
res, err := FetchMessagesByCids(context.TODO(), g, append(cids, cids[0]))
@@ -70,65 +61,3 @@ func TestFetchCidsWithDedup(t *testing.T) {
t.Fatalf("there is a nil message: first %p, last %p", res[0], res[len(res)-1])
}
}
func TestIndexerMessageValidator_Validate(t *testing.T) {
validCid, err := cid.Decode("QmbpDgg5kRLDgMxS8vPKNFXEcA6D5MC4CkuUdSWDVtHPGK")
if err != nil {
t.Fatal(err)
}
tests := []struct {
name string
selfPID string
senderPID string
extraData []byte
wantValidation pubsub.ValidationResult
}{
{
name: "invalid extra data is rejected",
selfPID: "12D3KooWQiCbqEStCkdqUvr69gQsrp9urYJZUCkzsQXia7mbqbFW",
senderPID: "12D3KooWE8yt84RVwW3sFcd6WMjbUdWrZer2YtT4dmtj3dHdahSZ",
extraData: []byte("f0127896"), // note, casting encoded address to byte is invalid.
wantValidation: pubsub.ValidationReject,
},
{
name: "same sender and receiver is ignored",
selfPID: "12D3KooWQiCbqEStCkdqUvr69gQsrp9urYJZUCkzsQXia7mbqbFW",
senderPID: "12D3KooWQiCbqEStCkdqUvr69gQsrp9urYJZUCkzsQXia7mbqbFW",
wantValidation: pubsub.ValidationIgnore,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
mc := gomock.NewController(t)
node := mocks.NewMockFullNode(mc)
subject := NewIndexerMessageValidator(peer.ID(tc.selfPID), node, node)
message := dtsync.Message{
Cid: validCid,
Addrs: nil,
ExtraData: tc.extraData,
}
buf := bytes.NewBuffer(nil)
if err := message.MarshalCBOR(buf); err != nil {
t.Fatal(err)
}
topic := "topic"
pbm := &pb.Message{
Data: buf.Bytes(),
Topic: &topic,
From: nil,
Seqno: nil,
}
validate := subject.Validate(context.Background(), peer.ID(tc.senderPID), &pubsub.Message{
Message: pbm,
ReceivedFrom: peer.ID(tc.senderPID),
ValidatorData: nil,
})
if validate != tc.wantValidation {
t.Fatalf("expected %v but got %v", tc.wantValidation, validate)
}
})
}
}
-89
View File
@@ -1,89 +0,0 @@
package ratelimit
import "errors"
var ErrRateLimitExceeded = errors.New("rate limit exceeded")
type queue struct {
buf []int64
count int
head int
tail int
}
// cap returns the queue capacity
func (q *queue) cap() int {
return len(q.buf)
}
// len returns the number of items in the queue
func (q *queue) len() int {
return q.count
}
// push adds an element to the end of the queue.
func (q *queue) push(elem int64) error {
if q.count == len(q.buf) {
return ErrRateLimitExceeded
}
q.buf[q.tail] = elem
// Calculate new tail position.
q.tail = q.next(q.tail)
q.count++
return nil
}
// pop removes and returns the element from the front of the queue.
func (q *queue) pop() int64 {
if q.count <= 0 {
panic("pop from empty queue")
}
ret := q.buf[q.head]
// Calculate new head position.
q.head = q.next(q.head)
q.count--
return ret
}
// front returns the element at the front of the queue. This is the element
// that would be returned by pop(). This call panics if the queue is empty.
func (q *queue) front() int64 {
if q.count <= 0 {
panic("front() called when empty")
}
return q.buf[q.head]
}
// back returns the element at the back of the queue. This call panics if the
// queue is empty.
func (q *queue) back() int64 {
if q.count <= 0 {
panic("back() called when empty")
}
return q.buf[q.prev(q.tail)]
}
// prev returns the previous buffer position wrapping around buffer.
func (q *queue) prev(i int) int {
if i == 0 {
return len(q.buf) - 1
}
return (i - 1) % len(q.buf)
}
// next returns the next buffer position wrapping around buffer.
func (q *queue) next(i int) int {
return (i + 1) % len(q.buf)
}
// truncate pops values that are less than or equal the specified threshold.
func (q *queue) truncate(threshold int64) {
for q.count != 0 && q.buf[q.head] <= threshold {
// pop() without returning a value
q.head = q.next(q.head)
q.count--
}
}
-70
View File
@@ -1,70 +0,0 @@
package ratelimit
import "time"
// Window is a time windows for counting events within a span of time. The
// windows slides forward in time so that it spans from the most recent event
// to size time in the past.
type Window struct {
q *queue
size int64
}
// NewWindow creates a new Window that limits the number of events to maximum
// count of events within a duration of time. The capacity sets the maximum
// number of events, and size sets the span of time over which the events are
// counted.
func NewWindow(capacity int, size time.Duration) *Window {
return &Window{
q: &queue{
buf: make([]int64, capacity),
},
size: int64(size),
}
}
// Add attempts to append a new timestamp into the current window. Previously
// added values that are not not within `size` difference from the value being
// added are first removed. Add fails if adding the value would cause the
// window to exceed capacity.
func (w *Window) Add() error {
now := time.Now().UnixNano()
if w.Len() != 0 {
w.q.truncate(now - w.size)
}
return w.q.push(now)
}
// Cap returns the maximum number of items the window can hold.
func (w *Window) Cap() int {
return w.q.cap()
}
// Len returns the number of elements currently in the window.
func (w *Window) Len() int {
return w.q.len()
}
// Span returns the distance from the first to the last item in the window.
func (w *Window) Span() time.Duration {
if w.q.len() < 2 {
return 0
}
return time.Duration(w.q.back() - w.q.front())
}
// Oldest returns the oldest timestamp in the window.
func (w *Window) Oldest() time.Time {
if w.q.len() == 0 {
return time.Time{}
}
return time.Unix(0, w.q.front())
}
// Newest returns the newest timestamp in the window.
func (w *Window) Newest() time.Time {
if w.q.len() == 0 {
return time.Time{}
}
return time.Unix(0, w.q.back())
}
-61
View File
@@ -1,61 +0,0 @@
package ratelimit
import (
"testing"
"time"
)
func TestWindow(t *testing.T) {
const (
maxEvents = 3
timeLimit = 100 * time.Millisecond
)
w := NewWindow(maxEvents, timeLimit)
if w.Len() != 0 {
t.Fatal("q.Len() =", w.Len(), "expect 0")
}
if w.Cap() != maxEvents {
t.Fatal("q.Cap() =", w.Cap(), "expect 3")
}
if !w.Newest().IsZero() {
t.Fatal("expected newest to be zero time with empty window")
}
if !w.Oldest().IsZero() {
t.Fatal("expected oldest to be zero time with empty window")
}
if w.Span() != 0 {
t.Fatal("expected span to be zero time with empty window")
}
var err error
for i := 0; i < maxEvents; i++ {
err = w.Add()
if err != nil {
t.Fatalf("cannot add event %d", i)
}
}
if w.Len() != maxEvents {
t.Fatalf("q.Len() is %d, expected %d", w.Len(), maxEvents)
}
if err = w.Add(); err != ErrRateLimitExceeded {
t.Fatalf("add event %d within time limit should have failed with err: %s", maxEvents+1, ErrRateLimitExceeded)
}
time.Sleep(timeLimit)
if err = w.Add(); err != nil {
t.Fatalf("cannot add event after time limit: %s", err)
}
prev := w.Newest()
time.Sleep(timeLimit)
err = w.Add()
if err != nil {
t.Fatalf("cannot add event")
}
if w.Newest().Before(prev) {
t.Fatal("newest is before previous value")
}
if w.Oldest().Before(prev) {
t.Fatal("oldest is before previous value")
}
}
+23 -23
View File
@@ -119,8 +119,8 @@ type SyncManagerCtor func(syncFn SyncFunc) SyncManager
type Genesis *types.TipSet
func LoadGenesis(ctx context.Context, sm *stmgr.StateManager) (Genesis, error) {
gen, err := sm.ChainStore().GetGenesis(ctx)
func LoadGenesis(sm *stmgr.StateManager) (Genesis, error) {
gen, err := sm.ChainStore().GetGenesis()
if err != nil {
return nil, xerrors.Errorf("getting genesis block: %w", err)
}
@@ -227,7 +227,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
// TODO: IMPORTANT(GARBAGE) this needs to be put in the 'temporary' side of
// the blockstore
if err := syncer.store.PersistBlockHeaders(ctx, fts.TipSet().Blocks()...); err != nil {
if err := syncer.store.PersistBlockHeaders(fts.TipSet().Blocks()...); err != nil {
log.Warn("failed to persist incoming block header: ", err)
return false
}
@@ -298,11 +298,11 @@ func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error {
// into the blockstore.
blockstore := bstore.NewMemory()
cst := cbor.NewCborStore(blockstore)
ctx := context.Background()
var bcids, scids []cid.Cid
for _, m := range fblk.BlsMessages {
c, err := store.PutMessage(ctx, blockstore, m)
c, err := store.PutMessage(blockstore, m)
if err != nil {
return xerrors.Errorf("putting bls message to blockstore after msgmeta computation: %w", err)
}
@@ -310,7 +310,7 @@ func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error {
}
for _, m := range fblk.SecpkMessages {
c, err := store.PutMessage(ctx, blockstore, m)
c, err := store.PutMessage(blockstore, m)
if err != nil {
return xerrors.Errorf("putting bls message to blockstore after msgmeta computation: %w", err)
}
@@ -360,7 +360,7 @@ func copyBlockstore(ctx context.Context, from, to bstore.Blockstore) error {
// TODO: should probably expose better methods on the blockstore for this operation
var blks []blocks.Block
for c := range cids {
b, err := from.Get(ctx, c)
b, err := from.Get(c)
if err != nil {
return err
}
@@ -368,7 +368,7 @@ func copyBlockstore(ctx context.Context, from, to bstore.Blockstore) error {
blks = append(blks, b)
}
if err := to.PutMany(ctx, blks); err != nil {
if err := to.PutMany(blks); err != nil {
return err
}
@@ -463,7 +463,7 @@ func computeMsgMeta(bs cbor.IpldStore, bmsgCids, smsgCids []cid.Cid) (cid.Cid, e
// {hint/usage} This is used from the HELLO protocol, to fetch the greeting
// peer's heaviest tipset if we don't have it.
func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipSetKey) (*store.FullTipSet, error) {
if fts, err := syncer.tryLoadFullTipSet(ctx, tsk); err == nil {
if fts, err := syncer.tryLoadFullTipSet(tsk); err == nil {
return fts, nil
}
@@ -474,15 +474,15 @@ func (syncer *Syncer) FetchTipSet(ctx context.Context, p peer.ID, tsk types.TipS
// tryLoadFullTipSet queries the tipset in the ChainStore, and returns a full
// representation of it containing FullBlocks. If ALL blocks are not found
// locally, it errors entirely with blockstore.ErrNotFound.
func (syncer *Syncer) tryLoadFullTipSet(ctx context.Context, tsk types.TipSetKey) (*store.FullTipSet, error) {
ts, err := syncer.store.LoadTipSet(ctx, tsk)
func (syncer *Syncer) tryLoadFullTipSet(tsk types.TipSetKey) (*store.FullTipSet, error) {
ts, err := syncer.store.LoadTipSet(tsk)
if err != nil {
return nil, err
}
fts := &store.FullTipSet{}
for _, b := range ts.Blocks() {
bmsgs, smsgs, err := syncer.store.MessagesForBlock(ctx, b)
bmsgs, smsgs, err := syncer.store.MessagesForBlock(b)
if err != nil {
return nil, err
}
@@ -583,7 +583,7 @@ func (syncer *Syncer) ValidateTipSet(ctx context.Context, fts *store.FullTipSet,
return xerrors.Errorf("validating block %s: %w", b.Cid(), err)
}
if err := syncer.sm.ChainStore().AddToTipSetTracker(ctx, b.Header); err != nil {
if err := syncer.sm.ChainStore().AddToTipSetTracker(b.Header); err != nil {
return xerrors.Errorf("failed to add validated header to tipset tracker: %w", err)
}
return nil
@@ -755,7 +755,7 @@ loop:
}
// If, for some reason, we have a suffix of the chain locally, handle that here
ts, err := syncer.store.LoadTipSet(ctx, at)
ts, err := syncer.store.LoadTipSet(at)
if err == nil {
acceptedBlocks = append(acceptedBlocks, at.Cids()...)
@@ -838,7 +838,7 @@ loop:
return blockSet, nil
}
knownParent, err := syncer.store.LoadTipSet(ctx, known.Parents())
knownParent, err := syncer.store.LoadTipSet(known.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load next local tipset: %w", err)
}
@@ -892,7 +892,7 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
return nil, err
}
nts, err := syncer.store.LoadTipSet(ctx, known.Parents())
nts, err := syncer.store.LoadTipSet(known.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load next local tipset: %w", err)
}
@@ -928,7 +928,7 @@ func (syncer *Syncer) syncFork(ctx context.Context, incoming *types.TipSet, know
return nil, ErrForkCheckpoint
}
nts, err = syncer.store.LoadTipSet(ctx, nts.Parents())
nts, err = syncer.store.LoadTipSet(nts.Parents())
if err != nil {
return nil, xerrors.Errorf("loading next local tipset: %w", err)
}
@@ -965,7 +965,7 @@ func (syncer *Syncer) iterFullTipsets(ctx context.Context, headers []*types.TipS
span.AddAttributes(trace.Int64Attribute("num_headers", int64(len(headers))))
for i := len(headers) - 1; i >= 0; {
fts, err := syncer.store.TryFillTipSet(ctx, headers[i])
fts, err := syncer.store.TryFillTipSet(headers[i])
if err != nil {
return err
}
@@ -1138,7 +1138,7 @@ func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.Co
for _, m := range bst.Bls {
//log.Infof("putting BLS message: %s", m.Cid())
if _, err := store.PutMessage(ctx, bs, m); err != nil {
if _, err := store.PutMessage(bs, m); err != nil {
log.Errorf("failed to persist messages: %+v", err)
return xerrors.Errorf("BLS message processing failed: %w", err)
}
@@ -1148,7 +1148,7 @@ func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.Co
return xerrors.Errorf("unknown signature type on message %s: %q", m.Cid(), m.Signature.Type)
}
//log.Infof("putting secp256k1 message: %s", m.Cid())
if _, err := store.PutMessage(ctx, bs, m); err != nil {
if _, err := store.PutMessage(bs, m); err != nil {
log.Errorf("failed to persist messages: %+v", err)
return xerrors.Errorf("secp256k1 message processing failed: %w", err)
}
@@ -1201,7 +1201,7 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet, hts *t
for _, ts := range headers {
toPersist = append(toPersist, ts.Blocks()...)
}
if err := syncer.store.PersistBlockHeaders(ctx, toPersist...); err != nil {
if err := syncer.store.PersistBlockHeaders(toPersist...); err != nil {
err = xerrors.Errorf("failed to persist synced blocks to the chainstore: %w", err)
ss.Error(err)
return err
@@ -1245,7 +1245,7 @@ func (syncer *Syncer) CheckBadBlockCache(blk cid.Cid) (string, bool) {
return bbr.String(), ok
}
func (syncer *Syncer) getLatestBeaconEntry(ctx context.Context, ts *types.TipSet) (*types.BeaconEntry, error) {
func (syncer *Syncer) getLatestBeaconEntry(_ context.Context, ts *types.TipSet) (*types.BeaconEntry, error) {
cur := ts
for i := 0; i < 20; i++ {
cbe := cur.Blocks()[0].BeaconEntries
@@ -1257,7 +1257,7 @@ func (syncer *Syncer) getLatestBeaconEntry(ctx context.Context, ts *types.TipSet
return nil, xerrors.Errorf("made it back to genesis block without finding beacon entry")
}
next, err := syncer.store.LoadTipSet(ctx, cur.Parents())
next, err := syncer.store.LoadTipSet(cur.Parents())
if err != nil {
return nil, xerrors.Errorf("failed to load parents when searching back for latest beacon entry: %w", err)
}
+6 -50
View File
@@ -1,4 +1,3 @@
//stm: #unit
package chain_test
import (
@@ -104,7 +103,7 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil {
ctx: ctx,
cancel: cancel,
mn: mocknet.New(),
mn: mocknet.New(ctx),
g: g,
us: filcns.DefaultUpgradeSchedule(),
}
@@ -158,7 +157,7 @@ func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syn
ctx: ctx,
cancel: cancel,
mn: mocknet.New(),
mn: mocknet.New(ctx),
g: g,
us: sched,
}
@@ -207,21 +206,20 @@ func (tu *syncTestUtil) pushFtsAndWait(to int, fts *store.FullTipSet, wait bool)
}
func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bool) {
ctx := context.TODO()
for _, fb := range fts.Blocks {
var b types.BlockMsg
// -1 to match block.Height
b.Header = fb.Header
for _, msg := range fb.SecpkMessages {
c, err := tu.nds[to].(*impl.FullNodeAPI).ChainAPI.Chain.PutMessage(ctx, msg)
c, err := tu.nds[to].(*impl.FullNodeAPI).ChainAPI.Chain.PutMessage(msg)
require.NoError(tu.t, err)
b.SecpkMessages = append(b.SecpkMessages, c)
}
for _, msg := range fb.BlsMessages {
c, err := tu.nds[to].(*impl.FullNodeAPI).ChainAPI.Chain.PutMessage(ctx, msg)
c, err := tu.nds[to].(*impl.FullNodeAPI).ChainAPI.Chain.PutMessage(msg)
require.NoError(tu.t, err)
b.BlsMessages = append(b.BlsMessages, c)
@@ -301,7 +299,7 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
lastTs := blocks[len(blocks)-1].Blocks
for _, lastB := range lastTs {
cs := out.(*impl.FullNodeAPI).ChainAPI.Chain
require.NoError(tu.t, cs.AddToTipSetTracker(context.Background(), lastB.Header))
require.NoError(tu.t, cs.AddToTipSetTracker(lastB.Header))
err = cs.AddBlock(tu.ctx, lastB.Header)
require.NoError(tu.t, err)
}
@@ -463,8 +461,6 @@ func (tu *syncTestUtil) waitUntilSyncTarget(to int, target *types.TipSet) {
}
func TestSyncSimple(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 50
tu := prepSyncTest(t, H)
@@ -481,8 +477,6 @@ func TestSyncSimple(t *testing.T) {
}
func TestSyncMining(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 50
tu := prepSyncTest(t, H)
@@ -505,8 +499,6 @@ func TestSyncMining(t *testing.T) {
}
func TestSyncBadTimestamp(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 50
tu := prepSyncTest(t, H)
@@ -561,8 +553,6 @@ func (wpp badWpp) ComputeProof(context.Context, []proof7.ExtendedSectorInfo, abi
}
func TestSyncBadWinningPoSt(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 15
tu := prepSyncTest(t, H)
@@ -592,9 +582,6 @@ func (tu *syncTestUtil) loadChainToNode(to int) {
}
func TestSyncFork(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -662,9 +649,6 @@ func TestSyncFork(t *testing.T) {
// A and B both include _different_ messages from sender X with nonce N (where N is the correct nonce for X).
// We can confirm that the state can be correctly computed, and that `MessagesForTipset` behaves as expected.
func TestDuplicateNonce(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -719,7 +703,6 @@ func TestDuplicateNonce(t *testing.T) {
var includedMsg cid.Cid
var skippedMsg cid.Cid
//stm: @CHAIN_STATE_SEARCH_MSG_001
r0, err0 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[0][0].Cid(), api.LookbackNoLimit, true)
r1, err1 := tu.nds[0].StateSearchMsg(context.TODO(), ts2.TipSet().Key(), msgs[1][0].Cid(), api.LookbackNoLimit, true)
@@ -752,7 +735,7 @@ func TestDuplicateNonce(t *testing.T) {
t.Fatal("included message should be in exec trace")
}
mft, err := tu.g.ChainStore().MessagesForTipset(context.TODO(), ts1.TipSet())
mft, err := tu.g.ChainStore().MessagesForTipset(ts1.TipSet())
require.NoError(t, err)
require.True(t, len(mft) == 1, "only expecting one message for this tipset")
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
@@ -761,9 +744,6 @@ func TestDuplicateNonce(t *testing.T) {
// This test asserts that a block that includes a message with bad nonce can't be synced. A nonce is "bad" if it can't
// be applied on the parent state.
func TestBadNonce(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -811,9 +791,6 @@ func TestBadNonce(t *testing.T) {
// One of the messages uses the sender's robust address, the other uses the ID address.
// Such a block is invalid and should not sync.
func TestMismatchedNoncesRobustID(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001, @CHAIN_SYNCER_STOP_001
v5h := abi.ChainEpoch(4)
tu := prepSyncTestWithV5Height(t, int(v5h+5), v5h)
@@ -826,7 +803,6 @@ func TestMismatchedNoncesRobustID(t *testing.T) {
require.NoError(t, err)
// Produce a message from the banker
//stm: @CHAIN_STATE_LOOKUP_ID_001
makeMsg := func(id bool) *types.SignedMessage {
sender := tu.g.Banker()
if id {
@@ -869,9 +845,6 @@ func TestMismatchedNoncesRobustID(t *testing.T) {
// One of the messages uses the sender's robust address, the other uses the ID address.
// Such a block is valid and should sync.
func TestMatchedNoncesRobustID(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001, @CHAIN_SYNCER_STOP_001
v5h := abi.ChainEpoch(4)
tu := prepSyncTestWithV5Height(t, int(v5h+5), v5h)
@@ -884,7 +857,6 @@ func TestMatchedNoncesRobustID(t *testing.T) {
require.NoError(t, err)
// Produce a message from the banker with specified nonce
//stm: @CHAIN_STATE_LOOKUP_ID_001
makeMsg := func(n uint64, id bool) *types.SignedMessage {
sender := tu.g.Banker()
if id {
@@ -944,8 +916,6 @@ func runSyncBenchLength(b *testing.B, l int) {
}
func TestSyncInputs(t *testing.T) {
//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_VALIDATE_BLOCK_001,
//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -973,9 +943,6 @@ func TestSyncInputs(t *testing.T) {
}
func TestSyncCheckpointHead(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -995,7 +962,6 @@ func TestSyncCheckpointHead(t *testing.T) {
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0, true)
tu.waitUntilSyncTarget(p1, a.TipSet())
//stm: @CHAIN_SYNCER_CHECKPOINT_001
tu.checkpointTs(p1, a.TipSet().Key())
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
@@ -1015,20 +981,15 @@ func TestSyncCheckpointHead(t *testing.T) {
tu.waitUntilNodeHasTs(p1, b.TipSet().Key())
p1Head := tu.getHead(p1)
require.True(tu.t, p1Head.Equals(a.TipSet()))
//stm: @CHAIN_SYNCER_CHECK_BAD_001
tu.assertBad(p1, b.TipSet())
// Should be able to switch forks.
//stm: @CHAIN_SYNCER_CHECKPOINT_001
tu.checkpointTs(p1, b.TipSet().Key())
p1Head = tu.getHead(p1)
require.True(tu.t, p1Head.Equals(b.TipSet()))
}
func TestSyncCheckpointEarlierThanHead(t *testing.T) {
//stm: @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01, @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_SYNC_001, @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001, @CHAIN_SYNCER_STOP_001
H := 10
tu := prepSyncTest(t, H)
@@ -1048,7 +1009,6 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0, true)
tu.waitUntilSyncTarget(p1, a.TipSet())
//stm: @CHAIN_SYNCER_CHECKPOINT_001
tu.checkpointTs(p1, a1.TipSet().Key())
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
@@ -1068,19 +1028,15 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
tu.waitUntilNodeHasTs(p1, b.TipSet().Key())
p1Head := tu.getHead(p1)
require.True(tu.t, p1Head.Equals(a.TipSet()))
//stm: @CHAIN_SYNCER_CHECK_BAD_001
tu.assertBad(p1, b.TipSet())
// Should be able to switch forks.
//stm: @CHAIN_SYNCER_CHECKPOINT_001
tu.checkpointTs(p1, b.TipSet().Key())
p1Head = tu.getHead(p1)
require.True(tu.t, p1Head.Equals(b.TipSet()))
}
func TestInvalidHeight(t *testing.T) {
//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001, @CHAIN_SYNCER_START_001
//stm: @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
H := 50
tu := prepSyncTest(t, H)
+4 -7
View File
@@ -10,9 +10,8 @@ import (
addr "github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/build"
"github.com/ipfs/go-cid"
)
type GasCharge struct {
@@ -82,9 +81,7 @@ type Pricelist interface {
OnVerifyConsensusFault() GasCharge
}
// Prices are the price lists per starting epoch. Public for testing purposes
// (concretely to allow the test vector runner to rebase prices).
var Prices = map[abi.ChainEpoch]Pricelist{
var prices = map[abi.ChainEpoch]Pricelist{
abi.ChainEpoch(0): &pricelistV0{
computeGasMulti: 1,
storageGasMulti: 1000,
@@ -219,8 +216,8 @@ func PricelistByEpoch(epoch abi.ChainEpoch) Pricelist {
// since we are storing the prices as map or epoch to price
// we need to get the price with the highest epoch that is lower or equal to the `epoch` arg
bestEpoch := abi.ChainEpoch(0)
bestPrice := Prices[bestEpoch]
for e, pl := range Prices {
bestPrice := prices[bestEpoch]
for e, pl := range prices {
// if `e` happened after `bestEpoch` and `e` is earlier or equal to the target `epoch`
if e > bestEpoch && e <= epoch {
bestEpoch = e
+7 -2
View File
@@ -1,6 +1,7 @@
package vm
import (
"context"
"fmt"
"io"
"testing"
@@ -135,7 +136,9 @@ func TestInvokerBasic(t *testing.T) {
{
_, aerr := code[1](&Runtime{
vm: &VM{networkVersion: network.Version0},
vm: &VM{ntwkVersion: func(ctx context.Context, epoch abi.ChainEpoch) network.Version {
return network.Version0
}},
Message: &basicRtMessage{},
}, []byte{99})
if aerrors.IsFatal(aerr) {
@@ -146,7 +149,9 @@ func TestInvokerBasic(t *testing.T) {
{
_, aerr := code[1](&Runtime{
vm: &VM{networkVersion: network.Version7},
vm: &VM{ntwkVersion: func(ctx context.Context, epoch abi.ChainEpoch) network.Version {
return network.Version7
}},
Message: &basicRtMessage{},
}, []byte{99})
if aerrors.IsFatal(aerr) {
+23 -5
View File
@@ -5,7 +5,6 @@ import (
"context"
"encoding/binary"
"fmt"
"os"
gruntime "runtime"
"time"
@@ -57,7 +56,7 @@ func (m *Message) ValueReceived() abi.TokenAmount {
}
// EnableGasTracing, if true, outputs gas tracing in execution traces.
var EnableGasTracing = os.Getenv("LOTUS_VM_ENABLE_GAS_TRACING_VERY_SLOW") == "1"
var EnableGasTracing = false
type Runtime struct {
rt7.Message
@@ -92,7 +91,7 @@ func (rt *Runtime) BaseFee() abi.TokenAmount {
}
func (rt *Runtime) NetworkVersion() network.Version {
return rt.vm.networkVersion
return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch())
}
func (rt *Runtime) TotalFilCircSupply() abi.TokenAmount {
@@ -224,7 +223,16 @@ func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
}
func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy)
var err error
var res []byte
rnv := rt.vm.ntwkVersion(rt.ctx, randEpoch)
if rnv >= network.Version13 {
res, err = rt.vm.rand.GetChainRandomnessV2(rt.ctx, personalization, randEpoch, entropy)
} else {
res, err = rt.vm.rand.GetChainRandomnessV1(rt.ctx, personalization, randEpoch, entropy)
}
if err != nil {
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
@@ -233,7 +241,17 @@ func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparat
}
func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy)
var err error
var res []byte
rnv := rt.vm.ntwkVersion(rt.ctx, randEpoch)
if rnv >= network.Version14 {
res, err = rt.vm.rand.GetBeaconRandomnessV3(rt.ctx, personalization, randEpoch, entropy)
} else if rnv == network.Version13 {
res, err = rt.vm.rand.GetBeaconRandomnessV2(rt.ctx, personalization, randEpoch, entropy)
} else {
res, err = rt.vm.rand.GetBeaconRandomnessV1(rt.ctx, personalization, randEpoch, entropy)
}
if err != nil {
panic(aerrors.Fatalf("could not get beacon randomness: %s", err))
+41 -23
View File
@@ -82,10 +82,10 @@ type gasChargingBlocks struct {
under cbor.IpldBlockstore
}
func (bs *gasChargingBlocks) View(ctx context.Context, c cid.Cid, cb func([]byte) error) error {
func (bs *gasChargingBlocks) View(c cid.Cid, cb func([]byte) error) error {
if v, ok := bs.under.(blockstore.Viewer); ok {
bs.chargeGas(bs.pricelist.OnIpldGet())
return v.View(ctx, c, func(b []byte) error {
return v.View(c, func(b []byte) error {
// we have successfully retrieved the value; charge for it, even if the user-provided function fails.
bs.chargeGas(newGasCharge("OnIpldViewEnd", 0, 0).WithExtra(len(b)))
bs.chargeGas(gasOnActorExec)
@@ -93,16 +93,16 @@ func (bs *gasChargingBlocks) View(ctx context.Context, c cid.Cid, cb func([]byte
})
}
// the underlying blockstore doesn't implement the viewer interface, fall back to normal Get behaviour.
blk, err := bs.Get(ctx, c)
blk, err := bs.Get(c)
if err == nil && blk != nil {
return cb(blk.RawData())
}
return err
}
func (bs *gasChargingBlocks) Get(ctx context.Context, c cid.Cid) (block.Block, error) {
func (bs *gasChargingBlocks) Get(c cid.Cid) (block.Block, error) {
bs.chargeGas(bs.pricelist.OnIpldGet())
blk, err := bs.under.Get(ctx, c)
blk, err := bs.under.Get(c)
if err != nil {
return nil, aerrors.Escalate(err, "failed to get block from blockstore")
}
@@ -112,10 +112,10 @@ func (bs *gasChargingBlocks) Get(ctx context.Context, c cid.Cid) (block.Block, e
return blk, nil
}
func (bs *gasChargingBlocks) Put(ctx context.Context, blk block.Block) error {
func (bs *gasChargingBlocks) Put(blk block.Block) error {
bs.chargeGas(bs.pricelist.OnIpldPut(len(blk.RawData())))
if err := bs.under.Put(ctx, blk); err != nil {
if err := bs.under.Put(blk); err != nil {
return aerrors.Escalate(err, "failed to write data to disk")
}
bs.chargeGas(gasOnActorExec)
@@ -169,7 +169,7 @@ func (vm *VM) makeRuntime(ctx context.Context, msg *types.Message, parent *Runti
}
vmm.From = resF
if vm.networkVersion <= network.Version3 {
if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 {
rt.Message = &vmm
} else {
resT, _ := rt.ResolveAddress(msg.To)
@@ -209,7 +209,7 @@ type VM struct {
areg *ActorRegistry
rand Rand
circSupplyCalc CircSupplyCalculator
networkVersion network.Version
ntwkVersion NtwkVersionGetter
baseFee abi.TokenAmount
lbStateGet LookbackStateGetter
baseCircSupply abi.TokenAmount
@@ -225,7 +225,7 @@ type VMOpts struct {
Actors *ActorRegistry
Syscalls SyscallBuilder
CircSupplyCalc CircSupplyCalculator
NetworkVersion network.Version
NtwkVersion NtwkVersionGetter // TODO: stebalien: In what cases do we actually need this? It seems like even when creating new networks we want to use the 'global'/build-default version getter
BaseFee abi.TokenAmount
LookbackState LookbackStateGetter
}
@@ -251,7 +251,7 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
areg: opts.Actors,
rand: opts.Rand, // TODO: Probably should be a syscall
circSupplyCalc: opts.CircSupplyCalc,
networkVersion: opts.NetworkVersion,
ntwkVersion: opts.NtwkVersion,
Syscalls: opts.Syscalls,
baseFee: opts.BaseFee,
baseCircSupply: baseCirc,
@@ -260,8 +260,11 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
}
type Rand interface {
GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetChainRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetChainRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error)
}
type ApplyRet struct {
@@ -313,7 +316,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
return nil, aerrors.Wrapf(err, "could not create account")
}
toActor = a
if vm.networkVersion <= network.Version3 {
if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version3 {
// Leave the rt.Message as is
} else {
nmsg := Message{
@@ -340,7 +343,7 @@ func (vm *VM) send(ctx context.Context, msg *types.Message, parent *Runtime,
defer rt.chargeGasSafe(newGasCharge("OnMethodInvocationDone", 0, 0))
if types.BigCmp(msg.Value, types.NewInt(0)) != 0 {
if err := vm.transfer(msg.From, msg.To, msg.Value, vm.networkVersion); err != nil {
if err := vm.transfer(msg.From, msg.To, msg.Value, vm.ntwkVersion(ctx, vm.blockHeight)); err != nil {
return nil, aerrors.Wrap(err, "failed to transfer funds")
}
}
@@ -617,7 +620,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
}
func (vm *VM) ShouldBurn(ctx context.Context, st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
if vm.networkVersion <= network.Version12 {
if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version12 {
// Check to see if we should burn funds. We avoid burning on successful
// window post. This won't catch _indirect_ window post calls, but this
// is the best we can get for now.
@@ -707,7 +710,7 @@ func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) err
go func() {
for b := range toFlush {
if err := to.PutMany(ctx, b); err != nil {
if err := to.PutMany(b); err != nil {
close(freeBufs)
errFlushChan <- xerrors.Errorf("batch put in copy: %w", err)
return
@@ -736,7 +739,7 @@ func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) err
return nil
}
if err := copyRec(ctx, from, to, root, batchCp); err != nil {
if err := copyRec(from, to, root, batchCp); err != nil {
return xerrors.Errorf("copyRec: %w", err)
}
@@ -761,13 +764,13 @@ func Copy(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid) err
return nil
}
func copyRec(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid, cp func(block.Block) error) error {
func copyRec(from, to blockstore.Blockstore, root cid.Cid, cp func(block.Block) error) error {
if root.Prefix().MhType == 0 {
// identity cid, skip
return nil
}
blk, err := from.Get(ctx, root)
blk, err := from.Get(root)
if err != nil {
return xerrors.Errorf("get %s failed: %w", root, err)
}
@@ -792,7 +795,7 @@ func copyRec(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid,
}
} else {
// If we have an object, we already have its children, skip the object.
has, err := to.Has(ctx, link)
has, err := to.Has(link)
if err != nil {
lerr = xerrors.Errorf("has: %w", err)
return
@@ -802,7 +805,7 @@ func copyRec(ctx context.Context, from, to blockstore.Blockstore, root cid.Cid,
}
}
if err := copyRec(ctx, from, to, link, cp); err != nil {
if err := copyRec(from, to, link, cp); err != nil {
lerr = err
return
}
@@ -824,6 +827,17 @@ func (vm *VM) StateTree() types.StateTree {
return vm.cstate
}
func (vm *VM) SetBlockHeight(ctx context.Context, h abi.ChainEpoch) error {
vm.blockHeight = h
ncirc, err := vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
if err != nil {
return err
}
vm.baseCircSupply = ncirc
return nil
}
func (vm *VM) Invoke(act *types.Actor, rt *Runtime, method abi.MethodNum, params []byte) ([]byte, aerrors.ActorError) {
ctx, span := trace.StartSpan(rt.ctx, "vm.Invoke")
defer span.End()
@@ -851,9 +865,13 @@ func (vm *VM) SetInvoker(i *ActorRegistry) {
vm.areg = i
}
func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version {
return vm.ntwkVersion(ctx, ce)
}
func (vm *VM) GetCircSupply(ctx context.Context) (abi.TokenAmount, error) {
// Before v15, this was recalculated on each invocation as the state tree was mutated
if vm.networkVersion <= network.Version14 {
if vm.GetNtwkVersion(ctx, vm.blockHeight) <= network.Version14 {
return vm.circSupplyCalc(ctx, vm.blockHeight, vm.cstate)
}
+11 -11
View File
@@ -39,7 +39,7 @@ type LedgerKeyInfo struct {
var _ api.Wallet = (*LedgerWallet)(nil)
func (lw LedgerWallet) WalletSign(ctx context.Context, signer address.Address, toSign []byte, meta api.MsgMeta) (*crypto.Signature, error) {
ki, err := lw.getKeyInfo(ctx, signer)
ki, err := lw.getKeyInfo(signer)
if err != nil {
return nil, err
}
@@ -80,8 +80,8 @@ func (lw LedgerWallet) WalletSign(ctx context.Context, signer address.Address, t
}, nil
}
func (lw LedgerWallet) getKeyInfo(ctx context.Context, addr address.Address) (*LedgerKeyInfo, error) {
kib, err := lw.ds.Get(ctx, keyForAddr(addr))
func (lw LedgerWallet) getKeyInfo(addr address.Address) (*LedgerKeyInfo, error) {
kib, err := lw.ds.Get(keyForAddr(addr))
if err != nil {
return nil, err
}
@@ -95,7 +95,7 @@ func (lw LedgerWallet) getKeyInfo(ctx context.Context, addr address.Address) (*L
}
func (lw LedgerWallet) WalletDelete(ctx context.Context, k address.Address) error {
return lw.ds.Delete(ctx, keyForAddr(k))
return lw.ds.Delete(keyForAddr(k))
}
func (lw LedgerWallet) WalletExport(ctx context.Context, k address.Address) (*types.KeyInfo, error) {
@@ -103,7 +103,7 @@ func (lw LedgerWallet) WalletExport(ctx context.Context, k address.Address) (*ty
}
func (lw LedgerWallet) WalletHas(ctx context.Context, k address.Address) (bool, error) {
_, err := lw.ds.Get(ctx, keyForAddr(k))
_, err := lw.ds.Get(keyForAddr(k))
if err == nil {
return true, nil
}
@@ -118,10 +118,10 @@ func (lw LedgerWallet) WalletImport(ctx context.Context, kinfo *types.KeyInfo) (
if err := json.Unmarshal(kinfo.PrivateKey, &ki); err != nil {
return address.Undef, err
}
return lw.importKey(ctx, ki)
return lw.importKey(ki)
}
func (lw LedgerWallet) importKey(ctx context.Context, ki LedgerKeyInfo) (address.Address, error) {
func (lw LedgerWallet) importKey(ki LedgerKeyInfo) (address.Address, error) {
if ki.Address == address.Undef {
return address.Undef, fmt.Errorf("no address given in imported key info")
}
@@ -133,7 +133,7 @@ func (lw LedgerWallet) importKey(ctx context.Context, ki LedgerKeyInfo) (address
return address.Undef, xerrors.Errorf("marshaling key info: %w", err)
}
if err := lw.ds.Put(ctx, keyForAddr(ki.Address), bb); err != nil {
if err := lw.ds.Put(keyForAddr(ki.Address), bb); err != nil {
return address.Undef, err
}
@@ -141,7 +141,7 @@ func (lw LedgerWallet) importKey(ctx context.Context, ki LedgerKeyInfo) (address
}
func (lw LedgerWallet) WalletList(ctx context.Context) ([]address.Address, error) {
res, err := lw.ds.Query(ctx, query.Query{Prefix: dsLedgerPrefix})
res, err := lw.ds.Query(query.Query{Prefix: dsLedgerPrefix})
if err != nil {
return nil, err
}
@@ -175,7 +175,7 @@ func (lw LedgerWallet) WalletNew(ctx context.Context, t types.KeyType) (address.
t, types.KTSecp256k1Ledger)
}
res, err := lw.ds.Query(ctx, query.Query{Prefix: dsLedgerPrefix})
res, err := lw.ds.Query(query.Query{Prefix: dsLedgerPrefix})
if err != nil {
return address.Undef, err
}
@@ -224,7 +224,7 @@ func (lw LedgerWallet) WalletNew(ctx context.Context, t types.KeyType) (address.
lki.Address = a
lki.Path = path
return lw.importKey(ctx, lki)
return lw.importKey(lki)
}
func (lw *LedgerWallet) Get() api.Wallet {
+1 -1
View File
@@ -66,7 +66,7 @@ func BackupCmd(repoFlag string, rt repo.RepoType, getApi BackupApiFn) *cli.Comma
return xerrors.Errorf("opening backup file %s: %w", fpath, err)
}
if err := bds.Backup(cctx.Context, out); err != nil {
if err := bds.Backup(out); err != nil {
if cerr := out.Close(); cerr != nil {
log.Errorw("error closing backup file while handling backup error", "closeErr", cerr, "backupErr", err)
}

Some files were not shown because too many files have changed in this diff Show More