Merge pull request #11451 from filecoin-project/chore/master-into-sturdy
chore: master into sturdypost
This commit is contained in:
commit
18f6907b9f
132
CHANGELOG.md
132
CHANGELOG.md
@ -1,22 +1,31 @@
|
||||
# Lotus changelog
|
||||
|
||||
# v 1.25.0-rc4 / 2023-11-08
|
||||
# UNRELEASED
|
||||
- chore: Auto remove local chain data when importing chain file or snapshot ([filecoin-project/lotus#11277](https://github.com/filecoin-project/lotus/pull/11277))
|
||||
- feat: metric: export Mpool message count ([filecoin-project/lotus#11361](https://github.com/filecoin-project/lotus/pull/11361))
|
||||
- feat: sealing: load SectorsSummary from sealing SectorStats instead of calling API each time ([filecoin-project/lotus#11353](https://github.com/filecoin-project/lotus/pull/11353))
|
||||
|
||||
This is the fourth release candidate of the upcoming OPTIONAL release Lotus v1.25.0. This optional release also supports the Filecoin network version 21 upgrade, codenamed Watermelon 🍉, in addition to the numerous improvements and enhancements for node operators, ETH RPC-providers and storage providers.
|
||||
## Improvements
|
||||
- fix: Add time slicing to splitstore purging step during compaction to reduce lock congestion [filecoin-project/lotus#11269](https://github.com/filecoin-project/lotus/pull/11269)
|
||||
- feat: Added instructions on how to setup Prometheus/Grafana for monitoring a local Lotus node [filecoin-project/lotus#11276](https://github.com/filecoin-project/lotus/pull/11276)
|
||||
- fix: Exclude reverted events in `eth_getLogs` results [filecoin-project/lotus#11318](https://github.com/filecoin-project/lotus/pull/11318)
|
||||
- fix: The Ethereum API will now use the correct state-tree when resolving "native" addresses into masked ID addresses. Additionally, pending messages from native account types won't be visible in the Ethereum API because there is no "correct" state-tree to pick in this case. However, pending _Ethereum_ transactions and native messages that have landed on-chain will still be visible through the Ethereum API.
|
||||
- feat: Unambiguously translate native messages to Ethereum transactions by:
|
||||
- Detecting native messages that "look" like Ethereum transactions (creating smart contracts, invoking a smart contract, etc.), and decoding them as such.
|
||||
- Otherwise, ABI-encoding the inputs as if they were calls to a `handle_filecoin_method` Solidity method.
|
||||
|
||||
## Calibration Testnet WatermelonFix Upgrade Recovery
|
||||
# v 1.25.0 / 2023-11-22
|
||||
|
||||
The Calibration Testnet halted 60 epochs after the WatermelonFix upgrade, we believe the cause is the new fixed miner actor CID isn't registered in the system actor state. Fortunately, this could be fixedby winding back the time prior to the upgrade, and reperform the migration with new miner actor CID registered in the system actor state. We would like to ask all calibrationnet node operators to run the following:
|
||||
- Upgrade your nodes and miners to v1.25.0-rc4
|
||||
- Shut down your daemon and restart it (miners too if applicable)
|
||||
This is a highly recommended feature release of Lotus. This optional release supports the Filecoin network version 21 upgrade, codenamed Watermelon 🍉, in addition to the numerous improvements and enhancements for node operators, ETH RPC-providers and storage providers.
|
||||
|
||||
Please reach out to us in #fil-net-calibration-discuss if you have any questions!
|
||||
**The Filecoin network upgrade v21, codenamed Watermelon 🍉, is at epoch 3469380 - 2023-12-12T13:30:00Z**
|
||||
|
||||
Make sure to check out the release log for [Lotus v1.24.0-rc5](https://github.com/filecoin-project/lotus/releases/tag/v1.24.0-rc5) to see the FIPs delivered in the network version 21 upgrade, v12 Builtin Actor Bundles, features and improvements.
|
||||
The full list of [protocol improvements delivered in the network upgrade can be found here](https://github.com/filecoin-project/core-devs/blob/master/Network%20Upgrades/v21.md).
|
||||
|
||||
## ☢️ Upgrade Warnings ☢️
|
||||
|
||||
- Please remove and clone a new Lotus repo (`git clone https://github.com/filecoin-project/lotus.git`) when upgrading to this version.
|
||||
- Read through the [changelog of the mandatory v1.24.0 release](https://github.com/filecoin-project/lotus/releases/tag/v1.24.0). Especially the `Migration` and `v12 Builtin Actor Bundle` sections.
|
||||
- Please remove and clone a new Lotus repo (`git clone https://github.com/filecoin-project/lotus.git`) when upgrading to this release.
|
||||
- This feature release requires a minimum Go version of v1.20.7 or higher to successfully build Lotus. Go version 1.21.x is not supported yet.
|
||||
- EthRPC providers, please check out the [new tracing API to Lotus RPC](https://github.com/filecoin-project/lotus/pull/11100)
|
||||
|
||||
@ -97,6 +106,8 @@ Lotus-workers can now be built to leverage the SupraSeal C2 sealing optimization
|
||||
- fix: build: use tagged releases ([filecoin-project/lotus#11194](https://github.com/filecoin-project/lotus/pull/11194))
|
||||
- chore: test-vectors: update ([filecoin-project/lotus#11196](https://github.com/filecoin-project/lotus/pull/11196))
|
||||
- chore: backport #11365 to release/v1.25.0 ([filecoin-project/lotus#11369](https://github.com/filecoin-project/lotus/pull/11369))
|
||||
- chore: deps: update to go-state-types v0.12.8 ([filecoin-project/lotus#11339](https://github.com/filecoin-project/lotus/pull/11437))
|
||||
- chore: deps: update to final actors ([filecoin-project/lotus#11330](https://github.com/filecoin-project/lotus/pull/11440))
|
||||
- github.com/filecoin-project/go-amt-ipld/v4 (v4.0.0 -> v4.2.0)
|
||||
- github.com/filecoin-project/test-vectors/schema (v0.0.5 -> v0.0.7)
|
||||
|
||||
@ -121,79 +132,106 @@ Lotus-workers can now be built to leverage the SupraSeal C2 sealing optimization
|
||||
- chore: backport #11294 into `release/v1.23.4` ([filecoin-project/lotus#11295](https://github.com/filecoin-project/lotus/pull/11295))
|
||||
- chore: release: V1.25 rebase ([filecoin-project/lotus#11342](https://github.com/filecoin-project/lotus/pull/11342))
|
||||
- backport: tests: add SynthPorep layers to cachefiles ([filecoin-project/lotus#11344](https://github.com/filecoin-project/lotus/pull/11344))
|
||||
- chore: backport #11408 to release/v1.25.0 ([filecoin-project/lotus#11414](https://github.com/filecoin-project/lotus/pull/11414))
|
||||
- chore: backport calibnet lightweight patch ([filecoin-project/lotus#11422](https://github.com/filecoin-project/lotus/pull/11422))
|
||||
- chore: update bootstrap nodes ([filecoin-project/lotus#11288](https://github.com/filecoin-project/lotus/pull/11288))
|
||||
- chore: add bootstrap node on calibration ([filecoin-project/lotus#11175](https://github.com/filecoin-project/lotus/pull/11175))
|
||||
|
||||
# v1.24.0-rc2 / 2023-10-17
|
||||
# 1.24.0 / 2023-11-22
|
||||
|
||||
This is the second release candidate of the upcoming **MANDATORY Lotus v1.24.0** release, which will deliver the Filecoin network version 21, codenamed Watermelon 🍉.
|
||||
This is the stable release for the upcoming **MANDATORY** Filecoin network upgrade v21, codenamed Watermelon 🍉, at **epoch 3469380 - 2023-12-12T13:30:00Z**.
|
||||
|
||||
**This release candidate does NOT set an upgrade epoch for mainnet, but sets the calibration network to upgrade at epoch 1013134, which is 2023-10-19T13:00:00Z.** This second release candidate updates go-state-types to v0.12.5, adding a proofs mapping that was missing v0.12.5. Lotus v1.24.0-RC1 remains valid for the network upgrade in the Calibration network. However, storage providers intending to conduct Synthetic PoRep testing are advised to use RC2.
|
||||
|
||||
The Filecoin network version 21 delivers the following FIPs:
|
||||
|
||||
- [FIP0052: Increase Max Sector Commitment to 3.5 years](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0052.md)
|
||||
- [FIP0059: Synthetic PoRep](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0059.md)
|
||||
- [FIP0070: Allow SPs to move partitions between deadlines](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0070.md)
|
||||
- [FIP0071: Deterministic State Access (IPLD Reachability)](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0071.md)
|
||||
- [FIP0072: Improved event syscall API](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0072.md)
|
||||
- [FIP0073: Remove beneficiary from the self_destruct syscall](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0073.md)
|
||||
- [FIP0075: Improvements to FVM randomness syscalls](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0075.md)
|
||||
|
||||
|
||||
Full list of the other protocol improvements we are delivering can be found [here](https://github.com/filecoin-project/core-devs/blob/master/Network%20Upgrades/v21.md).
|
||||
|
||||
## ☢️ Upgrade Warnings ☢️
|
||||
|
||||
This feature release requires a minimum Go version of v1.20.7 or higher to successfully build Lotus. Go version 1.21.x is not supported yet.
|
||||
|
||||
## v12 Builtin Actor Bundles
|
||||
|
||||
The actor bundles for the calibration network can be checked as follows:
|
||||
[Builtin actor v12.0.0](https://github.com/filecoin-project/builtin-actors/releases/tag/v12.0.0) is used for supporting this upgrade.
|
||||
Make sure that your lotus actor bundle matches the v12 actors manifest by running the following cli after upgrading:
|
||||
|
||||
```
|
||||
lotus state actor-cids --network-version=21
|
||||
./lotus state actor-cids --network-version 21
|
||||
Network Version: 21
|
||||
Actor Version: 12
|
||||
Manifest CID: bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs
|
||||
Manifest CID: bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio
|
||||
|
||||
Actor CID
|
||||
paymentchannel bafk2bzacebaxhk4itfiuvbftg7kz5zxugqnvdgerobitjq4vl6q4orcwk6wqg
|
||||
datacap bafk2bzacebpiwb2ml4qbnnaayxumtk43ryhc63exdgnhivy3hwgmzemawsmpq
|
||||
paymentchannel bafk2bzacectv4cm47bnhga5febf3lo3fq47g72kmmp2xd5s6tcxz7hiqdywa4
|
||||
storagemarket bafk2bzacedylkg5am446lcuih4voyzdn4yjeqfsxfzh5b6mcuhx4mok5ph5c4
|
||||
storagepower bafk2bzacecsij5tpfzjpfuckxvccv2p3bdqjklkrfyyoei6lx5dyj5j4fvjm6
|
||||
cron bafk2bzacechxjkfe2cehx4s7skj3wzfpzf7zolds64khrrrs66bhazsemktls
|
||||
eam bafk2bzaceb3elj4hfbbjp7g5bptc7su7mptszl4nlqfedilxvstjo5ungm6oe
|
||||
ethaccount bafk2bzaceb4gkau2vgsijcxpfuq33bd7w3efr2rrhxrwiacjmns2ntdiamswq
|
||||
reward bafk2bzacealqnxn5lwzwexd6reav4dppypquklx2ujlnvaxiqk2tzstyvkp5u
|
||||
verifiedregistry bafk2bzacedudgflxc75c77c6zkmfyq4u2xuk7k6xw6dfdccarjrvxx453b77q
|
||||
evm bafk2bzacecmnyfiwb52tkbwmm2dsd7ysi3nvuxl3lmspy7pl26wxj4zj7w4wi
|
||||
placeholder bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro
|
||||
ethaccount bafk2bzaceajmc3y3sedsqymfla3dzzqzmbu5kmr2iskm26ga2u34ll5fpztfw
|
||||
evm bafk2bzaced4sozr7m6rzcgpobzeiupghthfw6afumysu3oz6bxxirv74uo3vw
|
||||
system bafk2bzacecioupndtcnyw6iq2hbrxag3aufvczlv5nobnfbkbywqzcyfaa376
|
||||
init bafk2bzaceaewh7b6zl2egclm7fqzx2lsqr57i75lb6cj43ndoa4mal3k5ld3m
|
||||
multisig bafk2bzacednkwcpw5yzxjceoaliajgupzj6iqxe7ks2ll3unspbprbo5f2now
|
||||
eam bafk2bzacecb6cnwftvavpph4p34zs4psuy5xvbrhf7vszkva4npw6mw3c42xe
|
||||
reward bafk2bzacedra77pcglf7vdca2itcaa4vd6xrxynxmgfgdjdxqxfwqyhtoxehy
|
||||
storagemarket bafk2bzacea7g46y7xxu2zjq2h75x6mmx3utz2uxnlvnwi6tzpsvulna3bmiva
|
||||
storageminer bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq
|
||||
storagepower bafk2bzacedd3ka44k7d46ckbinjhv3diyuu2epgbyvhqqyjkc64qlrg3wlgzi
|
||||
verifiedregistry bafk2bzaceavldupmf7bimeeacs67z5xdfdlfca6p7sn6bev3mt5ggepfqvhqo
|
||||
account bafk2bzacechwwxdqvggkdylm37zldjsra2ivkdzwp7fee56bzxbzs544wv6u6
|
||||
cron bafk2bzacec4gdxxkqwxqqodsv6ug5dmdbqdfqwyqfek3yhxc2wweh5psxaeq6
|
||||
datacap bafk2bzacecq5ppfskxgv3iea3jarsix6jdduuhwsn4fbvngtbmzelzmlygorm
|
||||
storageminer bafk2bzacedo75pabe4i2l3hvhtsjmijrcytd2y76xwe573uku25fi7sugqld6
|
||||
system bafk2bzacebfqrja2hip7esf4eafxjmu6xcogoqu5xxtgdg7xa5szgvvdguchu
|
||||
account bafk2bzaceboftg75mdiba7xbo2i3uvgtca4brhnr3u5ptihonixgpnrvhpxoa
|
||||
init bafk2bzacebllyegx5r6lggf6ymyetbp7amacwpuxakhtjvjtvoy2bfkzk3vms
|
||||
```
|
||||
|
||||
## Migration
|
||||
|
||||
We are expecting a heavier than normal state migration for this upgrade due to the amount of state changes introduced for miner sector info. (This is a similar migration as the Shark upgrade, however, we have introduced a couple of migration performance optimizations since then for a smoother upgrade experience.)
|
||||
|
||||
All node operators, including storage providers, should be aware that ONE pre-migration is being scheduled 180 epochs before the upgrade, around 2023-12-12T12:00:00Z. It will take around 20-30 minutes for the pre-migration and less than 30 seconds for the final migration, depending on the amount of historical state in the node blockstore and the hardware specs the node is running on. During this time, expect slower block validation times, increased CPU and memory usage, and longer delays for API queries (during our testing, it topped out about 205 RAM(htop) on a 1TiB box).
|
||||
|
||||
We recommend node operators (who haven't enabled splitstore `discard` mode) that do not care about historical chain states, to prune the chain blockstore by syncing from a snapshot 1-2 days before the upgrade.
|
||||
|
||||
Note to full archival node operators: you may expect it takes some time for the node to complete the final migration, during this period your node will fall out of sync and your chain service may have some disruption. However, you can expect the node to catch up soon after the migration completes. You can test out the migration by running the following on your node in offline mode:
|
||||
|
||||
1. `lotus chain head | head -n1`
|
||||
2. Stop Lotus daemon
|
||||
3. `./lotus-shed migrate-state --repo=[path-to-your-lotus-repo] 21 [output-of-step-1]`
|
||||
|
||||
You can check out the [tutorial for benchmarking the network migration here.](https://lotus.filecoin.io/kb/test-migration/)
|
||||
|
||||
|
||||
## BREAKING CHANGE
|
||||
|
||||
There is a new protocol limit on how many partition could be submited in one PoSt - if you have any customized tooling for batching PoSts, please update accordingly.
|
||||
- feat: limit PoSted partitions to 3 ([filecoin-project/lotus#11327](https://github.com/filecoin-project/lotus/pull/11327))
|
||||
|
||||
## New features
|
||||
- Implement and support [FIP0052: Increase Max Sector Commitment to 3.5 years](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0052.md)
|
||||
- fix: docs: Update SectorLifetime to be in line with FIP-0052 ([filecoin-project/lotus#11314](https://github.com/filecoin-project/lotus/pull/11314))
|
||||
- Implement and support [FIP0059: Synthetic PoRep](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0059.md) - Check out the [Lotus documentation for Synthetic PoRep](https://lotus.filecoin.io/storage-providers/advanced-configurations/sealing/#synthetic-porep).
|
||||
- feat: implement Synthetic PoRep ([filecoin-project/lotus#11258](https://github.com/filecoin-project/lotus/pull/11258))
|
||||
- chore: config: Update todo in UseSyntheticPoRep ([filecoin-project/lotus#11297](https://github.com/filecoin-project/lotus/pull/11297))
|
||||
- Implement and support [FIP0070: Allow SPs to move partitions between deadlines](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0070.md) - Check out the [Lotus documentation for Moving Partitions](https://lotus.filecoin.io/storage-providers/operate/daily-chores/#move-partitions)
|
||||
- Feat: Lotus cli: actor: Support move partition command to move partitions' deadline ([filecoin-project/lotus#11301](https://github.com/filecoin-project/lotus/pull/11301))
|
||||
- feat: limit PoSted partitions to 3 ([filecoin-project/lotus#11327](https://github.com/filecoin-project/lotus/pull/11327))
|
||||
|
||||
## Improvements
|
||||
- Backport: feat: sealing: Switch to calling PreCommitSectorBatch2 ([filecoin-project/lotus#11215](https://github.com/filecoin-project/lotus/pull/11215))
|
||||
- updated the boostrap nodes
|
||||
|
||||
## Dependencies
|
||||
- github.com/filecoin-project/go-amt-ipld/v4 (v4.0.0 -> v4.2.0)
|
||||
- chore: deps: update bulitin-actors, FVM, and go-state-types ([filecoin-project/lotus#11291](https://github.com/filecoin-project/lotus/pull/11291))
|
||||
- chore: deps: update FFI, FVM, and actors ([filecoin-project/lotus#11310](https://github.com/filecoin-project/lotus/pull/11310))
|
||||
- chore: deps: update to latest actors and FFI ([filecoin-project/lotus#11330](https://github.com/filecoin-project/lotus/pull/11330))
|
||||
- chore: deps: update to go-state-types v0.12.5 ([filecoin-project/lotus#11339](https://github.com/filecoin-project/lotus/pull/11339))
|
||||
- chore: deps: update to final actors ([filecoin-project/lotus#11330](https://github.com/filecoin-project/lotus/pull/11440))
|
||||
- chore: deps: update to go-state-types v0.12.8 ([filecoin-project/lotus#11339](https://github.com/filecoin-project/lotus/pull/11437))
|
||||
- chore: deps: update libp2p to v0.30.0 #11434
|
||||
|
||||
|
||||
## Snapshots
|
||||
|
||||
The [Forest team](https://filecoinproject.slack.com/archives/C029LPZ5N73) at Chainsafe has launched a brand new lightweight snapshot service that is backed up by forest nodes! This is a great alternative service along with the fil-infra one, and it is compatible with lotus! We recommend lotus users to check it out [here](https://docs.filecoin.io/networks/mainnet#resources)!
|
||||
|
||||
## Others
|
||||
- chore: nv-skeleton for feat/nv21-branch ([filecoin-project/lotus#11176](https://github.com/filecoin-project/lotus/pull/11176))
|
||||
- chore: chain/actors: Use type proxies instead of versioned GST imports ([filecoin-project/lotus#11216](https://github.com/filecoin-project/lotus/pull/11216))
|
||||
- chore: butterfly: Add preliminary nv21 assets ([filecoin-project/lotus#11293](https://github.com/filecoin-project/lotus/pull/11293))
|
||||
- chore: butterfly: Update Butterfly Assets ([filecoin-project/lotus#11312](https://github.com/filecoin-project/lotus/pull/11312))
|
||||
- chore: release: Set calibration upgrade height ([filecoin-project/lotus#11331](https://github.com/filecoin-project/lotus/pull/11331))
|
||||
- chore: build: bump version to 1.24.0-rc1 ([filecoin-project/lotus#11332](https://github.com/filecoin-project/lotus/pull/11332))
|
||||
|
||||
|
||||
# v1.23.3 / 2023-08-01
|
||||
@ -221,7 +259,7 @@ This feature release requires a **minimum Go version of v1.19.12 or higher to su
|
||||
- feat: sealing: flag to run data_cid untied from addpiece ([filecoin-project/lotus#10797](https://github.com/filecoin-project/lotus/pull/10797))
|
||||
- feat: Lotus Gateway: add MpoolPending, ChainGetBlock and MinerGetBaseInfo ([filecoin-project/lotus#10929](https://github.com/filecoin-project/lotus/pull/10929))
|
||||
|
||||
## Improvements
|
||||
## Improvements && Bug Fixes
|
||||
- chore: update ffi & fvm ([filecoin-project/lotus#11040](https://github.com/filecoin-project/lotus/pull/11040))
|
||||
- feat: Make sure we don't store duplidate actor events caused to reorgs in events.db ([filecoin-project/lotus#11015](https://github.com/filecoin-project/lotus/pull/11015))
|
||||
- sealing: Use only non-assigned deals when selecting snap sectors ([filecoin-project/lotus#11002](https://github.com/filecoin-project/lotus/pull/11002))
|
||||
@ -299,6 +337,10 @@ This feature release requires a **minimum Go version of v1.19.12 or higher to su
|
||||
- fix: cli: Change arg wording in change-beneficiary cmd ([filecoin-project/lotus#10823](https://github.com/filecoin-project/lotus/pull/10823))
|
||||
- refactor: streamline error handling in CheckPendingMessages (#10818) ([filecoin-project/lotus#10818](https://github.com/filecoin-project/lotus/pull/10818))
|
||||
- feat: Add tmp indices to events table while performing migration to V2
|
||||
- fix: sync: iterate over returned messages directly #11373
|
||||
- fix: api: compute the effective gas cost with the correct base-fee #11357
|
||||
- fix: check invariants: v12 check #11371
|
||||
- fix: api: compute gasUsedRatio based on max gas in the tipset #11354
|
||||
|
||||
# v1.23.2 / 2023-06-28
|
||||
|
||||
|
Binary file not shown.
@ -2,3 +2,4 @@
|
||||
/dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWDTayrBojBn9jWNNUih4nNQQBGJD7Zo3gQCKgBkUsS6dp
|
||||
/dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWNRxTHUn8bf7jz1KEUPMc2dMgGfa4f8ZJTsquVSn3vHCG
|
||||
/dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWFWUqE9jgXvcKHWieYs9nhyp6NF4ftwLGAHm4sCv73jjK
|
||||
/dns4/calibration.node.glif.io/tcp/1237/p2p/12D3KooWQPYouEAsUQKzvFUA9sQ8tz4rfpqtTzh2eL6USd9bwg7x
|
||||
|
@ -8,7 +8,5 @@
|
||||
/dns4/bootstrap-0.starpool.in/tcp/12757/p2p/12D3KooWGHpBMeZbestVEWkfdnC9u7p6uFHXL1n7m1ZBqsEmiUzz
|
||||
/dns4/bootstrap-1.starpool.in/tcp/12757/p2p/12D3KooWQZrGH1PxSNZPum99M1zNvjNFM33d1AAu5DcvdHptuU7u
|
||||
/dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
|
||||
/dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
|
||||
/dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
|
||||
/dns4/bootstarp-0.1475.io/tcp/61256/p2p/12D3KooWRzCVDwHUkgdK7eRgnoXbjDAELhxPErjHzbRLguSV1aRt
|
||||
/dns4/bootstrap-venus.mainnet.filincubator.com/tcp/8888/p2p/QmQu8C6deXwKvJP2D8B6QGyhngc3ZiDnFzEHBDx8yeBXST
|
||||
|
@ -44,9 +44,10 @@ func init() {
|
||||
}
|
||||
|
||||
// The following code cid existed temporarily on the calibnet testnet, as a "buggy" storage miner actor implementation.
|
||||
// We include it in our builtin bundle, but intentionally omit from metadata.
|
||||
// We include them in our builtin bundle, but intentionally omit from metadata.
|
||||
if NetworkBundle == "calibrationnet" {
|
||||
actors.AddActorMeta("storageminer", cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq"), actorstypes.Version12)
|
||||
actors.AddActorMeta("storageminer", cid.MustParse("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie"), actorstypes.Version12)
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,9 +191,10 @@ func readEmbeddedBuiltinActorsMetadata(bundle string) ([]*BuiltinActorsMetadata,
|
||||
return nil, xerrors.Errorf("error loading builtin actors bundle: %w", err)
|
||||
}
|
||||
|
||||
// The following manifest cid existed temporarily on the calibnet testnet
|
||||
// We include it in our builtin bundle, but intentionally omit from metadata
|
||||
if root == cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs") {
|
||||
// The following manifest cids existed temporarily on the calibnet testnet
|
||||
// We include them in our builtin bundle, but intentionally omit from metadata
|
||||
if root == cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs") ||
|
||||
root == cid.MustParse("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru") {
|
||||
continue
|
||||
}
|
||||
bundles = append(bundles, &BuiltinActorsMetadata{
|
||||
|
@ -97,8 +97,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "butterflynet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceabeegs5mhrxwqodyt7u2ulxr2jg6eh5g3545ganqzkncnxzserue"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacebp7anjdtg2sohyt6lromx4xs7nujtwdfcsffnptphaayabx7ysxs"),
|
||||
"cron": MustParseCid("bafk2bzacecu2y3awtemmglpkroiglulc2fj3gpdn6eazdqr6avcautiaighrg"),
|
||||
@ -112,7 +112,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacedebvitdsztwebi44t5es4ls3p3hor252igzawr3s6uznmbvzh2ou"),
|
||||
"storagemarket": MustParseCid("bafk2bzaceb2tdeqtt2eqpzeb3gezuchb7g7uzbd52bgvcdt6bg3ckq7oisb74"),
|
||||
"storageminer": MustParseCid("bafk2bzacea2jzzulmz6ktj6vndjheybz2io3vznnhsb32zberpaqeo7s7xa56"),
|
||||
"storageminer": MustParseCid("bafk2bzaceb62clldtod2jimnri5k2koxttf6vqtlsvkjhnwduzs7sgsoakglw"),
|
||||
"storagepower": MustParseCid("bafk2bzacedxvlj5xmhytdjrjqyonz37duvxb2ioyzk75c27yypkqalxuh3xh6"),
|
||||
"system": MustParseCid("bafk2bzacec3vwj2chzaram3iqupkbfiein5h2l5qiltlrngbju2vg5umelclm"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacedv2irkql7nil3w5v3ohqq3e54w62pxeoppjmaktzokolaaoh5ksu"),
|
||||
@ -203,8 +203,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "calibrationnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacechwwxdqvggkdylm37zldjsra2ivkdzwp7fee56bzxbzs544wv6u6"),
|
||||
"cron": MustParseCid("bafk2bzacec4gdxxkqwxqqodsv6ug5dmdbqdfqwyqfek3yhxc2wweh5psxaeq6"),
|
||||
@ -218,7 +218,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacedra77pcglf7vdca2itcaa4vd6xrxynxmgfgdjdxqxfwqyhtoxehy"),
|
||||
"storagemarket": MustParseCid("bafk2bzacea7g46y7xxu2zjq2h75x6mmx3utz2uxnlvnwi6tzpsvulna3bmiva"),
|
||||
"storageminer": MustParseCid("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie"),
|
||||
"storageminer": MustParseCid("bafk2bzaceb7qzqsi5uyxe4o5iuasi47l2hnznvmqr2eu4pl3qscvarjqlnuxo"),
|
||||
"storagepower": MustParseCid("bafk2bzacedd3ka44k7d46ckbinjhv3diyuu2epgbyvhqqyjkc64qlrg3wlgzi"),
|
||||
"system": MustParseCid("bafk2bzacecioupndtcnyw6iq2hbrxag3aufvczlv5nobnfbkbywqzcyfaa376"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceavldupmf7bimeeacs67z5xdfdlfca6p7sn6bev3mt5ggepfqvhqo"),
|
||||
@ -318,8 +318,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "caterpillarnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacechvmc3iy6qrsbb6xwjhjibqpznqnkajowjsdmrq42ie5hysqemqa"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzacebxiub6qsy67asvl5cx33x5vjbuqinalmf3xtnbmokxmmklzdkvei"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacecereuhejfvodut5357cai4lmhsyr7uenhcxvmw6jpmhe6auuly32"),
|
||||
"cron": MustParseCid("bafk2bzacebo2whgy6jla4jsf5j4ovlqm2e4eepedlpw5wadas33yxmunis4b4"),
|
||||
@ -333,7 +333,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceb2x5zgkrho373l3ippp6krs7brugssg6hj2tib22xmqjzdm2o25a"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced5j6drzmsebpxbf2dtptrc5tyidlbftdljqxavxqb57s2qpbvdek"),
|
||||
"storageminer": MustParseCid("bafk2bzacec7al5izu3ynnb7wg6fxxck3hebtkvlgynufjwcio57jd3n4ke2ue"),
|
||||
"storageminer": MustParseCid("bafk2bzaceckgusfenkczxolfczvnygnuhxbou5to2skwwngbkihla7hgdv4yy"),
|
||||
"storagepower": MustParseCid("bafk2bzaceagp6ilkltsltwii66nz6a4zen4qtfk7rdkvdv3gzq7fbv4ivox3u"),
|
||||
"system": MustParseCid("bafk2bzacedye5j5uxox7knb6zlnhseaadztyav76mjbyk5qslhhbpiy5cdtt2"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacecduww5pirr7dvaijjijw4gf6ygf7vipgxh4scvv6vseo46gueb46"),
|
||||
@ -424,8 +424,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "devnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceau5i7eanhvss22z5ixmyrihilfniqn22tvkecjj56akz4xj7fvku"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacedki4apynvdxxuoigmqkgaktgy2erjftoxqxqaklnelgveyaqknfu"),
|
||||
"cron": MustParseCid("bafk2bzacebjpczf7qtcisy3zdp3sqoohxe75tgupmdo5dr26vh7orzrsjn3b2"),
|
||||
@ -439,7 +439,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacebzso6xkjxdscbpncw7el2d4hap6lfkgwqzrbc76lzp33vkwk6obc"),
|
||||
"storagemarket": MustParseCid("bafk2bzacebzg74vyk3gzbhnz4zviwvxblyar574mtd6ayognmsvlkriejmunu"),
|
||||
"storageminer": MustParseCid("bafk2bzaceckqrzomdnfb35byrhabrmmapxplj66cv3efw7u62qswjaqsuxah4"),
|
||||
"storageminer": MustParseCid("bafk2bzacecs262232b3awcrilyzpdketeayyqzzwgoavtxilgjvayrz55ovk4"),
|
||||
"storagepower": MustParseCid("bafk2bzacebbtj2m2ajawfuzxqz5nmdep7xevjo2qfjqa5tx3vr5m6qojolya4"),
|
||||
"system": MustParseCid("bafk2bzacecnau5wddulbsvwn75tc3w75jrlvkybgrlxs4ngonqab6xq3eowvg"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacec37mddea65nvh4htsagtryfa3sq6i67utcupslyhzbhjhoy6hopa"),
|
||||
@ -553,8 +553,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "mainnet",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacecooh5cjxkmraawn7wvmrx7k5hwdmbvqdteujr33mnaeclsazyb6a"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzaceboftg75mdiba7xbo2i3uvgtca4brhnr3u5ptihonixgpnrvhpxoa"),
|
||||
"cron": MustParseCid("bafk2bzacechxjkfe2cehx4s7skj3wzfpzf7zolds64khrrrs66bhazsemktls"),
|
||||
@ -568,7 +568,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzacealqnxn5lwzwexd6reav4dppypquklx2ujlnvaxiqk2tzstyvkp5u"),
|
||||
"storagemarket": MustParseCid("bafk2bzacedylkg5am446lcuih4voyzdn4yjeqfsxfzh5b6mcuhx4mok5ph5c4"),
|
||||
"storageminer": MustParseCid("bafk2bzacedio7wfaqutc4w6gl2dwqkgpcatz2r223ms74zxiovbjrfxmzeiou"),
|
||||
"storageminer": MustParseCid("bafk2bzacedo75pabe4i2l3hvhtsjmijrcytd2y76xwe573uku25fi7sugqld6"),
|
||||
"storagepower": MustParseCid("bafk2bzacecsij5tpfzjpfuckxvccv2p3bdqjklkrfyyoei6lx5dyj5j4fvjm6"),
|
||||
"system": MustParseCid("bafk2bzacebfqrja2hip7esf4eafxjmu6xcogoqu5xxtgdg7xa5szgvvdguchu"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzacedudgflxc75c77c6zkmfyq4u2xuk7k6xw6dfdccarjrvxx453b77q"),
|
||||
@ -659,8 +659,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "testing",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzacec7artlmtdmfuhurd2i7dgturiveblruub5xh3yizjtp5qzye3dly"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzaceaaxd6ytavsek5bi5soqo7qamezuqfyfjy42es2clpbzu3pwzcmye"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
|
||||
"cron": MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
|
||||
@ -674,7 +674,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
|
||||
"storageminer": MustParseCid("bafk2bzaceclcbtu6edh73cn7ga7kzkmxcfnjt7jnxolkc5id6l6f7sztevm24"),
|
||||
"storageminer": MustParseCid("bafk2bzacecvkbsjhufq2zr2dojohukdnql3gkqzdkmtp2hxvn5kczxp3tu6ko"),
|
||||
"storagepower": MustParseCid("bafk2bzacedexrf5qplrrl5xzijfrthjdqwodfs5e6zj5kpztc7qnywbqdyiii"),
|
||||
"system": MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
|
||||
@ -765,8 +765,8 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
}, {
|
||||
Network: "testing-fake-proofs",
|
||||
Version: 12,
|
||||
BundleGitTag: "v12.0.0-rc.2",
|
||||
ManifestCid: MustParseCid("bafy2bzaceand7owcb3omq7zjwir2q3lqapprl2eyiwpzv6oqs5bok4vzzqjbu"),
|
||||
BundleGitTag: "v12.0.0",
|
||||
ManifestCid: MustParseCid("bafy2bzacecver4l5d6jiuzubhrtcxjjfdx6jnxbmyp4bselol2atgkhz3e3um"),
|
||||
Actors: map[string]cid.Cid{
|
||||
"account": MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
|
||||
"cron": MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
|
||||
@ -780,7 +780,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
|
||||
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
|
||||
"reward": MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
|
||||
"storagemarket": MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
|
||||
"storageminer": MustParseCid("bafk2bzacebbusvtnyhi7mimbnx2tw2uyvrr3fbmncbf6frx6e4kvjvoqllu36"),
|
||||
"storageminer": MustParseCid("bafk2bzacedapzgrbc2rsmuqex76ftt2b62q6opi56gh2dr2oyyzuwin62rweg"),
|
||||
"storagepower": MustParseCid("bafk2bzacecdwijcbbryinjtm27pdinqqkyzoskri24pwsvsadwcq2alkkjpnc"),
|
||||
"system": MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
|
||||
"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -70,6 +70,9 @@ var UpgradeWatermelonHeight = abi.ChainEpoch(200)
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -100
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFix2Height = -101
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
@ -60,6 +60,9 @@ const UpgradeWatermelonHeight = 400
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -100
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFix2Height = -101
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg512MiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
|
@ -85,6 +85,9 @@ const UpgradeWatermelonHeight = 1013134
|
||||
// 2023-11-07T13:00:00Z
|
||||
const UpgradeWatermelonFixHeight = 1070494
|
||||
|
||||
// 2023-11-21T13:00:00Z
|
||||
const UpgradeWatermelonFix2Height = 1108174
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
|
@ -59,6 +59,9 @@ const UpgradeWatermelonHeight = 50
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -1
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFix2Height = -2
|
||||
|
||||
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
}
|
||||
|
@ -95,12 +95,15 @@ const UpgradeLightningHeight = 2809800
|
||||
// 2023-05-18T13:00:00Z
|
||||
const UpgradeThunderHeight = UpgradeLightningHeight + 2880*21
|
||||
|
||||
// 2023-11-29T13:30:00Z
|
||||
var UpgradeWatermelonHeight = abi.ChainEpoch(3431940)
|
||||
// 2023-12-12T13:30:00Z
|
||||
var UpgradeWatermelonHeight = abi.ChainEpoch(3469380)
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFixHeight = -1
|
||||
|
||||
// This fix upgrade only ran on calibrationnet
|
||||
const UpgradeWatermelonFix2Height = -2
|
||||
|
||||
var SupportedProofTypes = []abi.RegisteredSealProof{
|
||||
abi.RegisteredSealProof_StackedDrg32GiBV1,
|
||||
abi.RegisteredSealProof_StackedDrg64GiBV1,
|
||||
|
@ -87,30 +87,31 @@ var (
|
||||
UpgradeBreezeHeight abi.ChainEpoch = -1
|
||||
BreezeGasTampingDuration abi.ChainEpoch = 0
|
||||
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeAssemblyHeight abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -8
|
||||
UpgradePersianHeight abi.ChainEpoch = -9
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
||||
UpgradeClausHeight abi.ChainEpoch = -11
|
||||
UpgradeTrustHeight abi.ChainEpoch = -12
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -13
|
||||
UpgradeTurboHeight abi.ChainEpoch = -14
|
||||
UpgradeHyperdriveHeight abi.ChainEpoch = -15
|
||||
UpgradeChocolateHeight abi.ChainEpoch = -16
|
||||
UpgradeOhSnapHeight abi.ChainEpoch = -17
|
||||
UpgradeSkyrHeight abi.ChainEpoch = -18
|
||||
UpgradeSharkHeight abi.ChainEpoch = -19
|
||||
UpgradeHyggeHeight abi.ChainEpoch = -20
|
||||
UpgradeLightningHeight abi.ChainEpoch = -21
|
||||
UpgradeThunderHeight abi.ChainEpoch = -22
|
||||
UpgradeWatermelonHeight abi.ChainEpoch = -23
|
||||
UpgradeWatermelonFixHeight abi.ChainEpoch = -24
|
||||
UpgradeSmokeHeight abi.ChainEpoch = -1
|
||||
UpgradeIgnitionHeight abi.ChainEpoch = -2
|
||||
UpgradeRefuelHeight abi.ChainEpoch = -3
|
||||
UpgradeTapeHeight abi.ChainEpoch = -4
|
||||
UpgradeAssemblyHeight abi.ChainEpoch = 10
|
||||
UpgradeLiftoffHeight abi.ChainEpoch = -5
|
||||
UpgradeKumquatHeight abi.ChainEpoch = -6
|
||||
UpgradeCalicoHeight abi.ChainEpoch = -8
|
||||
UpgradePersianHeight abi.ChainEpoch = -9
|
||||
UpgradeOrangeHeight abi.ChainEpoch = -10
|
||||
UpgradeClausHeight abi.ChainEpoch = -11
|
||||
UpgradeTrustHeight abi.ChainEpoch = -12
|
||||
UpgradeNorwegianHeight abi.ChainEpoch = -13
|
||||
UpgradeTurboHeight abi.ChainEpoch = -14
|
||||
UpgradeHyperdriveHeight abi.ChainEpoch = -15
|
||||
UpgradeChocolateHeight abi.ChainEpoch = -16
|
||||
UpgradeOhSnapHeight abi.ChainEpoch = -17
|
||||
UpgradeSkyrHeight abi.ChainEpoch = -18
|
||||
UpgradeSharkHeight abi.ChainEpoch = -19
|
||||
UpgradeHyggeHeight abi.ChainEpoch = -20
|
||||
UpgradeLightningHeight abi.ChainEpoch = -21
|
||||
UpgradeThunderHeight abi.ChainEpoch = -22
|
||||
UpgradeWatermelonHeight abi.ChainEpoch = -23
|
||||
UpgradeWatermelonFixHeight abi.ChainEpoch = -24
|
||||
UpgradeWatermelonFix2Height abi.ChainEpoch = -25
|
||||
|
||||
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
|
||||
0: DrandMainnet,
|
||||
|
@ -37,7 +37,7 @@ func BuildTypeString() string {
|
||||
}
|
||||
|
||||
// BuildVersion is the local build version
|
||||
const BuildVersion = "1.25.0-rc4"
|
||||
const BuildVersion = "1.25.1-dev"
|
||||
|
||||
func UserVersion() string {
|
||||
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
||||
|
@ -279,8 +279,13 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
|
||||
}, {
|
||||
Height: build.UpgradeWatermelonFixHeight,
|
||||
Network: network.Version21,
|
||||
Migration: upgradeActorsV12Fix,
|
||||
Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID1, calibnetv12BuggyManifestCID2),
|
||||
},
|
||||
{
|
||||
Height: build.UpgradeWatermelonFix2Height,
|
||||
Network: network.Version21,
|
||||
Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID2, calibnetv12CorrectManifestCID1),
|
||||
},
|
||||
}
|
||||
|
||||
for _, u := range updates {
|
||||
@ -1876,7 +1881,17 @@ func UpgradeActorsV12(ctx context.Context, sm *stmgr.StateManager, cache stmgr.M
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
var calibnetv12BuggyBundle = cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs")
|
||||
var (
|
||||
calibnetv12BuggyMinerCID1 = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq")
|
||||
calibnetv12BuggyMinerCID2 = cid.MustParse("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie")
|
||||
|
||||
calibnetv12BuggyBundleSuffix1 = "calibrationnet-12-rc1"
|
||||
calibnetv12BuggyBundleSuffix2 = "calibrationnet-12-rc2"
|
||||
|
||||
calibnetv12BuggyManifestCID1 = cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs")
|
||||
calibnetv12BuggyManifestCID2 = cid.MustParse("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru")
|
||||
calibnetv12CorrectManifestCID1 = cid.MustParse("bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca")
|
||||
)
|
||||
|
||||
func upgradeActorsV12Common(
|
||||
ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache,
|
||||
@ -1923,7 +1938,7 @@ func upgradeActorsV12Common(
|
||||
|
||||
var manifestCid cid.Cid
|
||||
if initState.NetworkName == "calibrationnet" {
|
||||
embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, "calibrationnet-buggy")
|
||||
embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, calibnetv12BuggyBundleSuffix1)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("didn't find buggy calibrationnet bundle")
|
||||
}
|
||||
@ -1934,8 +1949,8 @@ func upgradeActorsV12Common(
|
||||
return cid.Undef, xerrors.Errorf("failed to load buggy calibnet bundle: %w", err)
|
||||
}
|
||||
|
||||
if manifestCid != calibnetv12BuggyBundle {
|
||||
return cid.Undef, xerrors.Errorf("didn't find expected buggy calibnet bundle manifest: %s != %s", manifestCid, calibnetv12BuggyBundle)
|
||||
if manifestCid != calibnetv12BuggyManifestCID1 {
|
||||
return cid.Undef, xerrors.Errorf("didn't find expected buggy calibnet bundle manifest: %s != %s", manifestCid, calibnetv12BuggyManifestCID1)
|
||||
}
|
||||
} else {
|
||||
ok := false
|
||||
@ -1974,148 +1989,161 @@ func upgradeActorsV12Common(
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
// ////////////////////
|
||||
func buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestCID cid.Cid) func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||
return func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||
stateStore := sm.ChainStore().StateBlockstore()
|
||||
adtStore := store.ActorStore(ctx, stateStore)
|
||||
|
||||
var calibnetv12BuggyMinerCID = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq")
|
||||
// ensure that the manifest is loaded in the blockstore
|
||||
|
||||
func upgradeActorsV12Fix(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor,
|
||||
root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
|
||||
stateStore := sm.ChainStore().StateBlockstore()
|
||||
adtStore := store.ActorStore(ctx, stateStore)
|
||||
|
||||
// ensure that the manifest is loaded in the blockstore
|
||||
if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
|
||||
}
|
||||
|
||||
// Load input state tree
|
||||
actorsIn, err := state.LoadStateTree(adtStore, root)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
// load old manifest data
|
||||
systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
|
||||
var systemState system11.State
|
||||
if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
|
||||
}
|
||||
|
||||
var oldManifestData manifest.ManifestData
|
||||
if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err)
|
||||
}
|
||||
|
||||
newManifestCID, ok := actors.GetManifest(actorstypes.Version12)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade")
|
||||
}
|
||||
|
||||
// load new manifest
|
||||
var newManifest manifest.Manifest
|
||||
if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
if err := newManifest.Load(ctx, adtStore); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
// build the CID mapping
|
||||
codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries))
|
||||
for _, oldEntry := range oldManifestData.Entries {
|
||||
newCID, ok := newManifest.Get(oldEntry.Name)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name)
|
||||
// this loads the "correct" bundle for UpgradeWatermelonFix2Height
|
||||
if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
|
||||
}
|
||||
|
||||
// Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor
|
||||
codeMapping[oldEntry.Code] = newCID
|
||||
}
|
||||
|
||||
// Create empty actorsOut
|
||||
|
||||
actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version())
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err)
|
||||
}
|
||||
|
||||
// Perform the migration
|
||||
err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error {
|
||||
newCid, ok := codeMapping[actor.Code]
|
||||
// this loads the second buggy bundle, for UpgradeWatermelonFixHeight
|
||||
embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, calibnetv12BuggyBundleSuffix2)
|
||||
if !ok {
|
||||
return xerrors.Errorf("didn't find mapping for %s", actor.Code)
|
||||
return cid.Undef, xerrors.Errorf("didn't find buggy calibrationnet bundle")
|
||||
}
|
||||
|
||||
return actorsOut.SetActor(a, &types.ActorV5{
|
||||
Code: newCid,
|
||||
Head: actor.Head,
|
||||
Nonce: actor.Nonce,
|
||||
Balance: actor.Balance,
|
||||
Address: actor.Address,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err)
|
||||
}
|
||||
|
||||
systemState.BuiltinActors = newManifest.Data
|
||||
newSystemHead, err := adtStore.Put(ctx, &systemState)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err)
|
||||
}
|
||||
|
||||
systemActor.Head = newSystemHead
|
||||
if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err)
|
||||
}
|
||||
|
||||
// Sanity checking
|
||||
|
||||
err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error {
|
||||
outActor, err := actorsOut.GetActor(a)
|
||||
_, err := bundle.LoadBundle(ctx, stateStore, bytes.NewReader(embedded))
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get actor in outTree: %w", err)
|
||||
return cid.Undef, xerrors.Errorf("failed to load buggy calibnet bundle: %w", err)
|
||||
}
|
||||
|
||||
if inActor.Nonce != outActor.Nonce {
|
||||
return xerrors.Errorf("mismatched nonce for actor %s", a)
|
||||
// now confirm we have the one we're migrating to
|
||||
if haveManifest, err := stateStore.Has(ctx, newManifestCID); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("blockstore error when loading manifest %s: %w", newManifestCID, err)
|
||||
} else if !haveManifest {
|
||||
return cid.Undef, xerrors.Errorf("missing new manifest %s in blockstore", newManifestCID)
|
||||
}
|
||||
|
||||
if !inActor.Balance.Equals(outActor.Balance) {
|
||||
return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
|
||||
// Load input state tree
|
||||
actorsIn, err := state.LoadStateTree(adtStore, root)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
|
||||
}
|
||||
|
||||
if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
|
||||
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
|
||||
// load old manifest data
|
||||
systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
|
||||
}
|
||||
|
||||
if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
|
||||
return xerrors.Errorf("mismatched head for actor %s", a)
|
||||
var systemState system11.State
|
||||
if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
|
||||
}
|
||||
|
||||
// This is the hard-coded "buggy" miner actor Code ID
|
||||
if inActor.Code != calibnetv12BuggyMinerCID && inActor.Code != outActor.Code {
|
||||
return xerrors.Errorf("unexpected change in code for actor %s", a)
|
||||
var oldManifestData manifest.ManifestData
|
||||
if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err)
|
||||
// load new manifest
|
||||
var newManifest manifest.Manifest
|
||||
if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
if err := newManifest.Load(ctx, adtStore); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err)
|
||||
}
|
||||
|
||||
// build the CID mapping
|
||||
codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries))
|
||||
for _, oldEntry := range oldManifestData.Entries {
|
||||
newCID, ok := newManifest.Get(oldEntry.Name)
|
||||
if !ok {
|
||||
return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name)
|
||||
}
|
||||
|
||||
// Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor
|
||||
codeMapping[oldEntry.Code] = newCID
|
||||
}
|
||||
|
||||
// Create empty actorsOut
|
||||
|
||||
actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version())
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err)
|
||||
}
|
||||
|
||||
// Perform the migration
|
||||
err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error {
|
||||
newCid, ok := codeMapping[actor.Code]
|
||||
if !ok {
|
||||
return xerrors.Errorf("didn't find mapping for %s", actor.Code)
|
||||
}
|
||||
|
||||
return actorsOut.SetActor(a, &types.ActorV5{
|
||||
Code: newCid,
|
||||
Head: actor.Head,
|
||||
Nonce: actor.Nonce,
|
||||
Balance: actor.Balance,
|
||||
Address: actor.Address,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err)
|
||||
}
|
||||
|
||||
systemState.BuiltinActors = newManifest.Data
|
||||
newSystemHead, err := adtStore.Put(ctx, &systemState)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err)
|
||||
}
|
||||
|
||||
systemActor.Head = newSystemHead
|
||||
if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err)
|
||||
}
|
||||
|
||||
// Sanity checking
|
||||
|
||||
err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error {
|
||||
outActor, err := actorsOut.GetActor(a)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get actor in outTree: %w", err)
|
||||
}
|
||||
|
||||
if inActor.Nonce != outActor.Nonce {
|
||||
return xerrors.Errorf("mismatched nonce for actor %s", a)
|
||||
}
|
||||
|
||||
if !inActor.Balance.Equals(outActor.Balance) {
|
||||
return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
|
||||
}
|
||||
|
||||
if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
|
||||
return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
|
||||
}
|
||||
|
||||
if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
|
||||
return xerrors.Errorf("mismatched head for actor %s", a)
|
||||
}
|
||||
|
||||
// Actor Codes are only expected to change for the miner actor
|
||||
if inActor.Code != oldBuggyMinerCID && inActor.Code != outActor.Code {
|
||||
return xerrors.Errorf("unexpected change in code for actor %s", a)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err)
|
||||
}
|
||||
|
||||
// Persist the result.
|
||||
newRoot, err := actorsOut.Flush(ctx)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
|
||||
}
|
||||
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
// Persist the result.
|
||||
newRoot, err := actorsOut.Flush(ctx)
|
||||
if err != nil {
|
||||
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
|
||||
}
|
||||
|
||||
return newRoot, nil
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
@ -62,9 +62,14 @@ type EthTxArgs struct {
|
||||
// - BlockHash
|
||||
// - BlockNumber
|
||||
// - TransactionIndex
|
||||
// - From
|
||||
// - Hash
|
||||
func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) {
|
||||
// The from address is always an f410f address, never an ID or other address.
|
||||
if !IsEthAddress(smsg.Message.From) {
|
||||
return EthTx{}, xerrors.Errorf("sender must be an eth account, was %s", smsg.Message.From)
|
||||
}
|
||||
|
||||
// Probably redundant, but we might as well check.
|
||||
if smsg.Signature.Type != typescrypto.SigTypeDelegated {
|
||||
return EthTx{}, xerrors.Errorf("signature is not delegated type, is type: %d", smsg.Signature.Type)
|
||||
}
|
||||
@ -79,10 +84,18 @@ func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) {
|
||||
return EthTx{}, xerrors.Errorf("failed to recover signature: %w", err)
|
||||
}
|
||||
|
||||
from, err := EthAddressFromFilecoinAddress(smsg.Message.From)
|
||||
if err != nil {
|
||||
// This should be impossible as we've already asserted that we have an EthAddress
|
||||
// sender...
|
||||
return EthTx{}, xerrors.Errorf("sender was not an eth account")
|
||||
}
|
||||
|
||||
return EthTx{
|
||||
Nonce: EthUint64(txArgs.Nonce),
|
||||
ChainID: EthUint64(txArgs.ChainID),
|
||||
To: txArgs.To,
|
||||
From: from,
|
||||
Value: EthBigInt(txArgs.Value),
|
||||
Type: Eip1559TxType,
|
||||
Gas: EthUint64(txArgs.GasLimit),
|
||||
|
@ -266,7 +266,10 @@ var simplePreCommit1 = &cli.Command{
|
||||
ProofType: spt(sectorSize, cctx.Bool("synthetic")),
|
||||
}
|
||||
|
||||
var ticket [32]byte // all zero
|
||||
ticket := [32]byte{}
|
||||
for i := range ticket {
|
||||
ticket[i] = 1
|
||||
}
|
||||
|
||||
pieces, err := ParsePieceInfos(cctx, 3)
|
||||
if err != nil {
|
||||
@ -420,7 +423,12 @@ var simpleCommit1 = &cli.Command{
|
||||
|
||||
start := time.Now()
|
||||
|
||||
var ticket, seed [32]byte // all zero
|
||||
ticket := [32]byte{}
|
||||
seed := [32]byte{}
|
||||
for i := range ticket {
|
||||
ticket[i] = 1
|
||||
seed[i] = 1
|
||||
}
|
||||
|
||||
commd, err := cid.Parse(cctx.Args().Get(2))
|
||||
if err != nil {
|
||||
|
@ -21,7 +21,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/builtin"
|
||||
minerV12 "github.com/filecoin-project/go-state-types/builtin/v12/miner"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v9/miner"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
|
||||
@ -50,7 +49,6 @@ var actorCmd = &cli.Command{
|
||||
actorProposeChangeWorker,
|
||||
actorConfirmChangeWorker,
|
||||
actorCompactAllocatedCmd,
|
||||
actorMovePartitionsCmd,
|
||||
actorProposeChangeBeneficiary,
|
||||
actorConfirmChangeBeneficiary,
|
||||
},
|
||||
@ -1288,142 +1286,6 @@ var actorConfirmChangeBeneficiary = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var actorMovePartitionsCmd = &cli.Command{
|
||||
Name: "move-partitions",
|
||||
Usage: "move deadline of specified partitions from one to another",
|
||||
Flags: []cli.Flag{
|
||||
&cli.Int64SliceFlag{
|
||||
Name: "partition-indices",
|
||||
Usage: "Indices of partitions to update, separated by comma",
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "orig-deadline",
|
||||
Usage: "Deadline to move partition from",
|
||||
},
|
||||
&cli.Uint64Flag{
|
||||
Name: "dest-deadline",
|
||||
Usage: "Deadline to move partition to",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "really-do-it",
|
||||
Usage: "Actually send transaction performing the action",
|
||||
Value: false,
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if !cctx.Bool("really-do-it") {
|
||||
fmt.Println("Pass --really-do-it to actually execute this action")
|
||||
return nil
|
||||
}
|
||||
|
||||
if cctx.Args().Present() {
|
||||
return fmt.Errorf("please use flags to provide arguments")
|
||||
}
|
||||
|
||||
ctx := lcli.ReqContext(cctx)
|
||||
|
||||
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
maddr, err := minerApi.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Miner: %s\n", color.BlueString("%s", maddr))
|
||||
|
||||
fullNodeApi, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer acloser()
|
||||
|
||||
minfo, err := fullNodeApi.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
origDeadline := cctx.Uint64("orig-deadline")
|
||||
if origDeadline > miner.WPoStPeriodDeadlines {
|
||||
return fmt.Errorf("orig-deadline %d out of range", origDeadline)
|
||||
}
|
||||
destDeadline := cctx.Uint64("dest-deadline")
|
||||
if destDeadline > miner.WPoStPeriodDeadlines {
|
||||
return fmt.Errorf("dest-deadline %d out of range", destDeadline)
|
||||
}
|
||||
if origDeadline == destDeadline {
|
||||
return fmt.Errorf("dest-desdline cannot be the same as orig-deadline")
|
||||
}
|
||||
|
||||
partitions := cctx.Int64Slice("partition-indices")
|
||||
if len(partitions) == 0 {
|
||||
return fmt.Errorf("must include at least one partition to move")
|
||||
}
|
||||
|
||||
curPartitions, err := fullNodeApi.StateMinerPartitions(ctx, maddr, origDeadline, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting partitions for deadline %d: %w", origDeadline, err)
|
||||
}
|
||||
if len(partitions) > len(curPartitions) {
|
||||
return fmt.Errorf("partition size(%d) cannot be bigger than current partition size(%d) for deadline %d", len(partitions), len(curPartitions), origDeadline)
|
||||
}
|
||||
|
||||
fmt.Printf("Moving %d paritions\n", len(partitions))
|
||||
|
||||
partitionsBf := bitfield.New()
|
||||
for _, partition := range partitions {
|
||||
if partition >= int64(len(curPartitions)) {
|
||||
return fmt.Errorf("partition index(%d) doesn't exist", partition)
|
||||
}
|
||||
partitionsBf.Set(uint64(partition))
|
||||
}
|
||||
|
||||
params := minerV12.MovePartitionsParams{
|
||||
OrigDeadline: origDeadline,
|
||||
DestDeadline: destDeadline,
|
||||
Partitions: partitionsBf,
|
||||
}
|
||||
|
||||
serializedParams, err := actors.SerializeParams(¶ms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("serializing params: %w", err)
|
||||
}
|
||||
|
||||
smsg, err := fullNodeApi.MpoolPushMessage(ctx, &types.Message{
|
||||
From: minfo.Worker,
|
||||
To: maddr,
|
||||
Method: builtin.MethodsMiner.MovePartitions,
|
||||
Value: big.Zero(),
|
||||
Params: serializedParams,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mpool push: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("MovePartitions Message CID:", smsg.Cid())
|
||||
|
||||
// wait for it to get mined into a block
|
||||
fmt.Println("Waiting for block confirmation...")
|
||||
wait, err := fullNodeApi.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check it executed successfully
|
||||
if wait.Receipt.ExitCode.IsError() {
|
||||
fmt.Println("Moving partitions failed!")
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Move partition confirmed")
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var actorCompactAllocatedCmd = &cli.Command{
|
||||
Name: "compact-allocated",
|
||||
Usage: "compact allocated sectors bitfield",
|
||||
|
@ -42,8 +42,8 @@ import (
|
||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
"github.com/filecoin-project/lotus/provider"
|
||||
"github.com/filecoin-project/lotus/storage/ctladdr"
|
||||
"github.com/filecoin-project/lotus/provider/lpwinning"
|
||||
"github.com/filecoin-project/lotus/storage/ctladdr"
|
||||
"github.com/filecoin-project/lotus/storage/paths"
|
||||
"github.com/filecoin-project/lotus/storage/sealer"
|
||||
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
|
||||
|
@ -7,7 +7,7 @@ USAGE:
|
||||
lotus-miner [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
1.25.0-rc4
|
||||
1.25.1-dev
|
||||
|
||||
COMMANDS:
|
||||
init Initialize a lotus miner repo
|
||||
@ -223,7 +223,6 @@ COMMANDS:
|
||||
propose-change-worker Propose a worker address change
|
||||
confirm-change-worker Confirm a worker address change
|
||||
compact-allocated compact allocated sectors bitfield
|
||||
move-partitions move deadline of specified partitions from one to another
|
||||
propose-change-beneficiary Propose a beneficiary address change
|
||||
confirm-change-beneficiary Confirm a beneficiary address change
|
||||
help, h Shows a list of commands or help for one command
|
||||
@ -373,22 +372,6 @@ OPTIONS:
|
||||
--help, -h show help
|
||||
```
|
||||
|
||||
### lotus-miner actor move-partitions
|
||||
```
|
||||
NAME:
|
||||
lotus-miner actor move-partitions - move deadline of specified partitions from one to another
|
||||
|
||||
USAGE:
|
||||
lotus-miner actor move-partitions [command options] [arguments...]
|
||||
|
||||
OPTIONS:
|
||||
--partition-indices value [ --partition-indices value ] Indices of partitions to update, separated by comma
|
||||
--orig-deadline value Deadline to move partition from (default: 0)
|
||||
--dest-deadline value Deadline to move partition to (default: 0)
|
||||
--really-do-it Actually send transaction performing the action (default: false)
|
||||
--help, -h show help
|
||||
```
|
||||
|
||||
### lotus-miner actor propose-change-beneficiary
|
||||
```
|
||||
NAME:
|
||||
|
@ -7,7 +7,7 @@ USAGE:
|
||||
lotus-worker [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
1.25.0-rc4
|
||||
1.25.1-dev
|
||||
|
||||
COMMANDS:
|
||||
run Start lotus worker
|
||||
|
@ -7,7 +7,7 @@ USAGE:
|
||||
lotus [global options] command [command options] [arguments...]
|
||||
|
||||
VERSION:
|
||||
1.25.0-rc4
|
||||
1.25.1-dev
|
||||
|
||||
COMMANDS:
|
||||
daemon Start a lotus daemon process
|
||||
|
2
extern/filecoin-ffi
vendored
2
extern/filecoin-ffi
vendored
@ -1 +1 @@
|
||||
Subproject commit 441fa8e61189dc32c2960c1f8d8ba56269f20366
|
||||
Subproject commit 4176a1e662e865834bfdc5861da921dc2d272b45
|
2
go.mod
2
go.mod
@ -45,7 +45,7 @@ require (
|
||||
github.com/filecoin-project/go-jsonrpc v0.3.1
|
||||
github.com/filecoin-project/go-padreader v0.0.1
|
||||
github.com/filecoin-project/go-paramfetch v0.0.4
|
||||
github.com/filecoin-project/go-state-types v0.12.5
|
||||
github.com/filecoin-project/go-state-types v0.12.8
|
||||
github.com/filecoin-project/go-statemachine v1.0.3
|
||||
github.com/filecoin-project/go-statestore v0.2.0
|
||||
github.com/filecoin-project/go-storedcounter v0.1.0
|
||||
|
4
go.sum
4
go.sum
@ -345,8 +345,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS
|
||||
github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
|
||||
github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
|
||||
github.com/filecoin-project/go-state-types v0.11.2-0.20230712101859-8f37624fa540/go.mod h1:SyNPwTsU7I22gL2r0OAPcImvLoTVfgRwdK/Y5rR1zz8=
|
||||
github.com/filecoin-project/go-state-types v0.12.5 h1:VQ2N2T3JeUDdIHEo/xhjnT7Q218Wl0UYIyglqT7Z9Ck=
|
||||
github.com/filecoin-project/go-state-types v0.12.5/go.mod h1:iJTqGdWDvzXhuVf64Lw0hzt4TIoitMo0VgHdxdjNDZI=
|
||||
github.com/filecoin-project/go-state-types v0.12.8 h1:W/UObdAsv+LbB9EfyLg92DSYoatzUWmlfV8FGyh30VA=
|
||||
github.com/filecoin-project/go-state-types v0.12.8/go.mod h1:gR2NV0CSGSQwopxF+3In9nDh1sqvoYukLcs5vK0AHCA=
|
||||
github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
|
||||
github.com/filecoin-project/go-statemachine v1.0.3 h1:N07o6alys+V1tNoSTi4WuuoeNC4erS/6jE74+NsgQuk=
|
||||
github.com/filecoin-project/go-statemachine v1.0.3/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=
|
||||
|
@ -120,7 +120,6 @@ func TestTransactionHashLookupBlsFilecoinMessage(t *testing.T) {
|
||||
kit.MockProofs(),
|
||||
kit.ThroughRPC(),
|
||||
)
|
||||
ens.InterconnectAll().BeginMining(blocktime)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
@ -146,9 +145,13 @@ func TestTransactionHashLookupBlsFilecoinMessage(t *testing.T) {
|
||||
hash, err := ethtypes.EthHashFromCid(sm.Message.Cid())
|
||||
require.NoError(t, err)
|
||||
|
||||
mpoolTx, err := client.EthGetTransactionByHash(ctx, &hash)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hash, mpoolTx.Hash)
|
||||
// Assert that BLS messages cannot be retrieved from the message pool until it lands
|
||||
// on-chain via the eth API.
|
||||
_, err = client.EthGetTransactionByHash(ctx, &hash)
|
||||
require.Error(t, err)
|
||||
|
||||
// Now start mining.
|
||||
ens.InterconnectAll().BeginMining(blocktime)
|
||||
|
||||
// Wait for message to land on chain
|
||||
var receipt *api.EthTxReceipt
|
||||
@ -177,6 +180,25 @@ func TestTransactionHashLookupBlsFilecoinMessage(t *testing.T) {
|
||||
require.NotEmpty(t, *chainTx.BlockHash)
|
||||
require.NotNil(t, chainTx.TransactionIndex)
|
||||
require.Equal(t, uint64(*chainTx.TransactionIndex), uint64(0)) // only transaction
|
||||
|
||||
// verify that we correctly reported the to address.
|
||||
toId, err := client.StateLookupID(ctx, addr, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
toEth, err := client.FilecoinAddressToEthAddress(ctx, toId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &toEth, chainTx.To)
|
||||
|
||||
const expectedHex = "868e10c4" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000060" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
// verify that the params are correctly encoded.
|
||||
expected, err := hex.DecodeString(expectedHex)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, ethtypes.EthBytes(expected), chainTx.Input)
|
||||
}
|
||||
|
||||
// TestTransactionHashLookupSecpFilecoinMessage tests to see if lotus can find a Secp Filecoin Message using the transaction hash
|
||||
@ -228,10 +250,6 @@ func TestTransactionHashLookupSecpFilecoinMessage(t *testing.T) {
|
||||
hash, err := ethtypes.EthHashFromCid(secpSmsg.Cid())
|
||||
require.NoError(t, err)
|
||||
|
||||
mpoolTx, err := client.EthGetTransactionByHash(ctx, &hash)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hash, mpoolTx.Hash)
|
||||
|
||||
_, err = client.StateWaitMsg(ctx, secpSmsg.Cid(), 3, api.LookbackNoLimit, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -253,6 +271,25 @@ func TestTransactionHashLookupSecpFilecoinMessage(t *testing.T) {
|
||||
require.NotEmpty(t, *chainTx.BlockHash)
|
||||
require.NotNil(t, chainTx.TransactionIndex)
|
||||
require.Equal(t, uint64(*chainTx.TransactionIndex), uint64(0)) // only transaction
|
||||
|
||||
// verify that we correctly reported the to address.
|
||||
toId, err := client.StateLookupID(ctx, client.DefaultKey.Address, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
toEth, err := client.FilecoinAddressToEthAddress(ctx, toId)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &toEth, chainTx.To)
|
||||
|
||||
const expectedHex = "868e10c4" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000060" +
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
// verify that the params are correctly encoded.
|
||||
expected, err := hex.DecodeString(expectedHex)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, ethtypes.EthBytes(expected), chainTx.Input)
|
||||
}
|
||||
|
||||
// TestTransactionHashLookupSecpFilecoinMessage tests to see if lotus can find a Secp Filecoin Message using the transaction hash
|
||||
|
@ -9,11 +9,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtin2 "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
@ -78,7 +80,7 @@ func TestValueTransferValidSignature(t *testing.T) {
|
||||
client.EVM().SignTransaction(&tx, key.PrivateKey)
|
||||
hash := client.EVM().SubmitTransaction(ctx, &tx)
|
||||
|
||||
receipt, err := waitForEthTxReceipt(ctx, client, hash)
|
||||
receipt, err := client.EVM().WaitTransaction(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
require.EqualValues(t, ethAddr, receipt.From)
|
||||
@ -166,7 +168,7 @@ func TestContractDeploymentValidSignature(t *testing.T) {
|
||||
client.EVM().SignTransaction(tx, key.PrivateKey)
|
||||
hash := client.EVM().SubmitTransaction(ctx, tx)
|
||||
|
||||
receipt, err := waitForEthTxReceipt(ctx, client, hash)
|
||||
receipt, err := client.EVM().WaitTransaction(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
|
||||
@ -213,7 +215,7 @@ func TestContractInvocation(t *testing.T) {
|
||||
client.EVM().SignTransaction(tx, key.PrivateKey)
|
||||
hash := client.EVM().SubmitTransaction(ctx, tx)
|
||||
|
||||
receipt, err := waitForEthTxReceipt(ctx, client, hash)
|
||||
receipt, err := client.EVM().WaitTransaction(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||
@ -267,7 +269,7 @@ func TestContractInvocation(t *testing.T) {
|
||||
client.EVM().SignTransaction(&invokeTx, key.PrivateKey)
|
||||
hash = client.EVM().SubmitTransaction(ctx, &invokeTx)
|
||||
|
||||
receipt, err = waitForEthTxReceipt(ctx, client, hash)
|
||||
receipt, err = client.EVM().WaitTransaction(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
|
||||
@ -376,16 +378,108 @@ func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr eth
|
||||
}, nil
|
||||
}
|
||||
|
||||
func waitForEthTxReceipt(ctx context.Context, client *kit.TestFullNode, hash ethtypes.EthHash) (*api.EthTxReceipt, error) {
|
||||
var receipt *api.EthTxReceipt
|
||||
var err error
|
||||
for i := 0; i < 10000000000; i++ {
|
||||
receipt, err = client.EthGetTransactionReceipt(ctx, hash)
|
||||
if err != nil || receipt == nil {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
break
|
||||
func TestEthTxFromNativeAccount(t *testing.T) {
|
||||
blockTime := 10 * time.Millisecond
|
||||
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
||||
|
||||
ens.InterconnectAll().BeginMining(blockTime)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
msg := &types.Message{
|
||||
From: client.DefaultKey.Address,
|
||||
To: client.DefaultKey.Address,
|
||||
Value: abi.TokenAmount(types.MustParseFIL("100")),
|
||||
Method: builtin2.MethodsEVM.InvokeContract,
|
||||
}
|
||||
return receipt, err
|
||||
|
||||
// Send a message with no input.
|
||||
|
||||
sMsg, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||
require.NoError(t, err)
|
||||
client.WaitMsg(ctx, sMsg.Cid())
|
||||
|
||||
hash, err := client.EthGetTransactionHashByCid(ctx, sMsg.Cid())
|
||||
require.NoError(t, err)
|
||||
tx, err := client.EthGetTransactionByHash(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Expect empty input params given that we "invoked" the contract (well, invoked ourselves).
|
||||
require.Equal(t, ethtypes.EthBytes{}, tx.Input)
|
||||
|
||||
// Send a message with some input.
|
||||
|
||||
input := abi.CborBytes([]byte{0x1, 0x2, 0x3, 0x4})
|
||||
msg.Params, err = actors.SerializeParams(&input)
|
||||
require.NoError(t, err)
|
||||
|
||||
sMsg, err = client.MpoolPushMessage(ctx, msg, nil)
|
||||
require.NoError(t, err)
|
||||
client.WaitMsg(ctx, sMsg.Cid())
|
||||
hash, err = client.EthGetTransactionHashByCid(ctx, sMsg.Cid())
|
||||
require.NoError(t, err)
|
||||
tx, err = client.EthGetTransactionByHash(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Expect the decoded input.
|
||||
require.EqualValues(t, input, tx.Input)
|
||||
|
||||
// Invoke the contract, but with incorrectly encoded input. We expect this to be abi-encoded
|
||||
// as if it were any other method call.
|
||||
|
||||
msg.Params = input
|
||||
require.NoError(t, err)
|
||||
|
||||
sMsg, err = client.MpoolPushMessage(ctx, msg, nil)
|
||||
require.NoError(t, err)
|
||||
client.WaitMsg(ctx, sMsg.Cid())
|
||||
hash, err = client.EthGetTransactionHashByCid(ctx, sMsg.Cid())
|
||||
require.NoError(t, err)
|
||||
tx, err = client.EthGetTransactionByHash(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
|
||||
const expectedHex1 = "868e10c4" + // "handle filecoin method" function selector
|
||||
// InvokeEVM method number
|
||||
"00000000000000000000000000000000000000000000000000000000e525aa15" +
|
||||
// CBOR multicodec (0x51)
|
||||
"0000000000000000000000000000000000000000000000000000000000000051" +
|
||||
// Offset
|
||||
"0000000000000000000000000000000000000000000000000000000000000060" +
|
||||
// Number of bytes in the input (4)
|
||||
"0000000000000000000000000000000000000000000000000000000000000004" +
|
||||
// Input: 1, 2, 3, 4
|
||||
"0102030400000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
input, err = hex.DecodeString(expectedHex1)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, input, tx.Input)
|
||||
|
||||
// Invoke a random method with the same input. We expect the same result as above, but with
|
||||
// a different method number.
|
||||
|
||||
msg.Method++
|
||||
|
||||
sMsg, err = client.MpoolPushMessage(ctx, msg, nil)
|
||||
require.NoError(t, err)
|
||||
client.WaitMsg(ctx, sMsg.Cid())
|
||||
hash, err = client.EthGetTransactionHashByCid(ctx, sMsg.Cid())
|
||||
require.NoError(t, err)
|
||||
tx, err = client.EthGetTransactionByHash(ctx, hash)
|
||||
require.NoError(t, err)
|
||||
|
||||
const expectedHex2 = "868e10c4" + // "handle filecoin method" function selector
|
||||
// InvokeEVM+1
|
||||
"00000000000000000000000000000000000000000000000000000000e525aa16" +
|
||||
// CBOR multicodec (0x51)
|
||||
"0000000000000000000000000000000000000000000000000000000000000051" +
|
||||
// Offset
|
||||
"0000000000000000000000000000000000000000000000000000000000000060" +
|
||||
// Number of bytes in the input (4)
|
||||
"0000000000000000000000000000000000000000000000000000000000000004" +
|
||||
// Input: 1, 2, 3, 4
|
||||
"0102030400000000000000000000000000000000000000000000000000000000"
|
||||
input, err = hex.DecodeString(expectedHex2)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, input, tx.Input)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package itests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
@ -14,8 +13,6 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
@ -43,7 +40,7 @@ func effectiveEthAddressForCreate(t *testing.T, sender address.Address) ethtypes
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func createAndDeploy(ctx context.Context, t *testing.T, client *kit.TestFullNode, fromAddr address.Address, contract []byte) *api.MsgLookup {
|
||||
func createAndDeploy(ctx context.Context, t *testing.T, client *kit.TestFullNode, fromAddr address.Address, contract []byte) *api.EthTxReceipt {
|
||||
// Create and deploy evm actor
|
||||
|
||||
method := builtintypes.MethodsEAM.CreateExternal
|
||||
@ -61,21 +58,13 @@ func createAndDeploy(ctx context.Context, t *testing.T, client *kit.TestFullNode
|
||||
smsg, err := client.MpoolPushMessage(ctx, createMsg, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
wait, err := client.StateWaitMsg(ctx, smsg.Cid(), 0, 0, false)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, exitcode.Ok, wait.Receipt.ExitCode)
|
||||
return wait
|
||||
}
|
||||
|
||||
func getEthAddressTX(ctx context.Context, t *testing.T, client *kit.TestFullNode, wait *api.MsgLookup, ethAddr ethtypes.EthAddress) ethtypes.EthAddress {
|
||||
// Check if eth address returned from CreateExternal is the same as eth address predicted at the start
|
||||
var createExternalReturn eam.CreateExternalReturn
|
||||
err := createExternalReturn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return))
|
||||
txHash, err := client.EthGetTransactionHashByCid(ctx, smsg.Cid())
|
||||
require.NoError(t, err)
|
||||
|
||||
createdEthAddr, err := ethtypes.CastEthAddress(createExternalReturn.EthAddress[:])
|
||||
receipt, err := client.EVM().WaitTransaction(ctx, *txHash)
|
||||
require.NoError(t, err)
|
||||
return createdEthAddr
|
||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||
return receipt
|
||||
}
|
||||
|
||||
func TestAddressCreationBeforeDeploy(t *testing.T) {
|
||||
@ -112,11 +101,11 @@ func TestAddressCreationBeforeDeploy(t *testing.T) {
|
||||
require.True(t, builtin.IsPlaceholderActor(actor.Code))
|
||||
|
||||
// Create and deploy evm actor
|
||||
wait := createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
receipt := createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
|
||||
// Check if eth address returned from CreateExternal is the same as eth address predicted at the start
|
||||
createdEthAddr := getEthAddressTX(ctx, t, client, wait, ethAddr)
|
||||
require.Equal(t, ethAddr, createdEthAddr)
|
||||
// Check if eth address returned from CreateExternal is the same as eth address predicted at
|
||||
// the start
|
||||
require.Equal(t, ðAddr, receipt.ContractAddress)
|
||||
|
||||
// Check if newly deployed actor still has funds
|
||||
actorPostCreate, err := client.StateGetActor(ctx, contractFilAddr, types.EmptyTSK)
|
||||
@ -158,11 +147,11 @@ func TestDeployAddressMultipleTimes(t *testing.T) {
|
||||
require.True(t, builtin.IsPlaceholderActor(actor.Code))
|
||||
|
||||
// Create and deploy evm actor
|
||||
wait := createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
receipt := createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
|
||||
// Check if eth address returned from CreateExternal is the same as eth address predicted at the start
|
||||
createdEthAddr := getEthAddressTX(ctx, t, client, wait, ethAddr)
|
||||
require.Equal(t, ethAddr, createdEthAddr)
|
||||
// Check if eth address returned from CreateExternal is the same as eth address predicted at
|
||||
// the start
|
||||
require.Equal(t, ðAddr, receipt.ContractAddress)
|
||||
|
||||
// Check if newly deployed actor still has funds
|
||||
actorPostCreate, err := client.StateGetActor(ctx, contractFilAddr, types.EmptyTSK)
|
||||
@ -171,10 +160,9 @@ func TestDeployAddressMultipleTimes(t *testing.T) {
|
||||
require.True(t, builtin.IsEvmActor(actorPostCreate.Code))
|
||||
|
||||
// Create and deploy evm actor
|
||||
wait = createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
receipt = createAndDeploy(ctx, t, client, fromAddr, contract)
|
||||
|
||||
// Check that this time eth address returned from CreateExternal is not the same as eth address predicted at the start
|
||||
createdEthAddr = getEthAddressTX(ctx, t, client, wait, ethAddr)
|
||||
require.NotEqual(t, ethAddr, createdEthAddr)
|
||||
require.NotEqual(t, ðAddr, receipt.ContractAddress)
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
amt4 "github.com/filecoin-project/go-amt-ipld/v4"
|
||||
@ -291,6 +292,17 @@ func (e *EVM) InvokeContractByFuncNameExpectExit(ctx context.Context, fromAddr a
|
||||
require.Equal(e.t, exit, wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
func (e *EVM) WaitTransaction(ctx context.Context, hash ethtypes.EthHash) (*api.EthTxReceipt, error) {
|
||||
if mcid, err := e.EthGetMessageCidByTransactionHash(ctx, &hash); err != nil {
|
||||
return nil, err
|
||||
} else if mcid == nil {
|
||||
return nil, xerrors.Errorf("couldn't find message CID for txn hash: %s", hash)
|
||||
} else {
|
||||
e.WaitMsg(ctx, *mcid)
|
||||
return e.EthGetTransactionReceipt(ctx, hash)
|
||||
}
|
||||
}
|
||||
|
||||
// function signatures are the first 4 bytes of the hash of the function name and types
|
||||
func CalcFuncSignature(funcName string) []byte {
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
|
@ -848,7 +848,7 @@ var GatewayNodeViews = append([]*view.View{
|
||||
|
||||
// SinceInMilliseconds returns the duration of time since the provide time as a float64.
|
||||
func SinceInMilliseconds(startTime time.Time) float64 {
|
||||
return float64(time.Since(startTime).Nanoseconds()) / 1e6
|
||||
return float64(time.Since(startTime).Milliseconds())
|
||||
}
|
||||
|
||||
// Timer is a function stopwatch, calling it starts the timer,
|
||||
|
@ -285,9 +285,20 @@ func (a *EthModule) EthGetTransactionByHashLimited(ctx context.Context, txHash *
|
||||
|
||||
for _, p := range pending {
|
||||
if p.Cid() == c {
|
||||
tx, err := newEthTxFromSignedMessage(ctx, p, a.StateAPI)
|
||||
// We only return pending eth-account messages because we can't guarantee
|
||||
// that the from/to addresses of other messages are conversable to 0x-style
|
||||
// addresses. So we just ignore them.
|
||||
//
|
||||
// This should be "fine" as anyone using an "Ethereum-centric" block
|
||||
// explorer shouldn't care about seeing pending messages from native
|
||||
// accounts.
|
||||
tx, err := ethtypes.EthTxFromSignedEthMessage(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not convert Filecoin message into tx: %s", err)
|
||||
return nil, fmt.Errorf("could not convert Filecoin message into tx: %w", err)
|
||||
}
|
||||
tx.Hash, err = tx.TxHash()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not compute tx hash for eth txn: %w", err)
|
||||
}
|
||||
return &tx, nil
|
||||
}
|
||||
@ -718,7 +729,7 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
|
||||
)
|
||||
|
||||
for blocksIncluded < int(params.BlkCount) && ts.Height() > 0 {
|
||||
msgs, rcpts, err := messagesAndReceipts(ctx, ts, a.Chain, a.StateAPI)
|
||||
_, msgs, rcpts, err := executeTipset(ctx, ts, a.Chain, a.StateAPI)
|
||||
if err != nil {
|
||||
return ethtypes.EthFeeHistory{}, xerrors.Errorf("failed to retrieve messages and receipts for height %d: %w", ts.Height(), err)
|
||||
}
|
||||
@ -837,19 +848,14 @@ func (a *EthModule) EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtyp
|
||||
return nil, xerrors.Errorf("failed to get tipset: %w", err)
|
||||
}
|
||||
|
||||
_, trace, err := a.StateManager.ExecutionTrace(ctx, ts)
|
||||
stRoot, trace, err := a.StateManager.ExecutionTrace(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed when calling ExecutionTrace: %w", err)
|
||||
}
|
||||
|
||||
tsParent, err := a.ChainAPI.ChainGetTipSetByHeight(ctx, ts.Height()+1, a.Chain.GetHeaviestTipSet().Key())
|
||||
st, err := a.StateManager.StateTree(stRoot)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("cannot get tipset at height: %v", ts.Height()+1)
|
||||
}
|
||||
|
||||
msgs, err := a.ChainGetParentMessages(ctx, tsParent.Blocks()[0].Cid())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get parent messages: %w", err)
|
||||
return nil, xerrors.Errorf("failed load computed state-tree: %w", err)
|
||||
}
|
||||
|
||||
cid, err := ts.Key().Cid()
|
||||
@ -870,11 +876,6 @@ func (a *EthModule) EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtyp
|
||||
continue
|
||||
}
|
||||
|
||||
// as we include TransactionPosition in the results, lets do sanity checking that the
|
||||
// traces are indeed in the message execution order
|
||||
if ir.Msg.Cid() != msgs[msgIdx].Message.Cid() {
|
||||
return nil, xerrors.Errorf("traces are not in message execution order")
|
||||
}
|
||||
msgIdx++
|
||||
|
||||
txHash, err := a.EthGetTransactionHashByCid(ctx, ir.MsgCid)
|
||||
@ -887,7 +888,7 @@ func (a *EthModule) EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtyp
|
||||
}
|
||||
|
||||
traces := []*ethtypes.EthTrace{}
|
||||
err = buildTraces(ctx, &traces, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), a.StateAPI)
|
||||
err = buildTraces(&traces, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), st)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed building traces: %w", err)
|
||||
}
|
||||
@ -919,11 +920,16 @@ func (a *EthModule) EthTraceReplayBlockTransactions(ctx context.Context, blkNum
|
||||
return nil, xerrors.Errorf("failed to get tipset: %w", err)
|
||||
}
|
||||
|
||||
_, trace, err := a.StateManager.ExecutionTrace(ctx, ts)
|
||||
stRoot, trace, err := a.StateManager.ExecutionTrace(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed when calling ExecutionTrace: %w", err)
|
||||
}
|
||||
|
||||
st, err := a.StateManager.StateTree(stRoot)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed load computed state-tree: %w", err)
|
||||
}
|
||||
|
||||
allTraces := make([]*ethtypes.EthTraceReplayBlockTransaction, 0, len(trace))
|
||||
for _, ir := range trace {
|
||||
// ignore messages from system actor
|
||||
@ -958,7 +964,7 @@ func (a *EthModule) EthTraceReplayBlockTransactions(ctx context.Context, blkNum
|
||||
VmTrace: nil,
|
||||
}
|
||||
|
||||
err = buildTraces(ctx, &t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), a.StateAPI)
|
||||
err = buildTraces(&t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), st)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed building traces: %w", err)
|
||||
}
|
||||
@ -1199,7 +1205,7 @@ func (e *EthEvent) EthGetLogs(ctx context.Context, filterSpec *ethtypes.EthFilte
|
||||
|
||||
_ = e.uninstallFilter(ctx, f)
|
||||
|
||||
return ethFilterResultFromEvents(ces, e.SubManager.StateAPI)
|
||||
return ethFilterResultFromEvents(ctx, ces, e.SubManager.StateAPI)
|
||||
}
|
||||
|
||||
func (e *EthEvent) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
|
||||
@ -1214,11 +1220,11 @@ func (e *EthEvent) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilte
|
||||
|
||||
switch fc := f.(type) {
|
||||
case filterEventCollector:
|
||||
return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.SubManager.StateAPI)
|
||||
return ethFilterResultFromEvents(ctx, fc.TakeCollectedEvents(ctx), e.SubManager.StateAPI)
|
||||
case filterTipSetCollector:
|
||||
return ethFilterResultFromTipSets(fc.TakeCollectedTipSets(ctx))
|
||||
case filterMessageCollector:
|
||||
return ethFilterResultFromMessages(fc.TakeCollectedMessages(ctx), e.SubManager.StateAPI)
|
||||
return ethFilterResultFromMessages(fc.TakeCollectedMessages(ctx))
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("unknown filter type")
|
||||
@ -1236,7 +1242,7 @@ func (e *EthEvent) EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID
|
||||
|
||||
switch fc := f.(type) {
|
||||
case filterEventCollector:
|
||||
return ethFilterResultFromEvents(fc.TakeCollectedEvents(ctx), e.SubManager.StateAPI)
|
||||
return ethFilterResultFromEvents(ctx, fc.TakeCollectedEvents(ctx), e.SubManager.StateAPI)
|
||||
}
|
||||
|
||||
return nil, xerrors.Errorf("wrong filter type")
|
||||
|
@ -93,7 +93,7 @@ func ethLogFromEvent(entries []types.EventEntry) (data []byte, topics []ethtypes
|
||||
return data, topics, true
|
||||
}
|
||||
|
||||
func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*ethtypes.EthFilterResult, error) {
|
||||
func ethFilterResultFromEvents(ctx context.Context, evs []*filter.CollectedEvent, sa StateAPI) (*ethtypes.EthFilterResult, error) {
|
||||
res := ðtypes.EthFilterResult{}
|
||||
for _, ev := range evs {
|
||||
log := ethtypes.EthLog{
|
||||
@ -117,7 +117,7 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.TransactionHash, err = ethTxHashFromMessageCid(context.TODO(), ev.MsgCid, sa)
|
||||
log.TransactionHash, err = ethTxHashFromMessageCid(ctx, ev.MsgCid, sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -155,11 +155,11 @@ func ethFilterResultFromTipSets(tsks []types.TipSetKey) (*ethtypes.EthFilterResu
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func ethFilterResultFromMessages(cs []*types.SignedMessage, sa StateAPI) (*ethtypes.EthFilterResult, error) {
|
||||
func ethFilterResultFromMessages(cs []*types.SignedMessage) (*ethtypes.EthFilterResult, error) {
|
||||
res := ðtypes.EthFilterResult{}
|
||||
|
||||
for _, c := range cs {
|
||||
hash, err := ethTxHashFromSignedMessage(context.TODO(), c, sa)
|
||||
hash, err := ethTxHashFromSignedMessage(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -321,14 +321,14 @@ func (e *ethSubscription) send(ctx context.Context, v interface{}) {
|
||||
}
|
||||
|
||||
func (e *ethSubscription) start(ctx context.Context) {
|
||||
for {
|
||||
for ctx.Err() == nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case v := <-e.in:
|
||||
switch vt := v.(type) {
|
||||
case *filter.CollectedEvent:
|
||||
evs, err := ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI)
|
||||
evs, err := ethFilterResultFromEvents(ctx, []*filter.CollectedEvent{vt}, e.StateAPI)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@ -344,7 +344,7 @@ func (e *ethSubscription) start(ctx context.Context) {
|
||||
|
||||
e.send(ctx, ev)
|
||||
case *types.SignedMessage: // mpool txid
|
||||
evs, err := ethFilterResultFromMessages([]*types.SignedMessage{vt}, e.StateAPI)
|
||||
evs, err := ethFilterResultFromMessages([]*types.SignedMessage{vt})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package full
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"github.com/multiformats/go-multicodec"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -12,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/evm"
|
||||
|
||||
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
)
|
||||
@ -39,18 +39,18 @@ func decodePayload(payload []byte, codec uint64) (ethtypes.EthBytes, error) {
|
||||
}
|
||||
|
||||
// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls
|
||||
func buildTraces(ctx context.Context, traces *[]*ethtypes.EthTrace, parent *ethtypes.EthTrace, addr []int, et types.ExecutionTrace, height int64, sa StateAPI) error {
|
||||
func buildTraces(traces *[]*ethtypes.EthTrace, parent *ethtypes.EthTrace, addr []int, et types.ExecutionTrace, height int64, st *state.StateTree) error {
|
||||
// lookup the eth address from the from/to addresses. Note that this may fail but to support
|
||||
// this we need to include the ActorID in the trace. For now, just log a warning and skip
|
||||
// this trace.
|
||||
//
|
||||
// TODO: Add ActorID in trace, see https://github.com/filecoin-project/lotus/pull/11100#discussion_r1302442288
|
||||
from, err := lookupEthAddress(ctx, et.Msg.From, sa)
|
||||
from, err := lookupEthAddress(et.Msg.From, st)
|
||||
if err != nil {
|
||||
log.Warnf("buildTraces: failed to lookup from address %s: %v", et.Msg.From, err)
|
||||
return nil
|
||||
}
|
||||
to, err := lookupEthAddress(ctx, et.Msg.To, sa)
|
||||
to, err := lookupEthAddress(et.Msg.To, st)
|
||||
if err != nil {
|
||||
log.Warnf("buildTraces: failed to lookup to address %s: %w", et.Msg.To, err)
|
||||
return nil
|
||||
@ -239,7 +239,7 @@ func buildTraces(ctx context.Context, traces *[]*ethtypes.EthTrace, parent *etht
|
||||
*traces = append(*traces, trace)
|
||||
|
||||
for i, call := range et.Subcalls {
|
||||
err := buildTraces(ctx, traces, trace, append(addr, i), call, height, sa)
|
||||
err := buildTraces(traces, trace, append(addr, i), call, height, st)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multicodec"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@ -21,6 +22,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/state"
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
@ -190,7 +192,8 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
||||
|
||||
bn := ethtypes.EthUint64(ts.Height())
|
||||
|
||||
blkCid, err := ts.Key().Cid()
|
||||
tsk := ts.Key()
|
||||
blkCid, err := tsk.Cid()
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, err
|
||||
}
|
||||
@ -199,11 +202,16 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
||||
return ethtypes.EthBlock{}, err
|
||||
}
|
||||
|
||||
msgs, rcpts, err := messagesAndReceipts(ctx, ts, cs, sa)
|
||||
stRoot, msgs, rcpts, err := executeTipset(ctx, ts, cs, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to retrieve messages and receipts: %w", err)
|
||||
}
|
||||
|
||||
st, err := sa.StateManager.StateTree(stRoot)
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to load state-tree root %q: %w", stRoot, err)
|
||||
}
|
||||
|
||||
block := ethtypes.NewEthBlock(len(msgs) > 0)
|
||||
|
||||
gasUsed := int64(0)
|
||||
@ -225,7 +233,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
||||
default:
|
||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to get signed msg %s: %w", msg.Cid(), err)
|
||||
}
|
||||
tx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
|
||||
tx, err := newEthTxFromSignedMessage(smsg, st)
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to convert msg to ethTx: %w", err)
|
||||
}
|
||||
@ -251,27 +259,27 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
||||
return block, nil
|
||||
}
|
||||
|
||||
func messagesAndReceipts(ctx context.Context, ts *types.TipSet, cs *store.ChainStore, sa StateAPI) ([]types.ChainMsg, []types.MessageReceipt, error) {
|
||||
func executeTipset(ctx context.Context, ts *types.TipSet, cs *store.ChainStore, sa StateAPI) (cid.Cid, []types.ChainMsg, []types.MessageReceipt, error) {
|
||||
msgs, err := cs.MessagesForTipset(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err)
|
||||
return cid.Undef, nil, nil, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err)
|
||||
}
|
||||
|
||||
_, rcptRoot, err := sa.StateManager.TipSetState(ctx, ts)
|
||||
stRoot, rcptRoot, err := sa.StateManager.TipSetState(ctx, ts)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("failed to compute state: %w", err)
|
||||
return cid.Undef, nil, nil, xerrors.Errorf("failed to compute state: %w", err)
|
||||
}
|
||||
|
||||
rcpts, err := cs.ReadReceipts(ctx, rcptRoot)
|
||||
if err != nil {
|
||||
return nil, nil, xerrors.Errorf("error loading receipts for tipset: %v: %w", ts, err)
|
||||
return cid.Undef, nil, nil, xerrors.Errorf("error loading receipts for tipset: %v: %w", ts, err)
|
||||
}
|
||||
|
||||
if len(msgs) != len(rcpts) {
|
||||
return nil, nil, xerrors.Errorf("receipts and message array lengths didn't match for tipset: %v: %w", ts, err)
|
||||
return cid.Undef, nil, nil, xerrors.Errorf("receipts and message array lengths didn't match for tipset: %v: %w", ts, err)
|
||||
}
|
||||
|
||||
return msgs, rcpts, nil
|
||||
return stRoot, msgs, rcpts, nil
|
||||
}
|
||||
|
||||
const errorFunctionSelector = "\x08\xc3\x79\xa0" // Error(string)
|
||||
@ -361,7 +369,7 @@ func parseEthRevert(ret []byte) string {
|
||||
// 3. Otherwise, we fall back to returning a masked ID Ethereum address. If the supplied address is an f0 address, we
|
||||
// use that ID to form the masked ID address.
|
||||
// 4. Otherwise, we fetch the actor's ID from the state tree and form the masked ID with it.
|
||||
func lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (ethtypes.EthAddress, error) {
|
||||
func lookupEthAddress(addr address.Address, st *state.StateTree) (ethtypes.EthAddress, error) {
|
||||
// BLOCK A: We are trying to get an actual Ethereum address from an f410 address.
|
||||
// Attempt to convert directly, if it's an f4 address.
|
||||
ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr)
|
||||
@ -370,7 +378,7 @@ func lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (e
|
||||
}
|
||||
|
||||
// Lookup on the target actor and try to get an f410 address.
|
||||
if actor, err := sa.StateGetActor(ctx, addr, types.EmptyTSK); err != nil {
|
||||
if actor, err := st.GetActor(addr); err != nil {
|
||||
return ethtypes.EthAddress{}, err
|
||||
} else if actor.Address != nil {
|
||||
if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() {
|
||||
@ -385,7 +393,7 @@ func lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (e
|
||||
}
|
||||
|
||||
// Otherwise, resolve the ID addr.
|
||||
idAddr, err := sa.StateLookupID(ctx, addr, types.EmptyTSK)
|
||||
idAddr, err := st.LookupID(addr)
|
||||
if err != nil {
|
||||
return ethtypes.EthAddress{}, err
|
||||
}
|
||||
@ -412,7 +420,7 @@ func ethTxHashFromMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethty
|
||||
smsg, err := sa.Chain.GetSignedMessage(ctx, c)
|
||||
if err == nil {
|
||||
// This is an Eth Tx, Secp message, Or BLS message in the mpool
|
||||
return ethTxHashFromSignedMessage(ctx, smsg, sa)
|
||||
return ethTxHashFromSignedMessage(smsg)
|
||||
}
|
||||
|
||||
_, err = sa.Chain.GetMessage(ctx, c)
|
||||
@ -424,13 +432,14 @@ func ethTxHashFromMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethty
|
||||
return ethtypes.EmptyEthHash, nil
|
||||
}
|
||||
|
||||
func ethTxHashFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthHash, error) {
|
||||
func ethTxHashFromSignedMessage(smsg *types.SignedMessage) (ethtypes.EthHash, error) {
|
||||
if smsg.Signature.Type == crypto.SigTypeDelegated {
|
||||
ethTx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
|
||||
tx, err := ethtypes.EthTxFromSignedEthMessage(smsg)
|
||||
if err != nil {
|
||||
return ethtypes.EmptyEthHash, err
|
||||
return ethtypes.EthHash{}, xerrors.Errorf("failed to convert from signed message: %w", err)
|
||||
}
|
||||
return ethTx.Hash, nil
|
||||
|
||||
return tx.TxHash()
|
||||
} else if smsg.Signature.Type == crypto.SigTypeSecp256k1 {
|
||||
return ethtypes.EthHashFromCid(smsg.Cid())
|
||||
} else { // BLS message
|
||||
@ -438,7 +447,7 @@ func ethTxHashFromSignedMessage(ctx context.Context, smsg *types.SignedMessage,
|
||||
}
|
||||
}
|
||||
|
||||
func newEthTxFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthTx, error) {
|
||||
func newEthTxFromSignedMessage(smsg *types.SignedMessage, st *state.StateTree) (ethtypes.EthTx, error) {
|
||||
var tx ethtypes.EthTx
|
||||
var err error
|
||||
|
||||
@ -453,42 +462,72 @@ func newEthTxFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, s
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to calculate hash for ethTx: %w", err)
|
||||
}
|
||||
|
||||
fromAddr, err := lookupEthAddress(ctx, smsg.Message.From, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||
}
|
||||
|
||||
tx.From = fromAddr
|
||||
} else if smsg.Signature.Type == crypto.SigTypeSecp256k1 { // Secp Filecoin Message
|
||||
tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), sa)
|
||||
tx = ethTxFromNativeMessage(smsg.VMMessage(), st)
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Cid())
|
||||
if err != nil {
|
||||
return tx, err
|
||||
return ethtypes.EthTx{}, err
|
||||
}
|
||||
} else { // BLS Filecoin message
|
||||
tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), sa)
|
||||
tx = ethTxFromNativeMessage(smsg.VMMessage(), st)
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Message.Cid())
|
||||
if err != nil {
|
||||
return tx, err
|
||||
return ethtypes.EthTx{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// Convert a native message to an eth transaction.
|
||||
//
|
||||
// - The state-tree must be from after the message was applied (ideally the following tipset).
|
||||
//
|
||||
// ethTxFromNativeMessage does NOT populate:
|
||||
// - BlockHash
|
||||
// - BlockNumber
|
||||
// - TransactionIndex
|
||||
// - Hash
|
||||
func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, sa StateAPI) ethtypes.EthTx {
|
||||
func ethTxFromNativeMessage(msg *types.Message, st *state.StateTree) ethtypes.EthTx {
|
||||
// We don't care if we error here, conversion is best effort for non-eth transactions
|
||||
from, _ := lookupEthAddress(ctx, msg.From, sa)
|
||||
to, _ := lookupEthAddress(ctx, msg.To, sa)
|
||||
from, _ := lookupEthAddress(msg.From, st)
|
||||
to, _ := lookupEthAddress(msg.To, st)
|
||||
toPtr := &to
|
||||
|
||||
// Convert the input parameters to "solidity ABI".
|
||||
|
||||
// For empty, we use "0" as the codec. Otherwise, we use CBOR for message
|
||||
// parameters.
|
||||
var codec uint64
|
||||
if len(msg.Params) > 0 {
|
||||
codec = uint64(multicodec.Cbor)
|
||||
}
|
||||
|
||||
// We try to decode the input as an EVM method invocation and/or a contract creation. If
|
||||
// that fails, we encode the "native" parameters as Solidity ABI.
|
||||
var input []byte
|
||||
switch msg.Method {
|
||||
case builtintypes.MethodsEVM.InvokeContract, builtintypes.MethodsEAM.CreateExternal:
|
||||
inp, err := decodePayload(msg.Params, codec)
|
||||
if err == nil {
|
||||
// If this is a valid "create external", unset the "to" address.
|
||||
if msg.Method == builtintypes.MethodsEAM.CreateExternal {
|
||||
toPtr = nil
|
||||
}
|
||||
input = []byte(inp)
|
||||
break
|
||||
}
|
||||
// Yeah, we're going to ignore errors here because the user can send whatever they
|
||||
// want and may send garbage.
|
||||
fallthrough
|
||||
default:
|
||||
input = encodeFilecoinParamsAsABI(msg.Method, codec, msg.Params)
|
||||
}
|
||||
|
||||
return ethtypes.EthTx{
|
||||
To: &to,
|
||||
To: toPtr,
|
||||
From: from,
|
||||
Input: input,
|
||||
Nonce: ethtypes.EthUint64(msg.Nonce),
|
||||
ChainID: ethtypes.EthUint64(build.Eip155ChainId),
|
||||
Value: ethtypes.EthBigInt(msg.Value),
|
||||
@ -566,7 +605,12 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *api.MsgLookup, tx
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to get signed msg: %w", err)
|
||||
}
|
||||
|
||||
tx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
|
||||
st, err := sa.StateManager.StateTree(ts.ParentState())
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to load message state tree: %w", err)
|
||||
}
|
||||
|
||||
tx, err := newEthTxFromSignedMessage(smsg, st)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, err
|
||||
}
|
||||
@ -576,7 +620,6 @@ func newEthTxFromMessageLookup(ctx context.Context, msgLookup *api.MsgLookup, tx
|
||||
ti = ethtypes.EthUint64(txIdx)
|
||||
)
|
||||
|
||||
tx.ChainID = ethtypes.EthUint64(build.Eip155ChainId)
|
||||
tx.BlockHash = &blkHash
|
||||
tx.BlockNumber = &bn
|
||||
tx.TransactionIndex = &ti
|
||||
@ -629,6 +672,11 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", lookup.TipSet, err)
|
||||
}
|
||||
|
||||
st, err := sa.StateManager.StateTree(ts.ParentState())
|
||||
if err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to load the state %s when constructing the eth txn receipt: %w", ts.ParentState(), err)
|
||||
}
|
||||
|
||||
// The tx is located in the parent tipset
|
||||
parentTs, err := cs.LoadTipSet(ctx, ts.Parents())
|
||||
if err != nil {
|
||||
@ -684,7 +732,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to create ID address: %w", err)
|
||||
}
|
||||
|
||||
l.Address, err = lookupEthAddress(ctx, addr, sa)
|
||||
l.Address, err = lookupEthAddress(addr, st)
|
||||
if err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/ethhashlookup"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
)
|
||||
|
||||
type EthTxHashManager struct {
|
||||
@ -64,7 +65,7 @@ func (m *EthTxHashManager) Apply(ctx context.Context, from, to *types.TipSet) er
|
||||
continue
|
||||
}
|
||||
|
||||
hash, err := ethTxHashFromSignedMessage(ctx, smsg, m.StateAPI)
|
||||
hash, err := ethTxHashFromSignedMessage(smsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -84,13 +85,18 @@ func (m *EthTxHashManager) ProcessSignedMessage(ctx context.Context, msg *types.
|
||||
return
|
||||
}
|
||||
|
||||
ethTx, err := newEthTxFromSignedMessage(ctx, msg, m.StateAPI)
|
||||
ethTx, err := ethtypes.EthTxFromSignedEthMessage(msg)
|
||||
if err != nil {
|
||||
log.Errorf("error converting filecoin message to eth tx: %s", err)
|
||||
return
|
||||
}
|
||||
txHash, err := ethTx.TxHash()
|
||||
if err != nil {
|
||||
log.Errorf("error hashing transaction: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = m.TransactionHashLookup.UpsertHash(ethTx.Hash, msg.Cid())
|
||||
err = m.TransactionHashLookup.UpsertHash(txHash, msg.Cid())
|
||||
if err != nil {
|
||||
log.Errorf("error inserting tx mapping to db: %s", err)
|
||||
return
|
||||
|
@ -339,19 +339,9 @@ func (sm *StorageMinerAPI) SectorsListInStates(ctx context.Context, states []api
|
||||
return sns, nil
|
||||
}
|
||||
|
||||
// Use SectorsSummary from stats (prometheus) for faster result
|
||||
func (sm *StorageMinerAPI) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) {
|
||||
sectors, err := sm.Miner.ListSectors()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := make(map[api.SectorState]int)
|
||||
for i := range sectors {
|
||||
state := api.SectorState(sectors[i].State)
|
||||
out[state]++
|
||||
}
|
||||
|
||||
return out, nil
|
||||
return sm.Miner.SectorsSummary(ctx), nil
|
||||
}
|
||||
|
||||
func (sm *StorageMinerAPI) StorageLocal(ctx context.Context) (map[storiface.ID]string, error) {
|
||||
|
53
scripts/supraseal-pc2.sh
Executable file
53
scripts/supraseal-pc2.sh
Executable file
@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
#set -o xtrace
|
||||
|
||||
# By default compile for 512MiB and 32GiB sectors only, use `-r` to compile for
|
||||
# other sector test sector sizes as well.
|
||||
SECTOR_SIZE=""
|
||||
while getopts r flag
|
||||
do
|
||||
case "${flag}" in
|
||||
r) SECTOR_SIZE="-DRUNTIME_SECTOR_SIZE";;
|
||||
*) ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -d "supra_seal" ]; then
|
||||
git clone https://github.com/supranational/supra_seal.git
|
||||
fi
|
||||
|
||||
cd supra_seal
|
||||
|
||||
rm -fr obj
|
||||
mkdir -p obj
|
||||
|
||||
rm -fr bin
|
||||
mkdir -p bin
|
||||
|
||||
mkdir -p deps
|
||||
if [ ! -d "deps/sppark" ]; then
|
||||
git clone https://github.com/supranational/sppark.git deps/sppark
|
||||
fi
|
||||
if [ ! -d "deps/blst" ]; then
|
||||
git clone https://github.com/supranational/blst.git deps/blst
|
||||
(cd deps/blst
|
||||
./build.sh -march=native)
|
||||
fi
|
||||
|
||||
# Generate .h files for the Poseidon constants
|
||||
xxd -i poseidon/constants/constants_2 > obj/constants_2.h
|
||||
xxd -i poseidon/constants/constants_4 > obj/constants_4.h
|
||||
xxd -i poseidon/constants/constants_8 > obj/constants_8.h
|
||||
xxd -i poseidon/constants/constants_11 > obj/constants_11.h
|
||||
xxd -i poseidon/constants/constants_16 > obj/constants_16.h
|
||||
xxd -i poseidon/constants/constants_24 > obj/constants_24.h
|
||||
xxd -i poseidon/constants/constants_36 > obj/constants_36.h
|
||||
|
||||
nvcc ${SECTOR_SIZE} -DNO_SPDK -DSTREAMING_NODE_READER_FILES \
|
||||
-arch=sm_80 -gencode arch=compute_70,code=sm_70 -t0 \
|
||||
-std=c++17 -g -O3 -Xcompiler -march=native \
|
||||
-Xcompiler -Wall,-Wextra,-Werror \
|
||||
-Xcompiler -Wno-subobject-linkage,-Wno-unused-parameter \
|
||||
-x cu tools/pc2.cu -o bin/pc2 \
|
||||
-Iposeidon -Ideps/sppark -Ideps/sppark/util -Ideps/blst/src -L deps/blst -lblst -lconfig++
|
@ -304,6 +304,20 @@ func (m *Sealing) TerminateSector(ctx context.Context, sid abi.SectorNumber) err
|
||||
return m.sectors.Send(uint64(sid), SectorTerminate{})
|
||||
}
|
||||
|
||||
func (m *Sealing) SectorsSummary(ctx context.Context) map[api.SectorState]int {
|
||||
m.stats.lk.Lock()
|
||||
defer m.stats.lk.Unlock()
|
||||
|
||||
out := make(map[api.SectorState]int)
|
||||
|
||||
for st, count := range m.stats.byState {
|
||||
state := api.SectorState(st)
|
||||
out[state] = int(count)
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *Sealing) TerminateFlush(ctx context.Context) (*cid.Cid, error) {
|
||||
return m.terminator.Flush(ctx)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user