updating faucet url and removing secp256k1 addresses to reduce confusion
This commit is contained in:
commit
2386537dfc
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,8 +2,11 @@
|
|||||||
/lotus-storage-miner
|
/lotus-storage-miner
|
||||||
/pond
|
/pond
|
||||||
/townhall
|
/townhall
|
||||||
|
/fountain
|
||||||
/lotuspond/front/node_modules
|
/lotuspond/front/node_modules
|
||||||
/lotuspond/front/build
|
/lotuspond/front/build
|
||||||
|
/cmd/lotus-townhall/townhall/node_modules
|
||||||
|
/cmd/lotus-townhall/townhall/build
|
||||||
**/*.h
|
**/*.h
|
||||||
**/*.a
|
**/*.a
|
||||||
**/*.pc
|
**/*.pc
|
||||||
|
9
Makefile
9
Makefile
@ -76,6 +76,9 @@ build: lotus lotus-storage-miner
|
|||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
|
|
||||||
|
install:
|
||||||
|
install -C ./lotus /usr/local/bin/lotus
|
||||||
|
install -C ./lotus /usr/local/bin/lotus-storage-miner
|
||||||
|
|
||||||
benchmarks:
|
benchmarks:
|
||||||
go run github.com/whyrusleeping/bencher ./... > bench.json
|
go run github.com/whyrusleeping/bencher ./... > bench.json
|
||||||
@ -95,6 +98,12 @@ townhall:
|
|||||||
go run github.com/GeertJohan/go.rice/rice append --exec townhall -i ./cmd/lotus-townhall
|
go run github.com/GeertJohan/go.rice/rice append --exec townhall -i ./cmd/lotus-townhall
|
||||||
.PHONY: townhall
|
.PHONY: townhall
|
||||||
|
|
||||||
|
fountain:
|
||||||
|
rm -f fountain
|
||||||
|
go build -o fountain ./cmd/lotus-fountain
|
||||||
|
go run github.com/GeertJohan/go.rice/rice append --exec fountain -i ./cmd/lotus-fountain
|
||||||
|
.PHONY: fountain
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(CLEAN)
|
rm -rf $(CLEAN)
|
||||||
-$(MAKE) -C $(BLS_PATH) clean
|
-$(MAKE) -C $(BLS_PATH) clean
|
||||||
|
48
README.md
48
README.md
@ -11,8 +11,10 @@ All work is tracked via issues. An attempt at keeping an up-to-date view on rema
|
|||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
*Dependencies:*
|
We currently only provide the option to build lotus from source. Binary installation options are coming soon!
|
||||||
|
|
||||||
|
In order to run lotus, please do the following:
|
||||||
|
1. Make sure you have these dependencies installed:
|
||||||
- go (1.13 or higher)
|
- go (1.13 or higher)
|
||||||
- gcc (7.4.0 or higher)
|
- gcc (7.4.0 or higher)
|
||||||
- git
|
- git
|
||||||
@ -20,19 +22,27 @@ All work is tracked via issues. An attempt at keeping an up-to-date view on rema
|
|||||||
- jq
|
- jq
|
||||||
- pkg-config
|
- pkg-config
|
||||||
|
|
||||||
*Building:*
|
|
||||||
|
2. Clone this repo & `cd` into it
|
||||||
|
```
|
||||||
|
$ git clone https://github.com/filecoin-project/lotus.git
|
||||||
|
$ cd lotus/
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Build and install the source code
|
||||||
```
|
```
|
||||||
$ make
|
$ make
|
||||||
|
$ sudo make install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Now, you should be able to perform the commands listed below.
|
||||||
|
|
||||||
## Devnet
|
## Devnet
|
||||||
|
|
||||||
### Node setup
|
### Node setup
|
||||||
|
|
||||||
If you have run lotus before and want to remove all previous data: `rm -rf ~/.lotus ~/.lotusstorage`
|
If you have run lotus before and want to remove all previous data: `rm -rf ~/.lotus ~/.lotusstorage`
|
||||||
|
|
||||||
[You can copy `lotus` and `lotus-storage-miner` to your `$GOPATH/bin` or `$PATH`, or reference all lotus commands below from your local build directory with `./lotus`]
|
|
||||||
|
|
||||||
The following sections describe how to use the lotus CLI. Alternately you can run lotus nodes and miners using the [Pond GUI](#pond).
|
The following sections describe how to use the lotus CLI. Alternately you can run lotus nodes and miners using the [Pond GUI](#pond).
|
||||||
|
|
||||||
### Genesis & Bootstrap
|
### Genesis & Bootstrap
|
||||||
@ -58,6 +68,9 @@ You can follow sync status with:
|
|||||||
$ watch lotus sync status
|
$ watch lotus sync status
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can view the latest block height along with other network metrics at the [lotus Devnet dashboard](https://lotus-metrics.kittyhawk.wtf/d/z6FtI92Zz/chain?orgId=1&refresh=5s&kiosk).
|
||||||
|
|
||||||
|
[It may take a few minutes for the chain to finish syncing. You will see `Height: 0` until the full chain is synced and validated.]
|
||||||
|
|
||||||
### Basics
|
### Basics
|
||||||
|
|
||||||
@ -67,19 +80,15 @@ $ lotus wallet new bls
|
|||||||
t3...
|
t3...
|
||||||
```
|
```
|
||||||
|
|
||||||
Grab some funds from faucet - go to http://147.75.80.29:777/, paste the address
|
Grab some funds from faucet - go to https://lotus-faucet.kittyhawk.wtf, paste the address
|
||||||
you just created, and press Send.
|
you just created, and press Send.
|
||||||
|
|
||||||
(You can also generate a public key address using secp256k1 with
|
Check the wallet balance (balance is listed in attoFIL, where 1 attoFIL = 10^-18 FIL):
|
||||||
`lotus wallet new secp256k1`. BLS signatures use less space so will have lower fees.)
|
|
||||||
|
|
||||||
Check the wallet balance:
|
|
||||||
```sh
|
```sh
|
||||||
$ lotus wallet balance [optional address (t3...)]
|
$ lotus wallet balance [optional address (t3...)]
|
||||||
```
|
```
|
||||||
(NOTE: If you see an error like `actor not found` after executing this command,
|
|
||||||
it means that either there are no transactions to this address on chain - using
|
(NOTE: If you see an error like `actor not found` after executing this command, it means that either your node isn't fully synced or there are no transactions to this address yet on chain. If the latter, using the faucet should 'fix' this).
|
||||||
faucet should 'fix' this, or your node isn't fully synced).
|
|
||||||
|
|
||||||
### Mining
|
### Mining
|
||||||
|
|
||||||
@ -88,7 +97,7 @@ cover pledge collateral:
|
|||||||
```sh
|
```sh
|
||||||
$ lotus state pledge-collateral
|
$ lotus state pledge-collateral
|
||||||
1234
|
1234
|
||||||
$ lotus wallet balance t3...
|
$ lotus wallet balance [t3...]
|
||||||
8999
|
8999
|
||||||
```
|
```
|
||||||
(Balance must be higher than the returned pledge collateral for the next step to work)
|
(Balance must be higher than the returned pledge collateral for the next step to work)
|
||||||
@ -129,12 +138,6 @@ $ lotus-storage-miner state power <miner>
|
|||||||
$ lotus-storage-miner state sectors <miner>
|
$ lotus-storage-miner state sectors <miner>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can view a list of miners with:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
$ lotus state list-miners
|
|
||||||
```
|
|
||||||
|
|
||||||
### Stage Data
|
### Stage Data
|
||||||
|
|
||||||
Import some data:
|
Import some data:
|
||||||
@ -158,14 +161,17 @@ $ lotus client local
|
|||||||
(It is possible for a Client to make a deal with a Miner on the same lotus Node.)
|
(It is possible for a Client to make a deal with a Miner on the same lotus Node.)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
# List all miners in the system. Choose one to make a deal with.
|
||||||
|
$ lotus state list-miners
|
||||||
|
|
||||||
# List asks proposed by a miner
|
# List asks proposed by a miner
|
||||||
$ lotus client query-ask <miner>
|
$ lotus client query-ask <miner>
|
||||||
|
|
||||||
# Propose a deal with a miner
|
# Propose a deal with a miner. Price is in attoFIL/byte/block. Duration is # of blocks.
|
||||||
$ lotus client deal <Data CID> <miner> <price> <duration>
|
$ lotus client deal <Data CID> <miner> <price> <duration>
|
||||||
```
|
```
|
||||||
|
|
||||||
For example `$ lotus client deal bafkre...qvtjsi t0111 36000 12` proposes a deal to store CID `bafkre...qvtjsi` with miner `t0111` at price `36000` for a duration of `12` blocks.
|
For example `$ lotus client deal bafkre...qvtjsi t0111 36000 12` proposes a deal to store CID `bafkre...qvtjsi` with miner `t0111` at price `36000` for a duration of `12` blocks. If successful, the `client deal` command will return a deal CID.
|
||||||
|
|
||||||
### Search & Retrieval
|
### Search & Retrieval
|
||||||
|
|
||||||
|
10
api/api.go
10
api/api.go
@ -50,8 +50,7 @@ type FullNode interface {
|
|||||||
// ChainNotify returns channel with chain head updates
|
// ChainNotify returns channel with chain head updates
|
||||||
// First message is guaranteed to be of len == 1, and type == 'current'
|
// First message is guaranteed to be of len == 1, and type == 'current'
|
||||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
||||||
ChainHead(context.Context) (*types.TipSet, error) // TODO: check serialization
|
ChainHead(context.Context) (*types.TipSet, error)
|
||||||
ChainSubmitBlock(ctx context.Context, blk *types.BlockMsg) error // TODO: check serialization
|
|
||||||
ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error)
|
ChainGetRandomness(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error)
|
||||||
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
ChainGetBlock(context.Context, cid.Cid) (*types.BlockHeader, error)
|
||||||
ChainGetTipSet(context.Context, []cid.Cid) (*types.TipSet, error)
|
ChainGetTipSet(context.Context, []cid.Cid) (*types.TipSet, error)
|
||||||
@ -62,12 +61,13 @@ type FullNode interface {
|
|||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||||
ChainSetHead(context.Context, *types.TipSet) error
|
ChainSetHead(context.Context, *types.TipSet) error
|
||||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||||
|
ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error)
|
||||||
|
|
||||||
// syncer
|
// syncer
|
||||||
SyncState(context.Context) (*SyncState, error)
|
SyncState(context.Context) (*SyncState, error)
|
||||||
|
SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error
|
||||||
|
|
||||||
// messages
|
// messages
|
||||||
|
|
||||||
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
|
MpoolPending(context.Context, *types.TipSet) ([]*types.SignedMessage, error)
|
||||||
MpoolPush(context.Context, *types.SignedMessage) error // TODO: remove
|
MpoolPush(context.Context, *types.SignedMessage) error // TODO: remove
|
||||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error) // get nonce, sign, push
|
||||||
@ -150,7 +150,7 @@ type FullNode interface {
|
|||||||
type StorageMiner interface {
|
type StorageMiner interface {
|
||||||
Common
|
Common
|
||||||
|
|
||||||
ActorAddresses(context.Context) ([]address.Address, error)
|
ActorAddress(context.Context) (address.Address, error)
|
||||||
|
|
||||||
// Temp api for testing
|
// Temp api for testing
|
||||||
StoreGarbageData(context.Context) (uint64, error)
|
StoreGarbageData(context.Context) (uint64, error)
|
||||||
@ -159,7 +159,7 @@ type StorageMiner interface {
|
|||||||
SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error)
|
SectorsStatus(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error)
|
||||||
|
|
||||||
// List all staged sectors
|
// List all staged sectors
|
||||||
SectorsStagedList(context.Context) ([]sectorbuilder.StagedSectorMetadata, error)
|
SectorsList(context.Context) ([]uint64, error)
|
||||||
|
|
||||||
// Seal all staged sectors
|
// Seal all staged sectors
|
||||||
SectorsStagedSeal(context.Context) error
|
SectorsStagedSeal(context.Context) error
|
||||||
|
@ -38,7 +38,6 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
|
ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"`
|
||||||
ChainSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
|
||||||
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
ChainGetRandomness func(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error) `perm:"read"`
|
ChainGetRandomness func(context.Context, *types.TipSet, []*types.Ticket, int) ([]byte, error) `perm:"read"`
|
||||||
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||||
@ -50,8 +49,10 @@ type FullNodeStruct struct {
|
|||||||
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"`
|
||||||
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"`
|
||||||
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"`
|
||||||
|
ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"`
|
||||||
|
|
||||||
SyncState func(context.Context) (*SyncState, error) `perm:"read"`
|
SyncState func(context.Context) (*SyncState, error) `perm:"read"`
|
||||||
|
SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"`
|
||||||
|
|
||||||
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
MpoolPending func(context.Context, *types.TipSet) ([]*types.SignedMessage, error) `perm:"read"`
|
||||||
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
MpoolPush func(context.Context, *types.SignedMessage) error `perm:"write"`
|
||||||
@ -118,12 +119,12 @@ type StorageMinerStruct struct {
|
|||||||
CommonStruct
|
CommonStruct
|
||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
ActorAddresses func(context.Context) ([]address.Address, error) `perm:"read"`
|
ActorAddress func(context.Context) (address.Address, error) `perm:"read"`
|
||||||
|
|
||||||
StoreGarbageData func(context.Context) (uint64, error) `perm:"write"`
|
StoreGarbageData func(context.Context) (uint64, error) `perm:"write"`
|
||||||
|
|
||||||
SectorsStatus func(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) `perm:"read"`
|
SectorsStatus func(context.Context, uint64) (sectorbuilder.SectorSealingStatus, error) `perm:"read"`
|
||||||
SectorsStagedList func(context.Context) ([]sectorbuilder.StagedSectorMetadata, error) `perm:"read"`
|
SectorsList func(context.Context) ([]uint64, error) `perm:"read"`
|
||||||
SectorsStagedSeal func(context.Context) error `perm:"write"`
|
SectorsStagedSeal func(context.Context) error `perm:"write"`
|
||||||
|
|
||||||
SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"`
|
SectorsRefs func(context.Context) (map[string][]SealedRef, error) `perm:"read"`
|
||||||
@ -228,10 +229,6 @@ func (c *FullNodeStruct) MinerCreateBlock(ctx context.Context, addr address.Addr
|
|||||||
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs, ts)
|
return c.Internal.MinerCreateBlock(ctx, addr, base, tickets, eproof, msgs, ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainSubmitBlock(ctx context.Context, blk *types.BlockMsg) error {
|
|
||||||
return c.Internal.ChainSubmitBlock(ctx, blk)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
func (c *FullNodeStruct) ChainHead(ctx context.Context) (*types.TipSet, error) {
|
||||||
return c.Internal.ChainHead(ctx)
|
return c.Internal.ChainHead(ctx)
|
||||||
}
|
}
|
||||||
@ -320,10 +317,18 @@ func (c *FullNodeStruct) ChainGetGenesis(ctx context.Context) (*types.TipSet, er
|
|||||||
return c.Internal.ChainGetGenesis(ctx)
|
return c.Internal.ChainGetGenesis(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||||
|
return c.Internal.ChainTipSetWeight(ctx, ts)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) SyncState(ctx context.Context) (*SyncState, error) {
|
func (c *FullNodeStruct) SyncState(ctx context.Context) (*SyncState, error) {
|
||||||
return c.Internal.SyncState(ctx)
|
return c.Internal.SyncState(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *FullNodeStruct) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error {
|
||||||
|
return c.Internal.SyncSubmitBlock(ctx, blk)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address) ([]*SectorInfo, error) {
|
func (c *FullNodeStruct) StateMinerSectors(ctx context.Context, addr address.Address) ([]*SectorInfo, error) {
|
||||||
return c.Internal.StateMinerSectors(ctx, addr)
|
return c.Internal.StateMinerSectors(ctx, addr)
|
||||||
}
|
}
|
||||||
@ -426,8 +431,8 @@ func (c *FullNodeStruct) PaychVoucherSubmit(ctx context.Context, ch address.Addr
|
|||||||
return c.Internal.PaychVoucherSubmit(ctx, ch, sv)
|
return c.Internal.PaychVoucherSubmit(ctx, ch, sv)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) ActorAddresses(ctx context.Context) ([]address.Address, error) {
|
func (c *StorageMinerStruct) ActorAddress(ctx context.Context) (address.Address, error) {
|
||||||
return c.Internal.ActorAddresses(ctx)
|
return c.Internal.ActorAddress(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) StoreGarbageData(ctx context.Context) (uint64, error) {
|
func (c *StorageMinerStruct) StoreGarbageData(ctx context.Context) (uint64, error) {
|
||||||
@ -440,8 +445,8 @@ func (c *StorageMinerStruct) SectorsStatus(ctx context.Context, sid uint64) (sec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List all staged sectors
|
// List all staged sectors
|
||||||
func (c *StorageMinerStruct) SectorsStagedList(ctx context.Context) ([]sectorbuilder.StagedSectorMetadata, error) {
|
func (c *StorageMinerStruct) SectorsList(ctx context.Context) ([]uint64, error) {
|
||||||
return c.Internal.SectorsStagedList(ctx)
|
return c.Internal.SectorsList(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seal all staged sectors
|
// Seal all staged sectors
|
||||||
|
@ -1 +1 @@
|
|||||||
/ip4/147.75.80.17/tcp/1347/p2p/12D3KooWJdB9SxJfUb327CsBMCyEqzkDCHaqcrwaHGZ88wUuoc5F
|
/ip4/147.75.80.17/tcp/1347/p2p/12D3KooWB54edC5VTSaQpvcYbqG8XKAziP77Natf75CieA5xKDJx
|
||||||
|
@ -1 +1 @@
|
|||||||
/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWAShT7qd3oM7QPC8AsQffs6ThH69fZGui4xCW68E35rDP
|
/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWGdsbvHwscFKT1kqBeeooPe6EneJvjXzTrWSzwKhc1ssn
|
||||||
|
Binary file not shown.
@ -38,6 +38,9 @@ const AllowableClockDrift = BlockDelay * 2
|
|||||||
// Blocks
|
// Blocks
|
||||||
const ForkLengthThreshold = 100
|
const ForkLengthThreshold = 100
|
||||||
|
|
||||||
|
// Blocks (e)
|
||||||
|
const BlocksPerEpoch = 1
|
||||||
|
|
||||||
// /////
|
// /////
|
||||||
// Proofs / Mining
|
// Proofs / Mining
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ func (sma StorageMinerActor) StorageMinerConstructor(act *types.Actor, vmctx typ
|
|||||||
sectors := amt.NewAMT(types.WrapStorage(vmctx.Storage()))
|
sectors := amt.NewAMT(types.WrapStorage(vmctx.Storage()))
|
||||||
scid, serr := sectors.Flush()
|
scid, serr := sectors.Flush()
|
||||||
if serr != nil {
|
if serr != nil {
|
||||||
return nil, aerrors.Escalate(serr, "initializing AMT")
|
return nil, aerrors.HandleExternalError(serr, "initializing AMT")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.Sectors = scid
|
self.Sectors = scid
|
||||||
@ -270,7 +270,7 @@ func (sma StorageMinerActor) CommitSector(act *types.Actor, vmctx types.VMContex
|
|||||||
// time to prove than large sectors do. Sector size is selected when pledging.
|
// time to prove than large sectors do. Sector size is selected when pledging.
|
||||||
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return nil, aerrors.Escalate(lerr, "could not load proving set node")
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
}
|
}
|
||||||
|
|
||||||
if pss.Count == 0 {
|
if pss.Count == 0 {
|
||||||
@ -366,7 +366,7 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
|||||||
|
|
||||||
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
pss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return nil, aerrors.Escalate(lerr, "could not load proving set node")
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
}
|
}
|
||||||
|
|
||||||
var sectorInfos []sectorbuilder.SectorInfo
|
var sectorInfos []sectorbuilder.SectorInfo
|
||||||
@ -409,19 +409,19 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
|||||||
|
|
||||||
ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
ss, lerr := amt.LoadAMT(types.WrapStorage(vmctx.Storage()), self.ProvingSet)
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return nil, aerrors.Escalate(lerr, "could not load proving set node")
|
return nil, aerrors.HandleExternalError(lerr, "could not load proving set node")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ss.BatchDelete(params.DoneSet.All()); err != nil {
|
if err := ss.BatchDelete(params.DoneSet.All()); err != nil {
|
||||||
// TODO: this could fail for system reasons (block not found) or for
|
// TODO: this could fail for system reasons (block not found) or for
|
||||||
// bad user input reasons (e.g. bad doneset). The latter should be a
|
// bad user input reasons (e.g. bad doneset). The latter should be a
|
||||||
// non-fatal error
|
// non-fatal error
|
||||||
return nil, aerrors.Escalate(err, "failed to delete sectors in done set")
|
return nil, aerrors.HandleExternalError(err, "failed to delete sectors in done set")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ProvingSet, lerr = ss.Flush()
|
self.ProvingSet, lerr = ss.Flush()
|
||||||
if lerr != nil {
|
if lerr != nil {
|
||||||
return nil, aerrors.Escalate(lerr, "could not flush AMT")
|
return nil, aerrors.HandleExternalError(lerr, "could not flush AMT")
|
||||||
}
|
}
|
||||||
|
|
||||||
oldPower := self.Power
|
oldPower := self.Power
|
||||||
@ -433,7 +433,7 @@ func (sma StorageMinerActor) SubmitPoSt(act *types.Actor, vmctx types.VMContext,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = vmctx.Send(StorageMarketAddress, SMAMethods.UpdateStorage, types.NewInt(0), enc)
|
_, err = vmctx.Send(StorageMarketAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -474,16 +474,16 @@ func SectorIsUnique(ctx context.Context, s types.Storage, sroot cid.Cid, sid uin
|
|||||||
func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64, commR, commD []byte) (cid.Cid, ActorError) {
|
||||||
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss)
|
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "could not load sector set node")
|
return cid.Undef, aerrors.HandleExternalError(err, "could not load sector set node")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := ssr.Set(sectorID, [][]byte{commR, commD}); err != nil {
|
if err := ssr.Set(sectorID, [][]byte{commR, commD}); err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to set commitment in sector set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to set commitment in sector set")
|
||||||
}
|
}
|
||||||
|
|
||||||
ncid, err := ssr.Flush()
|
ncid, err := ssr.Flush()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to flush sector set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to flush sector set")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ncid, nil
|
return ncid, nil
|
||||||
@ -492,7 +492,7 @@ func AddToSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID u
|
|||||||
func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) {
|
func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID uint64) (bool, []byte, []byte, ActorError) {
|
||||||
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss)
|
ssr, err := amt.LoadAMT(types.WrapStorage(s), ss)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, nil, aerrors.Escalate(err, "could not load sector set node")
|
return false, nil, nil, aerrors.HandleExternalError(err, "could not load sector set node")
|
||||||
}
|
}
|
||||||
|
|
||||||
var comms [][]byte
|
var comms [][]byte
|
||||||
@ -501,11 +501,11 @@ func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID
|
|||||||
if _, ok := err.(*amt.ErrNotFound); ok {
|
if _, ok := err.(*amt.ErrNotFound); ok {
|
||||||
return false, nil, nil, nil
|
return false, nil, nil, nil
|
||||||
}
|
}
|
||||||
return false, nil, nil, aerrors.Escalate(err, "failed to find sector in sector set")
|
return false, nil, nil, aerrors.HandleExternalError(err, "failed to find sector in sector set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(comms) != 2 {
|
if len(comms) != 2 {
|
||||||
return false, nil, nil, aerrors.Escalate(xerrors.New("sector set entry should only have 2 elements"), "")
|
return false, nil, nil, aerrors.Newf(20, "sector set entry should only have 2 elements")
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, comms[0], comms[1], nil
|
return true, comms[0], comms[1], nil
|
||||||
@ -514,7 +514,7 @@ func GetFromSectorSet(ctx context.Context, s types.Storage, ss cid.Cid, sectorID
|
|||||||
func ValidatePoRep(maddr address.Address, ssize types.BigInt, params *CommitSectorParams) (bool, ActorError) {
|
func ValidatePoRep(maddr address.Address, ssize types.BigInt, params *CommitSectorParams) (bool, ActorError) {
|
||||||
ok, err := sectorbuilder.VerifySeal(ssize.Uint64(), params.CommR, params.CommD, params.CommRStar, maddr, params.SectorID, params.Proof)
|
ok, err := sectorbuilder.VerifySeal(ssize.Uint64(), params.CommR, params.CommD, params.CommRStar, maddr, params.SectorID, params.Proof)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, aerrors.Escalate(err, "verify seal failed")
|
return false, aerrors.Absorb(err, 25, "verify seal failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok, nil
|
return ok, nil
|
||||||
@ -659,11 +659,11 @@ func (sma StorageMinerActor) PaymentVerifyInclusion(act *types.Actor, vmctx type
|
|||||||
|
|
||||||
var voucherData PieceInclVoucherData
|
var voucherData PieceInclVoucherData
|
||||||
if err := cbor.DecodeInto(params.Extra, &voucherData); err != nil {
|
if err := cbor.DecodeInto(params.Extra, &voucherData); err != nil {
|
||||||
return nil, aerrors.Escalate(err, "failed to decode storage voucher data for verification")
|
return nil, aerrors.Absorb(err, 2, "failed to decode storage voucher data for verification")
|
||||||
}
|
}
|
||||||
var proof InclusionProof
|
var proof InclusionProof
|
||||||
if err := cbor.DecodeInto(params.Proof, &proof); err != nil {
|
if err := cbor.DecodeInto(params.Proof, &proof); err != nil {
|
||||||
return nil, aerrors.Escalate(err, "failed to decode storage payment proof")
|
return nil, aerrors.Absorb(err, 3, "failed to decode storage payment proof")
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, _, commD, aerr := GetFromSectorSet(context.TODO(), vmctx.Storage(), self.Sectors, proof.Sector)
|
ok, _, commD, aerr := GetFromSectorSet(context.TODO(), vmctx.Storage(), self.Sectors, proof.Sector)
|
||||||
@ -671,15 +671,15 @@ func (sma StorageMinerActor) PaymentVerifyInclusion(act *types.Actor, vmctx type
|
|||||||
return nil, aerr
|
return nil, aerr
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, aerrors.New(1, "miner does not have required sector")
|
return nil, aerrors.New(4, "miner does not have required sector")
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := sectorbuilder.VerifyPieceInclusionProof(mi.SectorSize.Uint64(), voucherData.PieceSize.Uint64(), voucherData.CommP, commD, proof.Proof)
|
ok, err := sectorbuilder.VerifyPieceInclusionProof(mi.SectorSize.Uint64(), voucherData.PieceSize.Uint64(), voucherData.CommP, commD, proof.Proof)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, aerrors.Escalate(err, "verify piece inclusion proof failed")
|
return nil, aerrors.Absorb(err, 5, "verify piece inclusion proof failed")
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, aerrors.New(2, "piece inclusion proof was invalid")
|
return nil, aerrors.New(6, "piece inclusion proof was invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -2,7 +2,6 @@ package actors
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||||
@ -16,9 +15,9 @@ import (
|
|||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageMarketActor struct{}
|
type StoragePowerActor struct{}
|
||||||
|
|
||||||
type smaMethods struct {
|
type spaMethods struct {
|
||||||
Constructor uint64
|
Constructor uint64
|
||||||
CreateStorageMiner uint64
|
CreateStorageMiner uint64
|
||||||
ArbitrateConsensusFault uint64
|
ArbitrateConsensusFault uint64
|
||||||
@ -29,22 +28,22 @@ type smaMethods struct {
|
|||||||
PledgeCollateralForSize uint64
|
PledgeCollateralForSize uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
var SMAMethods = smaMethods{1, 2, 3, 4, 5, 6, 7, 8}
|
var SPAMethods = spaMethods{1, 2, 3, 4, 5, 6, 7, 8}
|
||||||
|
|
||||||
func (sma StorageMarketActor) Exports() []interface{} {
|
func (spa StoragePowerActor) Exports() []interface{} {
|
||||||
return []interface{}{
|
return []interface{}{
|
||||||
//1: sma.StorageMarketConstructor,
|
//1: spa.StoragePowerConstructor,
|
||||||
2: sma.CreateStorageMiner,
|
2: spa.CreateStorageMiner,
|
||||||
3: sma.ArbitrateConsensusFault,
|
3: spa.ArbitrateConsensusFault,
|
||||||
4: sma.UpdateStorage,
|
4: spa.UpdateStorage,
|
||||||
5: sma.GetTotalStorage,
|
5: spa.GetTotalStorage,
|
||||||
6: sma.PowerLookup,
|
6: spa.PowerLookup,
|
||||||
7: sma.IsMiner,
|
7: spa.IsMiner,
|
||||||
8: sma.PledgeCollateralForSize,
|
8: spa.PledgeCollateralForSize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type StorageMarketState struct {
|
type StoragePowerState struct {
|
||||||
Miners cid.Cid
|
Miners cid.Cid
|
||||||
MinerCount uint64
|
MinerCount uint64
|
||||||
|
|
||||||
@ -58,12 +57,12 @@ type CreateStorageMinerParams struct {
|
|||||||
PeerID peer.ID
|
PeerID peer.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) {
|
func (spa StoragePowerActor) CreateStorageMiner(act *types.Actor, vmctx types.VMContext, params *CreateStorageMinerParams) ([]byte, ActorError) {
|
||||||
if !SupportedSectorSize(params.SectorSize) {
|
if !SupportedSectorSize(params.SectorSize) {
|
||||||
return nil, aerrors.New(1, "Unsupported sector size")
|
return nil, aerrors.New(1, "Unsupported sector size")
|
||||||
}
|
}
|
||||||
|
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
old := vmctx.Storage().GetHead()
|
old := vmctx.Storage().GetHead()
|
||||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -129,7 +128,7 @@ type ArbitrateConsensusFaultParams struct {
|
|||||||
Block2 *types.BlockHeader
|
Block2 *types.BlockHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) {
|
func (spa StoragePowerActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) {
|
||||||
if params.Block1.Miner != params.Block2.Miner {
|
if params.Block1.Miner != params.Block2.Miner {
|
||||||
return nil, aerrors.New(2, "blocks must be from the same miner")
|
return nil, aerrors.New(2, "blocks must be from the same miner")
|
||||||
}
|
}
|
||||||
@ -145,11 +144,11 @@ func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx ty
|
|||||||
return nil, aerrors.Absorb(oerr, 3, "response from 'GetWorkerAddr' was not a valid address")
|
return nil, aerrors.Absorb(oerr, 3, "response from 'GetWorkerAddr' was not a valid address")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := params.Block1.CheckBlockSignature(worker); err != nil {
|
if err := params.Block1.CheckBlockSignature(vmctx.Context(), worker); err != nil {
|
||||||
return nil, aerrors.Absorb(err, 4, "block1 did not have valid signature")
|
return nil, aerrors.Absorb(err, 4, "block1 did not have valid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := params.Block2.CheckBlockSignature(worker); err != nil {
|
if err := params.Block2.CheckBlockSignature(vmctx.Context(), worker); err != nil {
|
||||||
return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature")
|
return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,18 +158,18 @@ func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx ty
|
|||||||
return nil, aerrors.New(6, "blocks do not prove a slashable offense")
|
return nil, aerrors.New(6, "blocks do not prove a slashable offense")
|
||||||
}
|
}
|
||||||
|
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
old := vmctx.Storage().GetHead()
|
old := vmctx.Storage().GetHead()
|
||||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.BigCmp(self.TotalStorage, types.NewInt(0)) == 0 {
|
if types.BigCmp(self.TotalStorage, types.NewInt(0)) == 0 {
|
||||||
return nil, aerrors.Fatal("invalid state, storage market actor has zero total storage")
|
return nil, aerrors.Fatal("invalid state, storage power actor has zero total storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
miner := params.Block1.Miner
|
miner := params.Block1.Miner
|
||||||
if has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, miner); err != nil {
|
if has, err := MinerSetHas(vmctx, self.Miners, miner); err != nil {
|
||||||
return nil, aerrors.Wrapf(err, "failed to check miner in set")
|
return nil, aerrors.Wrapf(err, "failed to check miner in set")
|
||||||
} else if !has {
|
} else if !has {
|
||||||
return nil, aerrors.New(7, "either already slashed or not a miner")
|
return nil, aerrors.New(7, "either already slashed or not a miner")
|
||||||
@ -270,14 +269,14 @@ type UpdateStorageParams struct {
|
|||||||
Delta types.BigInt
|
Delta types.BigInt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) {
|
func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) {
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
old := vmctx.Storage().GetHead()
|
old := vmctx.Storage().GetHead()
|
||||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, vmctx.Message().From)
|
has, err := MinerSetHas(vmctx, self.Miners, vmctx.Message().From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -300,8 +299,8 @@ func (sma StorageMarketActor) UpdateStorage(act *types.Actor, vmctx types.VMCont
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
func (spa StoragePowerActor) GetTotalStorage(act *types.Actor, vmctx types.VMContext, params *struct{}) ([]byte, ActorError) {
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -313,8 +312,8 @@ type PowerLookupParams struct {
|
|||||||
Miner address.Address
|
Miner address.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) ([]byte, ActorError) {
|
func (spa StoragePowerActor) PowerLookup(act *types.Actor, vmctx types.VMContext, params *PowerLookupParams) ([]byte, ActorError) {
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||||
return nil, aerrors.Wrap(err, "getting head")
|
return nil, aerrors.Wrap(err, "getting head")
|
||||||
}
|
}
|
||||||
@ -327,14 +326,14 @@ func (sma StorageMarketActor) PowerLookup(act *types.Actor, vmctx types.VMContex
|
|||||||
return pow.Bytes(), nil
|
return pow.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func powerLookup(ctx context.Context, vmctx types.VMContext, self *StorageMarketState, miner address.Address) (types.BigInt, ActorError) {
|
func powerLookup(ctx context.Context, vmctx types.VMContext, self *StoragePowerState, miner address.Address) (types.BigInt, ActorError) {
|
||||||
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, miner)
|
has, err := MinerSetHas(vmctx, self.Miners, miner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.EmptyInt, err
|
return types.EmptyInt, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !has {
|
if !has {
|
||||||
return types.EmptyInt, aerrors.New(1, "miner not registered with storage market")
|
return types.EmptyInt, aerrors.New(1, "miner not registered with storage power actor")
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := vmctx.Send(miner, MAMethods.GetPower, types.NewInt(0), nil)
|
ret, err := vmctx.Send(miner, MAMethods.GetPower, types.NewInt(0), nil)
|
||||||
@ -349,13 +348,13 @@ type IsMinerParam struct {
|
|||||||
Addr address.Address
|
Addr address.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) IsMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) ([]byte, ActorError) {
|
func (spa StoragePowerActor) IsMiner(act *types.Actor, vmctx types.VMContext, param *IsMinerParam) ([]byte, ActorError) {
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, param.Addr)
|
has, err := MinerSetHas(vmctx, self.Miners, param.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -367,8 +366,8 @@ type PledgeCollateralParams struct {
|
|||||||
Size types.BigInt
|
Size types.BigInt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sma StorageMarketActor) PledgeCollateralForSize(act *types.Actor, vmctx types.VMContext, param *PledgeCollateralParams) ([]byte, ActorError) {
|
func (spa StoragePowerActor) PledgeCollateralForSize(act *types.Actor, vmctx types.VMContext, param *PledgeCollateralParams) ([]byte, ActorError) {
|
||||||
var self StorageMarketState
|
var self StoragePowerState
|
||||||
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
if err := vmctx.Storage().Get(vmctx.Storage().GetHead(), &self); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -433,20 +432,20 @@ func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.Big
|
|||||||
return types.BigAdd(powerCollateral, perCapCollateral), nil
|
return types.BigAdd(powerCollateral, perCapCollateral), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MinerSetHas(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
|
func MinerSetHas(vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
|
||||||
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
|
nd, err := hamt.LoadNode(vmctx.Context(), vmctx.Ipld(), rcid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, aerrors.Escalate(err, "failed to load miner set")
|
return false, aerrors.HandleExternalError(err, "failed to load miner set")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nd.Find(ctx, string(maddr.Bytes()), nil)
|
err = nd.Find(vmctx.Context(), string(maddr.Bytes()), nil)
|
||||||
switch err {
|
switch err {
|
||||||
case hamt.ErrNotFound:
|
case hamt.ErrNotFound:
|
||||||
return false, nil
|
return false, nil
|
||||||
case nil:
|
case nil:
|
||||||
return true, nil
|
return true, nil
|
||||||
default:
|
default:
|
||||||
return false, aerrors.Escalate(err, "failed to do set lookup")
|
return false, aerrors.HandleExternalError(err, "failed to do set lookup")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,30 +474,30 @@ func MinerSetList(ctx context.Context, cst *hamt.CborIpldStore, rcid cid.Cid) ([
|
|||||||
func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) {
|
func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) {
|
||||||
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
|
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to load miner set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to load miner set")
|
||||||
}
|
}
|
||||||
|
|
||||||
mkey := string(maddr.Bytes())
|
mkey := string(maddr.Bytes())
|
||||||
err = nd.Find(ctx, mkey, nil)
|
err = nd.Find(ctx, mkey, nil)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return cid.Undef, aerrors.Escalate(fmt.Errorf("miner already found"), "miner set add failed")
|
return cid.Undef, aerrors.New(20, "miner already in set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !xerrors.Is(err, hamt.ErrNotFound) {
|
if !xerrors.Is(err, hamt.ErrNotFound) {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to do miner set check")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to do miner set check")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := nd.Set(ctx, mkey, uint64(1)); err != nil {
|
if err := nd.Set(ctx, mkey, uint64(1)); err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "adding miner address to set failed")
|
return cid.Undef, aerrors.HandleExternalError(err, "adding miner address to set failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := nd.Flush(ctx); err != nil {
|
if err := nd.Flush(ctx); err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to flush miner set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to flush miner set")
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := vmctx.Ipld().Put(ctx, nd)
|
c, err := vmctx.Ipld().Put(ctx, nd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to persist miner set to storage")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to persist miner set to storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
@ -507,7 +506,7 @@ func MinerSetAdd(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr
|
|||||||
func MinerSetRemove(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) {
|
func MinerSetRemove(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (cid.Cid, aerrors.ActorError) {
|
||||||
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
|
nd, err := hamt.LoadNode(ctx, vmctx.Ipld(), rcid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to load miner set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to load miner set")
|
||||||
}
|
}
|
||||||
|
|
||||||
mkey := string(maddr.Bytes())
|
mkey := string(maddr.Bytes())
|
||||||
@ -515,17 +514,17 @@ func MinerSetRemove(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, ma
|
|||||||
case hamt.ErrNotFound:
|
case hamt.ErrNotFound:
|
||||||
return cid.Undef, aerrors.New(1, "miner not found in set on delete")
|
return cid.Undef, aerrors.New(1, "miner not found in set on delete")
|
||||||
default:
|
default:
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to delete miner from set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to delete miner from set")
|
||||||
case nil:
|
case nil:
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := nd.Flush(ctx); err != nil {
|
if err := nd.Flush(ctx); err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to flush miner set")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to flush miner set")
|
||||||
}
|
}
|
||||||
|
|
||||||
c, err := vmctx.Ipld().Put(ctx, nd)
|
c, err := vmctx.Ipld().Put(ctx, nd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, aerrors.Escalate(err, "failed to persist miner set to storage")
|
return cid.Undef, aerrors.HandleExternalError(err, "failed to persist miner set to storage")
|
||||||
}
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
@ -37,7 +37,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
// cheating the bootstrapping problem
|
// cheating the bootstrapping problem
|
||||||
cheatStorageMarketTotal(t, h.vm, h.cs.Blockstore())
|
cheatStorageMarketTotal(t, h.vm, h.cs.Blockstore())
|
||||||
|
|
||||||
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SPAMethods.CreateStorageMiner,
|
||||||
types.NewInt(500000),
|
types.NewInt(500000),
|
||||||
&CreateStorageMinerParams{
|
&CreateStorageMinerParams{
|
||||||
Owner: ownerAddr,
|
Owner: ownerAddr,
|
||||||
@ -52,7 +52,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner,
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.IsMiner,
|
||||||
&IsMinerParam{Addr: minerAddr})
|
&IsMinerParam{Addr: minerAddr})
|
||||||
ApplyOK(t, ret)
|
ApplyOK(t, ret)
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.PowerLookup,
|
||||||
&PowerLookupParams{Miner: minerAddr})
|
&PowerLookupParams{Miner: minerAddr})
|
||||||
ApplyOK(t, ret)
|
ApplyOK(t, ret)
|
||||||
power := types.BigFromBytes(ret.Return)
|
power := types.BigFromBytes(ret.Return)
|
||||||
@ -93,7 +93,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
signBlock(t, h.w, workerAddr, b1)
|
signBlock(t, h.w, workerAddr, b1)
|
||||||
signBlock(t, h.w, workerAddr, b2)
|
signBlock(t, h.w, workerAddr, b2)
|
||||||
|
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.ArbitrateConsensusFault,
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.ArbitrateConsensusFault,
|
||||||
&ArbitrateConsensusFaultParams{
|
&ArbitrateConsensusFaultParams{
|
||||||
Block1: b1,
|
Block1: b1,
|
||||||
Block2: b2,
|
Block2: b2,
|
||||||
@ -102,13 +102,13 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.PowerLookup,
|
||||||
&PowerLookupParams{Miner: minerAddr})
|
&PowerLookupParams{Miner: minerAddr})
|
||||||
assert.Equal(t, ret.ExitCode, byte(1))
|
assert.Equal(t, ret.ExitCode, byte(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner, &IsMinerParam{minerAddr})
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SPAMethods.IsMiner, &IsMinerParam{minerAddr})
|
||||||
ApplyOK(t, ret)
|
ApplyOK(t, ret)
|
||||||
assert.Equal(t, ret.Return, cbg.CborBoolFalse)
|
assert.Equal(t, ret.Return, cbg.CborBoolFalse)
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ func cheatStorageMarketTotal(t *testing.T, vm *vm.VM, bs bstore.Blockstore) {
|
|||||||
|
|
||||||
cst := hamt.CSTFromBstore(bs)
|
cst := hamt.CSTFromBstore(bs)
|
||||||
|
|
||||||
var smastate StorageMarketState
|
var smastate StoragePowerState
|
||||||
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
|
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
@ -53,7 +53,7 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore)
|
|||||||
cs := store.NewChainStore(bs, nil)
|
cs := store.NewChainStore(bs, nil)
|
||||||
|
|
||||||
// TODO: should probabaly mock out the randomness bit, nil works for now
|
// TODO: should probabaly mock out the randomness bit, nil works for now
|
||||||
vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs)
|
vm, err := vm.NewVM(stateroot, 1, nil, maddr, cs.Blockstore())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func TestVMInvokeMethod(t *testing.T) {
|
|||||||
from := addrs[0]
|
from := addrs[0]
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
cenc, err := SerializeParams(&StorageMinerConstructorParams{})
|
cenc, err := SerializeParams(&StorageMinerConstructorParams{Owner: from, Worker: from})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -116,6 +116,7 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
|
|||||||
cheatStorageMarketTotal(t, vm, bs)
|
cheatStorageMarketTotal(t, vm, bs)
|
||||||
|
|
||||||
params := &StorageMinerConstructorParams{
|
params := &StorageMinerConstructorParams{
|
||||||
|
Owner: maddr,
|
||||||
Worker: maddr,
|
Worker: maddr,
|
||||||
SectorSize: types.NewInt(build.SectorSize),
|
SectorSize: types.NewInt(build.SectorSize),
|
||||||
PeerID: "fakepeerid",
|
PeerID: "fakepeerid",
|
||||||
@ -129,7 +130,7 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
|
|||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: StorageMarketAddress,
|
To: StorageMarketAddress,
|
||||||
From: from,
|
From: from,
|
||||||
Method: SMAMethods.CreateStorageMiner,
|
Method: SPAMethods.CreateStorageMiner,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
GasPrice: types.NewInt(1),
|
GasPrice: types.NewInt(1),
|
||||||
GasLimit: types.NewInt(10000),
|
GasLimit: types.NewInt(10000),
|
||||||
|
@ -103,7 +103,7 @@ func Absorb(err error, retCode uint8, msg string) ActorError {
|
|||||||
fatal: true,
|
fatal: true,
|
||||||
retCode: 0,
|
retCode: 0,
|
||||||
|
|
||||||
msg: "tried absorbing an error that is alreay an fatal error",
|
msg: "tried absorbing an error that is already a fatal error",
|
||||||
frame: xerrors.Caller(1),
|
frame: xerrors.Caller(1),
|
||||||
err: err,
|
err: err,
|
||||||
}
|
}
|
||||||
@ -142,3 +142,28 @@ func Escalate(err error, msg string) ActorError {
|
|||||||
err: err,
|
err: err,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HandleExternalError(err error, msg string) ActorError {
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if aerr, ok := err.(ActorError); ok {
|
||||||
|
return &actorError{
|
||||||
|
fatal: IsFatal(aerr),
|
||||||
|
retCode: RetCode(aerr),
|
||||||
|
|
||||||
|
msg: msg,
|
||||||
|
frame: xerrors.Caller(1),
|
||||||
|
err: aerr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &actorError{
|
||||||
|
fatal: true,
|
||||||
|
|
||||||
|
msg: msg,
|
||||||
|
frame: xerrors.Caller(1),
|
||||||
|
err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2379,7 +2379,7 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StorageMarketState) MarshalCBOR(w io.Writer) error {
|
func (t *StoragePowerState) MarshalCBOR(w io.Writer) error {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
_, err := w.Write(cbg.CborNull)
|
_, err := w.Write(cbg.CborNull)
|
||||||
return err
|
return err
|
||||||
@ -2406,7 +2406,7 @@ func (t *StorageMarketState) MarshalCBOR(w io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *StorageMarketState) UnmarshalCBOR(r io.Reader) error {
|
func (t *StoragePowerState) UnmarshalCBOR(r io.Reader) error {
|
||||||
br := cbg.GetPeeker(r)
|
br := cbg.GetPeeker(r)
|
||||||
|
|
||||||
maj, extra, err := cbg.CborReadHeader(br)
|
maj, extra, err := cbg.CborReadHeader(br)
|
||||||
|
@ -158,7 +158,7 @@ func NewHarness(t *testing.T, options ...HarnessOpt) *Harness {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
h.cs = store.NewChainStore(h.bs, nil)
|
h.cs = store.NewChainStore(h.bs, nil)
|
||||||
h.vm, err = vm.NewVM(stateroot, 1, nil, h.HI.Miner, h.cs)
|
h.vm, err = vm.NewVM(stateroot, 1, nil, h.HI.Miner, h.cs.Blockstore())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,10 @@ func hash(ingest []byte, cfg *blake2b.Config) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a Address) MarshalCBOR(w io.Writer) error {
|
func (a Address) MarshalCBOR(w io.Writer) error {
|
||||||
|
if a == Undef {
|
||||||
|
return fmt.Errorf("cannot marshal undefined address")
|
||||||
|
}
|
||||||
|
|
||||||
abytes := a.Bytes()
|
abytes := a.Bytes()
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(abytes)))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(abytes)))); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -360,6 +364,9 @@ func (a *Address) UnmarshalCBOR(br io.Reader) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if addr == Undef {
|
||||||
|
return fmt.Errorf("cbor input should not contain empty addresses")
|
||||||
|
}
|
||||||
|
|
||||||
*a = addr
|
*a = addr
|
||||||
|
|
||||||
|
@ -121,13 +121,13 @@ func (e *heightEvents) headChangeAt(rev, app []*types.TipSet) error {
|
|||||||
//
|
//
|
||||||
// ts passed to handlers is the tipset at the specified, or above, if lower tipsets were null
|
// ts passed to handlers is the tipset at the specified, or above, if lower tipsets were null
|
||||||
func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h uint64) error {
|
func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h uint64) error {
|
||||||
e.lk.Lock()
|
|
||||||
defer e.lk.Unlock()
|
e.lk.Lock() // Tricky locking, check your locks if you modify this function!
|
||||||
|
|
||||||
bestH := e.tsc.best().Height()
|
bestH := e.tsc.best().Height()
|
||||||
|
|
||||||
if bestH >= h+uint64(confidence) {
|
if bestH >= h+uint64(confidence) {
|
||||||
ts, err := e.tsc.get(h)
|
ts, err := e.tsc.getNonNull(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("events.ChainAt: calling HandleFunc with nil tipset, not found in cache: %s", err)
|
log.Warnf("events.ChainAt: calling HandleFunc with nil tipset, not found in cache: %s", err)
|
||||||
}
|
}
|
||||||
@ -140,6 +140,8 @@ func (e *heightEvents) ChainAt(hnd HeightHandler, rev RevertHandler, confidence
|
|||||||
bestH = e.tsc.best().Height()
|
bestH = e.tsc.best().Height()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer e.lk.Unlock()
|
||||||
|
|
||||||
if bestH >= h+uint64(confidence)+e.gcConfidence {
|
if bestH >= h+uint64(confidence)+e.gcConfidence {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,11 @@ func (fcs *fakeCS) ChainGetTipSetByHeight(context.Context, uint64, *types.TipSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet {
|
func makeTs(t *testing.T, h uint64, msgcid cid.Cid) *types.TipSet {
|
||||||
|
a, _ := address.NewFromString("t00")
|
||||||
ts, err := types.NewTipSet([]*types.BlockHeader{
|
ts, err := types.NewTipSet([]*types.BlockHeader{
|
||||||
{
|
{
|
||||||
Height: h,
|
Height: h,
|
||||||
|
Miner: a,
|
||||||
|
|
||||||
ParentStateRoot: dummyCid,
|
ParentStateRoot: dummyCid,
|
||||||
Messages: msgcid,
|
Messages: msgcid,
|
||||||
@ -432,6 +434,35 @@ func TestAtChainedConfidence(t *testing.T) {
|
|||||||
require.Equal(t, false, reverted)
|
require.Equal(t, false, reverted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAtChainedConfidenceNull(t *testing.T) {
|
||||||
|
fcs := &fakeCS{
|
||||||
|
t: t,
|
||||||
|
h: 1,
|
||||||
|
tsc: newTSCache(2*build.ForkLengthThreshold, nil),
|
||||||
|
}
|
||||||
|
require.NoError(t, fcs.tsc.add(makeTs(t, 1, dummyCid)))
|
||||||
|
|
||||||
|
events := NewEvents(context.Background(), fcs)
|
||||||
|
|
||||||
|
fcs.advance(0, 15, nil, 5)
|
||||||
|
|
||||||
|
var applied bool
|
||||||
|
var reverted bool
|
||||||
|
|
||||||
|
err := events.ChainAt(func(ts *types.TipSet, curH uint64) error {
|
||||||
|
applied = true
|
||||||
|
require.Equal(t, 6, int(ts.Height()))
|
||||||
|
return nil
|
||||||
|
}, func(ts *types.TipSet) error {
|
||||||
|
reverted = true
|
||||||
|
return nil
|
||||||
|
}, 3, 5)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, true, applied)
|
||||||
|
require.Equal(t, false, reverted)
|
||||||
|
}
|
||||||
|
|
||||||
func TestCalled(t *testing.T) {
|
func TestCalled(t *testing.T) {
|
||||||
fcs := &fakeCS{
|
fcs := &fakeCS{
|
||||||
t: t,
|
t: t,
|
||||||
@ -479,7 +510,7 @@ func TestCalled(t *testing.T) {
|
|||||||
fcs.advance(0, 3, map[int]cid.Cid{ // msg at H=6; H=8 (confidence=2)
|
fcs.advance(0, 3, map[int]cid.Cid{ // msg at H=6; H=8 (confidence=2)
|
||||||
0: fcs.fakeMsgs(fakeMsg{
|
0: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 1},
|
{To: t0123, From: t0123, Method: 5, Nonce: 1},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
@ -520,7 +551,7 @@ func TestCalled(t *testing.T) {
|
|||||||
|
|
||||||
n2msg := fcs.fakeMsgs(fakeMsg{
|
n2msg := fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 2},
|
{To: t0123, From: t0123, Method: 5, Nonce: 2},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -574,7 +605,7 @@ func TestCalled(t *testing.T) {
|
|||||||
fcs.advance(0, 1, map[int]cid.Cid{ // msg at H=16; H=16
|
fcs.advance(0, 1, map[int]cid.Cid{ // msg at H=16; H=16
|
||||||
0: fcs.fakeMsgs(fakeMsg{
|
0: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 3},
|
{To: t0123, From: t0123, Method: 5, Nonce: 3},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
@ -597,7 +628,7 @@ func TestCalled(t *testing.T) {
|
|||||||
fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29
|
fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29
|
||||||
0: fcs.fakeMsgs(fakeMsg{
|
0: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 4}, // this signals we don't want more
|
{To: t0123, From: t0123, Method: 5, Nonce: 4}, // this signals we don't want more
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
@ -609,7 +640,7 @@ func TestCalled(t *testing.T) {
|
|||||||
fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29
|
fcs.advance(0, 4, map[int]cid.Cid{ // msg at H=26; H=29
|
||||||
0: fcs.fakeMsgs(fakeMsg{
|
0: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 5},
|
{To: t0123, From: t0123, Method: 5, Nonce: 5},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
@ -754,12 +785,12 @@ func TestCalledOrder(t *testing.T) {
|
|||||||
fcs.advance(0, 10, map[int]cid.Cid{
|
fcs.advance(0, 10, map[int]cid.Cid{
|
||||||
1: fcs.fakeMsgs(fakeMsg{
|
1: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 1},
|
{To: t0123, From: t0123, Method: 5, Nonce: 1},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
2: fcs.fakeMsgs(fakeMsg{
|
2: fcs.fakeMsgs(fakeMsg{
|
||||||
bmsgs: []*types.Message{
|
bmsgs: []*types.Message{
|
||||||
{To: t0123, Method: 5, Nonce: 2},
|
{To: t0123, From: t0123, Method: 5, Nonce: 2},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
@ -2,9 +2,11 @@ package events
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,8 +18,11 @@ func TestTsCache(t *testing.T) {
|
|||||||
|
|
||||||
h := uint64(75)
|
h := uint64(75)
|
||||||
|
|
||||||
|
a, _ := address.NewFromString("t00")
|
||||||
|
|
||||||
add := func() {
|
add := func() {
|
||||||
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
||||||
|
Miner: a,
|
||||||
Height: h,
|
Height: h,
|
||||||
ParentStateRoot: dummyCid,
|
ParentStateRoot: dummyCid,
|
||||||
Messages: dummyCid,
|
Messages: dummyCid,
|
||||||
@ -54,8 +59,10 @@ func TestTsCacheNulls(t *testing.T) {
|
|||||||
|
|
||||||
h := uint64(75)
|
h := uint64(75)
|
||||||
|
|
||||||
|
a, _ := address.NewFromString("t00")
|
||||||
add := func() {
|
add := func() {
|
||||||
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
ts, err := types.NewTipSet([]*types.BlockHeader{{
|
||||||
|
Miner: a,
|
||||||
Height: h,
|
Height: h,
|
||||||
ParentStateRoot: dummyCid,
|
ParentStateRoot: dummyCid,
|
||||||
Messages: dummyCid,
|
Messages: dummyCid,
|
||||||
|
@ -413,7 +413,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, ticks []*types.Ticket,
|
|||||||
return false, nil, xerrors.Errorf("failed to check power: %w", err)
|
return false, nil, xerrors.Errorf("failed to check power: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.PowerCmp(vrfout, pow.MinerPower, pow.TotalPower), vrfout, nil
|
return types.PowerCmp(vrfout, types.BigMul(pow.MinerPower, types.NewInt(build.BlocksPerEpoch)), pow.TotalPower), vrfout, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
|
type SignFunc func(context.Context, address.Address, []byte) (*types.Signature, error)
|
||||||
|
@ -96,8 +96,11 @@ func MinerCreateBlock(ctx context.Context, sm *stmgr.StateManager, w *wallet.Wal
|
|||||||
}
|
}
|
||||||
|
|
||||||
next.BLSAggregate = aggSig
|
next.BLSAggregate = aggSig
|
||||||
pweight := sm.ChainStore().Weight(parents)
|
pweight, err := sm.ChainStore().Weight(ctx, parents)
|
||||||
next.ParentWeight = types.NewInt(pweight)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
next.ParentWeight = pweight
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore())
|
cst := hamt.CSTFromBstore(sm.ChainStore().Blockstore())
|
||||||
tree, err := state.LoadStateTree(cst, st)
|
tree, err := state.LoadStateTree(cst, st)
|
||||||
|
@ -143,7 +143,7 @@ func SetupStorageMarketActor(bs bstore.Blockstore) (*types.Actor, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sms := &actors.StorageMarketState{
|
sms := &actors.StoragePowerState{
|
||||||
Miners: emptyhamt,
|
Miners: emptyhamt,
|
||||||
TotalStorage: types.NewInt(0),
|
TotalStorage: types.NewInt(0),
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ func mustEnc(i cbg.CBORMarshaler) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, error) {
|
func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid, gmcfg *GenMinerCfg) (cid.Cid, error) {
|
||||||
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs)
|
vm, err := vm.NewVM(sroot, 0, nil, actors.NetworkAddress, cs.Blockstore())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create NewVM: %w", err)
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
|
|
||||||
// TODO: hardcoding 7000000 here is a little fragile, it changes any
|
// TODO: hardcoding 7000000 here is a little fragile, it changes any
|
||||||
// time anyone changes the initial account allocations
|
// time anyone changes the initial account allocations
|
||||||
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6500), actors.SMAMethods.CreateStorageMiner, params)
|
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6500), actors.SPAMethods.CreateStorageMiner, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
|
|
||||||
params = mustEnc(&actors.UpdateStorageParams{Delta: types.NewInt(5000)})
|
params = mustEnc(&actors.UpdateStorageParams{Delta: types.NewInt(5000)})
|
||||||
|
|
||||||
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SMAMethods.UpdateStorage, params)
|
_, err = doExec(ctx, vm, actors.StorageMarketAddress, maddr, actors.SPAMethods.UpdateStorage, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err)
|
return cid.Undef, xerrors.Errorf("failed to update total storage: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,6 @@ func (ms *msgSet) add(m *types.SignedMessage) error {
|
|||||||
log.Error("Add with duplicate nonce")
|
log.Error("Add with duplicate nonce")
|
||||||
return xerrors.Errorf("message to %s with nonce %d already in mpool")
|
return xerrors.Errorf("message to %s with nonce %d already in mpool")
|
||||||
}
|
}
|
||||||
log.Warn("Add called with the same message multiple times")
|
|
||||||
}
|
}
|
||||||
ms.msgs[m.Message.Nonce] = m
|
ms.msgs[m.Message.Nonce] = m
|
||||||
|
|
||||||
|
@ -89,11 +89,16 @@ func sendHeadNotifs(ctx context.Context, ps *pubsub.PubSub, topic string, chain
|
|||||||
case notif := <-notifs:
|
case notif := <-notifs:
|
||||||
n := notif[len(notif)-1]
|
n := notif[len(notif)-1]
|
||||||
|
|
||||||
|
w, err := chain.ChainTipSetWeight(ctx, n.Val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
m := message{
|
m := message{
|
||||||
Cids: n.Val.Cids(),
|
Cids: n.Val.Cids(),
|
||||||
Blocks: n.Val.Blocks(),
|
Blocks: n.Val.Blocks(),
|
||||||
Height: n.Val.Height(),
|
Height: n.Val.Height(),
|
||||||
Weight: n.Val.Weight(),
|
Weight: w,
|
||||||
NodeName: nickname,
|
NodeName: nickname,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,16 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/vm"
|
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate cid.Cid, r vm.Rand, bheight uint64) (*types.MessageReceipt, error) {
|
func (sm *StateManager) CallRaw(ctx context.Context, msg *types.Message, bstate cid.Cid, r vm.Rand, bheight uint64) (*types.MessageReceipt, error) {
|
||||||
vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs)
|
vmi, err := vm.NewVM(bstate, bheight, r, actors.NetworkAddress, sm.cs.Blockstore())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||||
}
|
}
|
||||||
@ -55,7 +56,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
|
|||||||
|
|
||||||
state := ts.ParentState()
|
state := ts.ParentState()
|
||||||
|
|
||||||
r := vm.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil)
|
r := store.NewChainRand(sm.cs, ts.Cids(), ts.Height(), nil)
|
||||||
|
|
||||||
return sm.CallRaw(ctx, msg, state, r, ts.Height())
|
return sm.CallRaw(ctx, msg, state, r, ts.Height())
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
|
|||||||
cids[i] = v.Cid()
|
cids[i] = v.Cid()
|
||||||
}
|
}
|
||||||
|
|
||||||
r := vm.NewChainRand(sm.cs, cids, blks[0].Height, nil)
|
r := store.NewChainRand(sm.cs, cids, blks[0].Height, nil)
|
||||||
|
|
||||||
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs)
|
vmi, err := vm.NewVM(pstate, blks[0].Height, r, address.Undef, sm.cs.Blockstore())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
return cid.Undef, cid.Undef, xerrors.Errorf("instantiating VM failed: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package stmgr
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
@ -71,18 +70,18 @@ func GetMinerOwner(ctx context.Context, sm *StateManager, st cid.Cid, maddr addr
|
|||||||
|
|
||||||
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) {
|
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (types.BigInt, types.BigInt, error) {
|
||||||
var err error
|
var err error
|
||||||
enc, err := actors.SerializeParams(&actors.PowerLookupParams{maddr})
|
|
||||||
if err != nil {
|
|
||||||
return types.EmptyInt, types.EmptyInt, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var mpow types.BigInt
|
var mpow types.BigInt
|
||||||
|
|
||||||
if maddr != address.Undef {
|
if maddr != address.Undef {
|
||||||
|
enc, aerr := actors.SerializeParams(&actors.PowerLookupParams{maddr})
|
||||||
|
if aerr != nil {
|
||||||
|
return types.EmptyInt, types.EmptyInt, aerr
|
||||||
|
}
|
||||||
ret, err := sm.Call(ctx, &types.Message{
|
ret, err := sm.Call(ctx, &types.Message{
|
||||||
From: maddr,
|
From: maddr,
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
Method: actors.SMAMethods.PowerLookup,
|
Method: actors.SPAMethods.PowerLookup,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
}, ts)
|
}, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -98,7 +97,7 @@ func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr add
|
|||||||
ret, err := sm.Call(ctx, &types.Message{
|
ret, err := sm.Call(ctx, &types.Message{
|
||||||
From: actors.StorageMarketAddress,
|
From: actors.StorageMarketAddress,
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
Method: actors.SMAMethods.GetTotalStorage,
|
Method: actors.SPAMethods.GetTotalStorage,
|
||||||
}, ts)
|
}, ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
|
return types.EmptyInt, types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
|
||||||
|
@ -7,9 +7,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/state"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld"
|
amt "github.com/filecoin-project/go-amt-ipld"
|
||||||
@ -182,14 +185,14 @@ func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cs.PutTipSet(ts); err != nil {
|
if err := cs.PutTipSet(context.TODO(), ts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cs.ds.Put(dstore.NewKey("0"), b.Cid().Bytes())
|
return cs.ds.Put(dstore.NewKey("0"), b.Cid().Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) PutTipSet(ts *types.TipSet) error {
|
func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
|
||||||
for _, b := range ts.Blocks() {
|
for _, b := range ts.Blocks() {
|
||||||
if err := cs.PersistBlockHeader(b); err != nil {
|
if err := cs.PersistBlockHeader(b); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -202,16 +205,25 @@ func (cs *ChainStore) PutTipSet(ts *types.TipSet) error {
|
|||||||
}
|
}
|
||||||
log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids())
|
log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids())
|
||||||
|
|
||||||
if err := cs.MaybeTakeHeavierTipSet(expanded); err != nil {
|
if err := cs.MaybeTakeHeavierTipSet(ctx, expanded); err != nil {
|
||||||
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet")
|
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) MaybeTakeHeavierTipSet(ts *types.TipSet) error {
|
func (cs *ChainStore) MaybeTakeHeavierTipSet(ctx context.Context, ts *types.TipSet) error {
|
||||||
cs.heaviestLk.Lock()
|
cs.heaviestLk.Lock()
|
||||||
defer cs.heaviestLk.Unlock()
|
defer cs.heaviestLk.Unlock()
|
||||||
if cs.heaviest == nil || cs.Weight(ts) > cs.Weight(cs.heaviest) {
|
w, err := cs.Weight(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
heaviestW, err := cs.Weight(ctx, cs.heaviest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if w.GreaterThan(heaviestW) {
|
||||||
// TODO: don't do this for initial sync. Now that we don't have a
|
// TODO: don't do this for initial sync. Now that we don't have a
|
||||||
// difference between 'bootstrap sync' and 'caught up' sync, we need
|
// difference between 'bootstrap sync' and 'caught up' sync, we need
|
||||||
// some other heuristic.
|
// some other heuristic.
|
||||||
@ -261,7 +273,7 @@ func (cs *ChainStore) takeHeaviestTipSet(ts *types.TipSet) error {
|
|||||||
new: ts,
|
new: ts,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Warn("no heaviest tipset found, using %s", ts.Cids())
|
log.Warnf("no heaviest tipset found, using %s", ts.Cids())
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("New heaviest tipset! %s", ts.Cids())
|
log.Debugf("New heaviest tipset! %s", ts.Cids())
|
||||||
@ -377,10 +389,6 @@ func (cs *ChainStore) ReorgOps(a, b *types.TipSet) ([]*types.TipSet, []*types.Ti
|
|||||||
return leftChain, rightChain, nil
|
return leftChain, rightChain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) Weight(ts *types.TipSet) uint64 {
|
|
||||||
return ts.Blocks()[0].ParentWeight.Uint64() + uint64(len(ts.Cids()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet {
|
func (cs *ChainStore) GetHeaviestTipSet() *types.TipSet {
|
||||||
cs.heaviestLk.Lock()
|
cs.heaviestLk.Lock()
|
||||||
defer cs.heaviestLk.Unlock()
|
defer cs.heaviestLk.Unlock()
|
||||||
@ -469,7 +477,7 @@ func (cs *ChainStore) expandTipset(b *types.BlockHeader) (*types.TipSet, error)
|
|||||||
return types.NewTipSet(all)
|
return types.NewTipSet(all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
|
func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error {
|
||||||
if err := cs.PersistBlockHeader(b); err != nil {
|
if err := cs.PersistBlockHeader(b); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -479,7 +487,7 @@ func (cs *ChainStore) AddBlock(b *types.BlockHeader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cs.MaybeTakeHeavierTipSet(ts); err != nil {
|
if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
|
||||||
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed")
|
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -720,6 +728,9 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets []*types.Ticket, lb int64) ([]byte, error) {
|
func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets []*types.Ticket, lb int64) ([]byte, error) {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "store.GetRandomness")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
if lb < 0 {
|
if lb < 0 {
|
||||||
return nil, fmt.Errorf("negative lookback parameters are not valid (got %d)", lb)
|
return nil, fmt.Errorf("negative lookback parameters are not valid (got %d)", lb)
|
||||||
}
|
}
|
||||||
@ -793,3 +804,24 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h uint64, ts *types
|
|||||||
ts = pts
|
ts = pts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type chainRand struct {
|
||||||
|
cs *ChainStore
|
||||||
|
blks []cid.Cid
|
||||||
|
bh uint64
|
||||||
|
tickets []*types.Ticket
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewChainRand(cs *ChainStore, blks []cid.Cid, bheight uint64, tickets []*types.Ticket) vm.Rand {
|
||||||
|
return &chainRand{
|
||||||
|
cs: cs,
|
||||||
|
blks: blks,
|
||||||
|
bh: bheight,
|
||||||
|
tickets: tickets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
|
||||||
|
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h
|
||||||
|
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
|
||||||
|
}
|
||||||
|
94
chain/store/weight.go
Normal file
94
chain/store/weight.go
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
var zero = types.NewInt(0)
|
||||||
|
|
||||||
|
func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||||
|
if ts == nil {
|
||||||
|
return types.NewInt(0), nil
|
||||||
|
}
|
||||||
|
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
|
||||||
|
|
||||||
|
var out = new(big.Int).Set(ts.Blocks()[0].ParentWeight.Int)
|
||||||
|
|
||||||
|
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
|
||||||
|
|
||||||
|
ret, err := cs.call(ctx, &types.Message{
|
||||||
|
From: actors.StorageMarketAddress,
|
||||||
|
To: actors.StorageMarketAddress,
|
||||||
|
Method: actors.SPAMethods.GetTotalStorage,
|
||||||
|
}, ts)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("failed to get total power from chain: %w", err)
|
||||||
|
}
|
||||||
|
if ret.ExitCode != 0 {
|
||||||
|
return types.EmptyInt, xerrors.Errorf("failed to get total power from chain (exit code %d)", ret.ExitCode)
|
||||||
|
}
|
||||||
|
log2P := int64(0)
|
||||||
|
tpow := types.BigFromBytes(ret.Return)
|
||||||
|
if tpow.GreaterThan(zero) {
|
||||||
|
log2P = int64(tpow.BitLen() - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Add(out, big.NewInt(log2P*256))
|
||||||
|
|
||||||
|
// (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
|
||||||
|
|
||||||
|
wRatioNum := int64(1)
|
||||||
|
wRatioDen := 2
|
||||||
|
|
||||||
|
eWeight := big.NewInt((log2P * int64(len(ts.Blocks())) * wRatioNum) << 8)
|
||||||
|
eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*wRatioDen)))
|
||||||
|
out.Add(out, eWeight)
|
||||||
|
|
||||||
|
return types.BigInt{Int: out}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: dedupe with state manager
|
||||||
|
func (cs *ChainStore) call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*types.MessageReceipt, error) {
|
||||||
|
bstate := ts.ParentState()
|
||||||
|
|
||||||
|
r := NewChainRand(cs, ts.Cids(), ts.Height(), nil)
|
||||||
|
|
||||||
|
vmi, err := vm.NewVM(bstate, ts.Height(), r, actors.NetworkAddress, cs.bs)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to set up vm: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg.GasLimit == types.EmptyInt {
|
||||||
|
msg.GasLimit = types.NewInt(10000000000)
|
||||||
|
}
|
||||||
|
if msg.GasPrice == types.EmptyInt {
|
||||||
|
msg.GasPrice = types.NewInt(0)
|
||||||
|
}
|
||||||
|
if msg.Value == types.EmptyInt {
|
||||||
|
msg.Value = types.NewInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fromActor, err := vmi.StateTree().GetActor(msg.From)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("call raw get actor: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Nonce = fromActor.Nonce
|
||||||
|
|
||||||
|
// TODO: maybe just use the invoker directly?
|
||||||
|
ret, err := vmi.ApplyMessage(ctx, msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("apply message failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret.ActorErr != nil {
|
||||||
|
log.Warnf("chain call failed: %s", ret.ActorErr)
|
||||||
|
}
|
||||||
|
return &ret.MessageReceipt, nil
|
||||||
|
}
|
@ -94,7 +94,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, b := range fts.Blocks {
|
for _, b := range fts.Blocks {
|
||||||
if err := syncer.validateMsgMeta(b); err != nil {
|
if err := syncer.ValidateMsgMeta(b); err != nil {
|
||||||
log.Warnf("invalid block received: %s", err)
|
log.Warnf("invalid block received: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -122,7 +122,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) validateMsgMeta(fblk *types.FullBlock) error {
|
func (syncer *Syncer) ValidateMsgMeta(fblk *types.FullBlock) error {
|
||||||
var bcids, scids []cbg.CBORMarshaler
|
var bcids, scids []cbg.CBORMarshaler
|
||||||
for _, m := range fblk.BlsMessages {
|
for _, m := range fblk.BlsMessages {
|
||||||
c := cbg.CborCid(m.Cid())
|
c := cbg.CborCid(m.Cid())
|
||||||
@ -147,6 +147,14 @@ func (syncer *Syncer) validateMsgMeta(fblk *types.FullBlock) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (syncer *Syncer) LocalPeer() peer.ID {
|
||||||
|
return syncer.self
|
||||||
|
}
|
||||||
|
|
||||||
|
func (syncer *Syncer) ChainStore() *store.ChainStore {
|
||||||
|
return syncer.store
|
||||||
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) {
|
func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) {
|
||||||
// TODO: search for other blocks that could form a tipset with this block
|
// TODO: search for other blocks that could form a tipset with this block
|
||||||
// and then send that tipset to InformNewHead
|
// and then send that tipset to InformNewHead
|
||||||
@ -253,7 +261,7 @@ func computeMsgMeta(bs amt.Blocks, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.
|
|||||||
return mrcid, nil
|
return mrcid, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
|
func (syncer *Syncer) selectHead(ctx context.Context, heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
|
||||||
var headsArr []*types.TipSet
|
var headsArr []*types.TipSet
|
||||||
for _, ts := range heads {
|
for _, ts := range heads {
|
||||||
headsArr = append(headsArr, ts)
|
headsArr = append(headsArr, ts)
|
||||||
@ -290,7 +298,16 @@ func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet
|
|||||||
return nil, fmt.Errorf("Conflict exists in heads set")
|
return nil, fmt.Errorf("Conflict exists in heads set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if syncer.store.Weight(cur) > syncer.store.Weight(sel) {
|
curw, err := syncer.store.Weight(ctx, cur)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
selw, err := syncer.store.Weight(ctx, sel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if curw.GreaterThan(selw) {
|
||||||
sel = cur
|
sel = cur
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,7 +361,7 @@ func (syncer *Syncer) Sync(ctx context.Context, maybeHead *types.TipSet) error {
|
|||||||
return xerrors.Errorf("collectChain failed: %w", err)
|
return xerrors.Errorf("collectChain failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := syncer.store.PutTipSet(maybeHead); err != nil {
|
if err := syncer.store.PutTipSet(ctx, maybeHead); err != nil {
|
||||||
return xerrors.Errorf("failed to put synced tipset to chainstore: %w", err)
|
return xerrors.Errorf("failed to put synced tipset to chainstore: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +400,7 @@ func (syncer *Syncer) minerIsValid(ctx context.Context, maddr address.Address, b
|
|||||||
ret, err := syncer.sm.Call(ctx, &types.Message{
|
ret, err := syncer.sm.Call(ctx, &types.Message{
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
From: maddr,
|
From: maddr,
|
||||||
Method: actors.SMAMethods.IsMiner,
|
Method: actors.SPAMethods.IsMiner,
|
||||||
Params: enc,
|
Params: enc,
|
||||||
}, baseTs)
|
}, baseTs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -467,7 +484,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
|
|||||||
return xerrors.Errorf("GetMinerWorker failed: %w", err)
|
return xerrors.Errorf("GetMinerWorker failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.CheckBlockSignature(waddr); err != nil {
|
if err := h.CheckBlockSignature(ctx, waddr); err != nil {
|
||||||
return xerrors.Errorf("check block signature failed: %w", err)
|
return xerrors.Errorf("check block signature failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,7 +581,7 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
pubks = append(pubks, pubk)
|
pubks = append(pubks, pubk)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := syncer.verifyBlsAggregate(b.Header.BLSAggregate, sigCids, pubks); err != nil {
|
if err := syncer.verifyBlsAggregate(ctx, b.Header.BLSAggregate, sigCids, pubks); err != nil {
|
||||||
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
|
return xerrors.Errorf("bls aggregate signature was invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,7 +629,13 @@ func (syncer *Syncer) checkBlockMessages(ctx context.Context, b *types.FullBlock
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (syncer *Syncer) verifyBlsAggregate(sig types.Signature, msgs []cid.Cid, pubks []bls.PublicKey) error {
|
func (syncer *Syncer) verifyBlsAggregate(ctx context.Context, sig types.Signature, msgs []cid.Cid, pubks []bls.PublicKey) error {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "syncer.verifyBlsAggregate")
|
||||||
|
defer span.End()
|
||||||
|
span.AddAttributes(
|
||||||
|
trace.Int64Attribute("msgCount", int64(len(msgs))),
|
||||||
|
)
|
||||||
|
|
||||||
var digests []bls.Digest
|
var digests []bls.Digest
|
||||||
for _, c := range msgs {
|
for _, c := range msgs {
|
||||||
digests = append(digests, bls.Hash(bls.Message(c.Bytes())))
|
digests = append(digests, bls.Hash(bls.Message(c.Bytes())))
|
||||||
|
@ -32,9 +32,6 @@ func (tu *syncTestUtil) repoWithChain(t testing.TB, h int) (repo.Repo, []byte, [
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
blks[i] = mts.TipSet
|
blks[i] = mts.TipSet
|
||||||
|
|
||||||
ts := mts.TipSet.TipSet()
|
|
||||||
fmt.Printf("tipset at H:%d: %s\n", ts.Height(), ts.Cids())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := tu.g.YieldRepo()
|
r, err := tu.g.YieldRepo()
|
||||||
@ -94,8 +91,38 @@ func (tu *syncTestUtil) Shutdown() {
|
|||||||
tu.cancel()
|
tu.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tu *syncTestUtil) printHeads() {
|
||||||
|
for i, n := range tu.nds {
|
||||||
|
head, err := n.ChainHead(tu.ctx)
|
||||||
|
if err != nil {
|
||||||
|
tu.t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Node %d: %s\n", i, head.Cids())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) pushFtsAndWait(to int, fts *store.FullTipSet, wait bool) {
|
func (tu *syncTestUtil) pushFtsAndWait(to int, fts *store.FullTipSet, wait bool) {
|
||||||
// TODO: would be great if we could pass a whole tipset here...
|
// TODO: would be great if we could pass a whole tipset here...
|
||||||
|
tu.pushTsExpectErr(to, fts, false)
|
||||||
|
|
||||||
|
if wait {
|
||||||
|
start := time.Now()
|
||||||
|
h, err := tu.nds[to].ChainHead(tu.ctx)
|
||||||
|
require.NoError(tu.t, err)
|
||||||
|
for !h.Equals(fts.TipSet()) {
|
||||||
|
time.Sleep(time.Millisecond * 50)
|
||||||
|
h, err = tu.nds[to].ChainHead(tu.ctx)
|
||||||
|
require.NoError(tu.t, err)
|
||||||
|
|
||||||
|
if time.Since(start) > time.Second*10 {
|
||||||
|
tu.t.Fatal("took too long waiting for block to be accepted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bool) {
|
||||||
for _, fb := range fts.Blocks {
|
for _, fb := range fts.Blocks {
|
||||||
var b types.BlockMsg
|
var b types.BlockMsg
|
||||||
|
|
||||||
@ -115,27 +142,17 @@ func (tu *syncTestUtil) pushFtsAndWait(to int, fts *store.FullTipSet, wait bool)
|
|||||||
b.BlsMessages = append(b.BlsMessages, c)
|
b.BlsMessages = append(b.BlsMessages, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(tu.t, tu.nds[to].ChainSubmitBlock(tu.ctx, &b))
|
err := tu.nds[to].SyncSubmitBlock(tu.ctx, &b)
|
||||||
|
if experr {
|
||||||
}
|
require.Error(tu.t, err, "expected submit block to fail")
|
||||||
|
} else {
|
||||||
if wait {
|
|
||||||
start := time.Now()
|
|
||||||
h, err := tu.nds[to].ChainHead(tu.ctx)
|
|
||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
for !h.Equals(fts.TipSet()) {
|
|
||||||
time.Sleep(time.Millisecond * 50)
|
|
||||||
h, err = tu.nds[to].ChainHead(tu.ctx)
|
|
||||||
require.NoError(tu.t, err)
|
|
||||||
|
|
||||||
if time.Since(start) > time.Second*10 {
|
|
||||||
tu.t.Fatal("took too long waiting for block to be accepted")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int, wait bool) *store.FullTipSet {
|
}
|
||||||
|
|
||||||
|
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int, wait, fail bool) *store.FullTipSet {
|
||||||
if miners == nil {
|
if miners == nil {
|
||||||
for i := range tu.g.Miners {
|
for i := range tu.g.Miners {
|
||||||
miners = append(miners, i)
|
miners = append(miners, i)
|
||||||
@ -152,13 +169,17 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, src int, miners []int
|
|||||||
mts, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
|
mts, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
|
||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
|
|
||||||
|
if fail {
|
||||||
|
tu.pushTsExpectErr(src, mts.TipSet, true)
|
||||||
|
} else {
|
||||||
tu.pushFtsAndWait(src, mts.TipSet, wait)
|
tu.pushFtsAndWait(src, mts.TipSet, wait)
|
||||||
|
}
|
||||||
|
|
||||||
return mts.TipSet
|
return mts.TipSet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) mineNewBlock(src int, miners []int) {
|
func (tu *syncTestUtil) mineNewBlock(src int, miners []int) {
|
||||||
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true)
|
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false)
|
||||||
tu.g.CurTipset = mts
|
tu.g.CurTipset = mts
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +218,9 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
|
|||||||
|
|
||||||
lastTs := blocks[len(blocks)-1].Blocks
|
lastTs := blocks[len(blocks)-1].Blocks
|
||||||
for _, lastB := range lastTs {
|
for _, lastB := range lastTs {
|
||||||
err = out.(*impl.FullNodeAPI).ChainAPI.Chain.AddBlock(lastB.Header)
|
cs := out.(*impl.FullNodeAPI).ChainAPI.Chain
|
||||||
|
require.NoError(tu.t, cs.AddToTipSetTracker(lastB.Header))
|
||||||
|
err = cs.AddBlock(tu.ctx, lastB.Header)
|
||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,12 +391,17 @@ func TestSyncBadTimestamp(t *testing.T) {
|
|||||||
return pts.MinTimestamp() + 2
|
return pts.MinTimestamp() + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
a1 := tu.mineOnBlock(base, 0, nil, false)
|
fmt.Println("BASE: ", base.Cids())
|
||||||
|
tu.printHeads()
|
||||||
|
|
||||||
|
a1 := tu.mineOnBlock(base, 0, nil, false, true)
|
||||||
|
|
||||||
tu.g.Timestamper = nil
|
tu.g.Timestamper = nil
|
||||||
tu.g.ResyncBankerNonce(a1.TipSet())
|
tu.g.ResyncBankerNonce(a1.TipSet())
|
||||||
|
|
||||||
a2 := tu.mineOnBlock(base, 0, nil, true)
|
fmt.Println("After mine bad block!")
|
||||||
|
tu.printHeads()
|
||||||
|
a2 := tu.mineOnBlock(base, 0, nil, true, false)
|
||||||
|
|
||||||
tu.waitUntilSync(0, client)
|
tu.waitUntilSync(0, client)
|
||||||
|
|
||||||
@ -427,16 +455,16 @@ func TestSyncFork(t *testing.T) {
|
|||||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||||
|
|
||||||
// The two nodes fork at this point into 'a' and 'b'
|
// The two nodes fork at this point into 'a' and 'b'
|
||||||
a1 := tu.mineOnBlock(base, p1, []int{0}, true)
|
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false)
|
||||||
a := tu.mineOnBlock(a1, p1, []int{0}, true)
|
a := tu.mineOnBlock(a1, p1, []int{0}, true, false)
|
||||||
a = tu.mineOnBlock(a, p1, []int{0}, true)
|
a = tu.mineOnBlock(a, p1, []int{0}, true, false)
|
||||||
|
|
||||||
tu.g.ResyncBankerNonce(a1.TipSet())
|
tu.g.ResyncBankerNonce(a1.TipSet())
|
||||||
// chain B will now be heaviest
|
// chain B will now be heaviest
|
||||||
b := tu.mineOnBlock(base, p2, []int{1}, true)
|
b := tu.mineOnBlock(base, p2, []int{1}, true, false)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false)
|
||||||
|
|
||||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||||
|
@ -133,6 +133,10 @@ func (bi *BigInt) cborBytes() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fromCborBytes(buf []byte) (BigInt, error) {
|
func fromCborBytes(buf []byte) (BigInt, error) {
|
||||||
|
if len(buf) == 0 {
|
||||||
|
return NewInt(0), nil
|
||||||
|
}
|
||||||
|
|
||||||
var negative bool
|
var negative bool
|
||||||
switch buf[0] {
|
switch buf[0] {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
func TestBigIntSerializationRoundTrip(t *testing.T) {
|
func TestBigIntSerializationRoundTrip(t *testing.T) {
|
||||||
testValues := []string{
|
testValues := []string{
|
||||||
"0", "1", "10", "9999", "12345678901234567891234567890123456789012345678901234567890",
|
"0", "1", "10", "-10", "9999", "12345678901234567891234567890123456789012345678901234567890",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range testValues {
|
for _, v := range testValues {
|
||||||
@ -29,5 +29,6 @@ func TestBigIntSerializationRoundTrip(t *testing.T) {
|
|||||||
if BigCmp(out, bi) != 0 {
|
if BigCmp(out, bi) != 0 {
|
||||||
t.Fatal("failed to round trip BigInt through cbor")
|
t.Fatal("failed to round trip BigInt through cbor")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,14 @@ package types
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
|
"go.opencensus.io/trace"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
@ -98,7 +100,10 @@ func (blk *BlockHeader) SigningBytes() ([]byte, error) {
|
|||||||
return blkcopy.Serialize()
|
return blkcopy.Serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blk *BlockHeader) CheckBlockSignature(worker address.Address) error {
|
func (blk *BlockHeader) CheckBlockSignature(ctx context.Context, worker address.Address) error {
|
||||||
|
ctx, span := trace.StartSpan(ctx, "checkBlockSignature")
|
||||||
|
defer span.End()
|
||||||
|
|
||||||
sigb, err := blk.SigningBytes()
|
sigb, err := blk.SigningBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to get block signing bytes: %w", err)
|
return xerrors.Errorf("failed to get block signing bytes: %w", err)
|
||||||
|
@ -75,6 +75,8 @@ func NewTipSet(blks []*BlockHeader) (*TipSet, error) {
|
|||||||
return nil, fmt.Errorf("cannot create tipset with mismatching heights")
|
return nil, fmt.Errorf("cannot create tipset with mismatching heights")
|
||||||
}
|
}
|
||||||
ts.cids = append(ts.cids, b.Cid())
|
ts.cids = append(ts.cids, b.Cid())
|
||||||
|
|
||||||
|
// TODO: ensure the same parents
|
||||||
}
|
}
|
||||||
ts.height = blks[0].Height
|
ts.height = blks[0].Height
|
||||||
|
|
||||||
@ -89,12 +91,6 @@ func (ts *TipSet) Height() uint64 {
|
|||||||
return ts.height
|
return ts.height
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) Weight() BigInt {
|
|
||||||
// TODO: implement correctly
|
|
||||||
log.Warn("Called TipSet.Weight: TODO: correct implementation")
|
|
||||||
return BigAdd(ts.blks[0].ParentWeight, NewInt(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ts *TipSet) Parents() []cid.Cid {
|
func (ts *TipSet) Parents() []cid.Cid {
|
||||||
return ts.blks[0].Parents
|
return ts.blks[0].Parents
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld"
|
amt "github.com/filecoin-project/go-amt-ipld"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
@ -38,6 +40,8 @@ type VMContext interface {
|
|||||||
ChargeGas(uint64) aerrors.ActorError
|
ChargeGas(uint64) aerrors.ActorError
|
||||||
GetRandomness(height uint64) ([]byte, aerrors.ActorError)
|
GetRandomness(height uint64) ([]byte, aerrors.ActorError)
|
||||||
GetBalance(address.Address) (BigInt, aerrors.ActorError)
|
GetBalance(address.Address) (BigInt, aerrors.ActorError)
|
||||||
|
|
||||||
|
Context() context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
type storageWrapper struct {
|
type storageWrapper struct {
|
||||||
|
@ -30,7 +30,7 @@ func newInvoker() *invoker {
|
|||||||
|
|
||||||
// add builtInCode using: register(cid, singleton)
|
// add builtInCode using: register(cid, singleton)
|
||||||
inv.register(actors.InitActorCodeCid, actors.InitActor{}, actors.InitActorState{})
|
inv.register(actors.InitActorCodeCid, actors.InitActor{}, actors.InitActorState{})
|
||||||
inv.register(actors.StorageMarketActorCodeCid, actors.StorageMarketActor{}, actors.StorageMarketState{})
|
inv.register(actors.StorageMarketActorCodeCid, actors.StoragePowerActor{}, actors.StoragePowerState{})
|
||||||
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
inv.register(actors.StorageMinerCodeCid, actors.StorageMinerActor{}, actors.StorageMinerActorState{})
|
||||||
inv.register(actors.MultisigActorCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
|
inv.register(actors.MultisigActorCodeCid, actors.MultiSigActor{}, actors.MultiSigActorState{})
|
||||||
inv.register(actors.PaymentChannelActorCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
inv.register(actors.PaymentChannelActorCodeCid, actors.PaymentChannelActor{}, actors.PaymentChannelActorState{})
|
||||||
|
@ -3,15 +3,16 @@ package vm
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
dstore "github.com/ipfs/go-datastore"
|
||||||
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors"
|
"github.com/filecoin-project/go-lotus/chain/actors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/state"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
dstore "github.com/ipfs/go-datastore"
|
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
|
||||||
bstore "github.com/ipfs/go-ipfs-blockstore"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -3,6 +3,7 @@ package vm
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
blockstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
@ -10,7 +11,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/state"
|
"github.com/filecoin-project/go-lotus/chain/state"
|
||||||
"github.com/filecoin-project/go-lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
"github.com/filecoin-project/go-lotus/lib/bufbstore"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
@ -239,6 +239,10 @@ func (vmctx *VMContext) GetBalance(a address.Address) (types.BigInt, aerrors.Act
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (vmctx *VMContext) Context() context.Context {
|
||||||
|
return vmctx.ctx
|
||||||
|
}
|
||||||
|
|
||||||
type hBlocks interface {
|
type hBlocks interface {
|
||||||
GetBlock(context.Context, cid.Cid) (block.Block, error)
|
GetBlock(context.Context, cid.Cid) (block.Block, error)
|
||||||
AddBlock(block.Block) error
|
AddBlock(block.Block) error
|
||||||
@ -296,7 +300,6 @@ func (vm *VM) makeVMContext(ctx context.Context, sroot cid.Cid, msg *types.Messa
|
|||||||
type VM struct {
|
type VM struct {
|
||||||
cstate *state.StateTree
|
cstate *state.StateTree
|
||||||
base cid.Cid
|
base cid.Cid
|
||||||
cs *store.ChainStore
|
|
||||||
cst *hamt.CborIpldStore
|
cst *hamt.CborIpldStore
|
||||||
buf *bufbstore.BufferedBS
|
buf *bufbstore.BufferedBS
|
||||||
blockHeight uint64
|
blockHeight uint64
|
||||||
@ -305,8 +308,8 @@ type VM struct {
|
|||||||
rand Rand
|
rand Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cs *store.ChainStore) (*VM, error) {
|
func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cbs blockstore.Blockstore) (*VM, error) {
|
||||||
buf := bufbstore.NewBufferedBstore(cs.Blockstore())
|
buf := bufbstore.NewBufferedBstore(cbs)
|
||||||
cst := hamt.CSTFromBstore(buf)
|
cst := hamt.CSTFromBstore(buf)
|
||||||
state, err := state.LoadStateTree(cst, base)
|
state, err := state.LoadStateTree(cst, base)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -316,7 +319,6 @@ func NewVM(base cid.Cid, height uint64, r Rand, maddr address.Address, cs *store
|
|||||||
return &VM{
|
return &VM{
|
||||||
cstate: state,
|
cstate: state,
|
||||||
base: base,
|
base: base,
|
||||||
cs: cs,
|
|
||||||
cst: cst,
|
cst: cst,
|
||||||
buf: buf,
|
buf: buf,
|
||||||
blockHeight: height,
|
blockHeight: height,
|
||||||
@ -330,27 +332,6 @@ type Rand interface {
|
|||||||
GetRandomness(ctx context.Context, h int64) ([]byte, error)
|
GetRandomness(ctx context.Context, h int64) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type chainRand struct {
|
|
||||||
cs *store.ChainStore
|
|
||||||
blks []cid.Cid
|
|
||||||
bh uint64
|
|
||||||
tickets []*types.Ticket
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewChainRand(cs *store.ChainStore, blks []cid.Cid, bheight uint64, tickets []*types.Ticket) Rand {
|
|
||||||
return &chainRand{
|
|
||||||
cs: cs,
|
|
||||||
blks: blks,
|
|
||||||
bh: bheight,
|
|
||||||
tickets: tickets,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cr *chainRand) GetRandomness(ctx context.Context, h int64) ([]byte, error) {
|
|
||||||
lb := (int64(cr.bh) + int64(len(cr.tickets))) - h
|
|
||||||
return cr.cs.GetRandomness(ctx, cr.blks, cr.tickets, lb)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApplyRet struct {
|
type ApplyRet struct {
|
||||||
types.MessageReceipt
|
types.MessageReceipt
|
||||||
ActorErr aerrors.ActorError
|
ActorErr aerrors.ActorError
|
||||||
|
40
cli/chain.go
40
cli/chain.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
@ -279,7 +280,12 @@ var chainListCmd = &cli.Command{
|
|||||||
Usage: "View a segment of the chain",
|
Usage: "View a segment of the chain",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.Uint64Flag{Name: "height"},
|
&cli.Uint64Flag{Name: "height"},
|
||||||
&cli.UintFlag{Name: "count", Value: 30},
|
&cli.IntFlag{Name: "count", Value: 30},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "format",
|
||||||
|
Usage: "specify the format to print out tipsets",
|
||||||
|
Value: "<height>: (<time>) <blocks>",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
@ -300,15 +306,15 @@ var chainListCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
count := cctx.Uint("count")
|
count := cctx.Int("count")
|
||||||
if count < 1 {
|
if count < 1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tss := make([]*types.TipSet, count)
|
tss := make([]*types.TipSet, 0, count)
|
||||||
tss[0] = head
|
tss = append(tss, head)
|
||||||
|
|
||||||
for i := 1; i < len(tss); i++ {
|
for i := 1; i < count; i++ {
|
||||||
if head.Height() == 0 {
|
if head.Height() == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -318,18 +324,26 @@ var chainListCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tss[i] = head
|
tss = append(tss, head)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := len(tss) - 1; i >= 0; i-- {
|
for i := len(tss) - 1; i >= 0; i-- {
|
||||||
mints := tss[i].MinTimestamp()
|
printTipSet(cctx.String("format"), tss[i])
|
||||||
t := time.Unix(int64(mints), 0)
|
|
||||||
fmt.Printf("%d: (%s) [ ", tss[i].Height(), t.Format(time.Stamp))
|
|
||||||
for _, b := range tss[i].Blocks() {
|
|
||||||
fmt.Printf("%s: %s,", b.Cid(), b.Miner)
|
|
||||||
}
|
|
||||||
fmt.Println("]")
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printTipSet(format string, ts *types.TipSet) {
|
||||||
|
format = strings.ReplaceAll(format, "<height>", fmt.Sprint(ts.Height()))
|
||||||
|
format = strings.ReplaceAll(format, "<time>", time.Unix(int64(ts.MinTimestamp()), 0).Format(time.Stamp))
|
||||||
|
blks := "[ "
|
||||||
|
for _, b := range ts.Blocks() {
|
||||||
|
blks += fmt.Sprintf("%s: %s,", b.Cid(), b.Miner)
|
||||||
|
}
|
||||||
|
blks += " ]"
|
||||||
|
format = strings.ReplaceAll(format, "<blocks>", blks)
|
||||||
|
format = strings.ReplaceAll(format, "<weight>", fmt.Sprint(ts.Blocks()[0].ParentWeight))
|
||||||
|
|
||||||
|
fmt.Println(format)
|
||||||
|
}
|
||||||
|
@ -71,7 +71,7 @@ var createMinerCmd = &cli.Command{
|
|||||||
msg := &types.Message{
|
msg := &types.Message{
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
From: addr,
|
From: addr,
|
||||||
Method: actors.SMAMethods.CreateStorageMiner,
|
Method: actors.SPAMethods.CreateStorageMiner,
|
||||||
Params: params,
|
Params: params,
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(0),
|
||||||
GasPrice: types.NewInt(0),
|
GasPrice: types.NewInt(0),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
@ -32,7 +33,11 @@ var mpoolPending = &cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
fmt.Println(msg)
|
out, err := json.MarshalIndent(msg, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(string(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
38
cli/sync.go
38
cli/sync.go
@ -2,11 +2,13 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
cid "github.com/ipfs/go-cid"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain"
|
"github.com/filecoin-project/go-lotus/chain"
|
||||||
cid "github.com/ipfs/go-cid"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var syncCmd = &cli.Command{
|
var syncCmd = &cli.Command{
|
||||||
@ -14,6 +16,7 @@ var syncCmd = &cli.Command{
|
|||||||
Usage: "Inspect or interact with the chain syncer",
|
Usage: "Inspect or interact with the chain syncer",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
syncStatusCmd,
|
syncStatusCmd,
|
||||||
|
syncWaitCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,3 +52,36 @@ var syncStatusCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var syncWaitCmd = &cli.Command{
|
||||||
|
Name: "wait",
|
||||||
|
Usage: "Wait for sync to be complete",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
napi, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := ReqContext(cctx)
|
||||||
|
|
||||||
|
for {
|
||||||
|
ss, err := napi.SyncState(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var target []cid.Cid
|
||||||
|
if ss.Target != nil {
|
||||||
|
target = ss.Target.Cids()
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("\r\x1b[2KTarget: %s\tState: %s\tHeight: %d", target, chain.SyncStageString(ss.Stage), ss.Height)
|
||||||
|
if ss.Stage == api.StageSyncComplete {
|
||||||
|
fmt.Println("\nDone")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
93
cmd/chain-noise/main.go
Normal file
93
cmd/chain-noise/main.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
lcli "github.com/filecoin-project/go-lotus/cli"
|
||||||
|
|
||||||
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := &cli.App{
|
||||||
|
Name: "chain-noise",
|
||||||
|
Usage: "Generate some spam transactions in the network",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "repo",
|
||||||
|
EnvVars: []string{"LOTUS_PATH"},
|
||||||
|
Hidden: true,
|
||||||
|
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Commands: []*cli.Command{runCmd},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := app.Run(os.Args); err != nil {
|
||||||
|
fmt.Println("Error: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var runCmd = &cli.Command{
|
||||||
|
Name: "run",
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
addr, err := address.NewFromString(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer closer()
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
sendSmallFundsTxs(ctx, api, addr, 5)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendSmallFundsTxs(ctx context.Context, api api.FullNode, from address.Address, rate int) error {
|
||||||
|
var sendSet []address.Address
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
naddr, err := api.WalletNew(ctx, "bls")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sendSet = append(sendSet, naddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
tick := time.NewTicker(time.Second / time.Duration(rate))
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-tick.C:
|
||||||
|
msg := &types.Message{
|
||||||
|
From: from,
|
||||||
|
To: sendSet[rand.Intn(20)],
|
||||||
|
Value: types.NewInt(1),
|
||||||
|
GasLimit: types.NewInt(100000),
|
||||||
|
GasPrice: types.NewInt(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := api.MpoolPushMessage(ctx, msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("Message sent: ", smsg.Cid())
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
rice "github.com/GeertJohan/go.rice"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
@ -89,8 +90,9 @@ var runCmd = &cli.Command{
|
|||||||
from: from,
|
from: from,
|
||||||
}
|
}
|
||||||
|
|
||||||
http.HandleFunc("/", h.index)
|
http.Handle("/", http.FileServer(rice.MustFindBox("site").HTTPBox()))
|
||||||
http.HandleFunc("/send", h.send)
|
http.HandleFunc("/send", h.send)
|
||||||
|
http.HandleFunc("/sendcoll", h.sendColl)
|
||||||
|
|
||||||
fmt.Printf("Open http://%s\n", cctx.String("front"))
|
fmt.Printf("Open http://%s\n", cctx.String("front"))
|
||||||
|
|
||||||
@ -110,13 +112,6 @@ type handler struct {
|
|||||||
from address.Address
|
from address.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) index(w http.ResponseWriter, r *http.Request) {
|
|
||||||
fmt.Fprintf(w, "<!DOCTYPE html>\n<html><head><title>Lotus Fountain</title><style>body {font-family: 'monospace';}</style></head><body>")
|
|
||||||
fmt.Fprintf(w, "<form action='/send' method='get'>Enter destination address: ")
|
|
||||||
fmt.Fprintf(w, "<input type='text' name='address'><br><button type='submit'>Send</button>")
|
|
||||||
fmt.Fprintf(w, "</form></body></html>")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
||||||
to, err := address.NewFromString(r.FormValue("address"))
|
to, err := address.NewFromString(r.FormValue("address"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -141,3 +136,33 @@ func (h *handler) send(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
w.Write([]byte(smsg.Cid().String()))
|
w.Write([]byte(smsg.Cid().String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *handler) sendColl(w http.ResponseWriter, r *http.Request) {
|
||||||
|
to, err := address.NewFromString(r.FormValue("address"))
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(400)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
coll, err := h.api.StatePledgeCollateral(h.ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := h.api.MpoolPushMessage(h.ctx, &types.Message{
|
||||||
|
Value: coll,
|
||||||
|
From: h.from,
|
||||||
|
To: to,
|
||||||
|
|
||||||
|
GasPrice: types.NewInt(0),
|
||||||
|
GasLimit: types.NewInt(1000),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(400)
|
||||||
|
w.Write([]byte(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(smsg.Cid().String()))
|
||||||
|
}
|
||||||
|
20
cmd/lotus-fountain/site/index.html
Normal file
20
cmd/lotus-fountain/site/index.html
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Lotus Fountain</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'monospace';
|
||||||
|
background: #1f1f1f;
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form action='/send' method='get'>
|
||||||
|
<span>Enter destination address:</span>
|
||||||
|
<input type='text' name='address' style="width: 300px">
|
||||||
|
<button type='submit'>Send</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,11 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/go-lotus/cli"
|
lcli "github.com/filecoin-project/go-lotus/cli"
|
||||||
|
sectorstate "github.com/filecoin-project/go-sectorbuilder/sealing_state"
|
||||||
)
|
)
|
||||||
|
|
||||||
var infoCmd = &cli.Command{
|
var infoCmd = &cli.Command{
|
||||||
@ -17,14 +21,40 @@ var infoCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer closer()
|
defer closer()
|
||||||
|
|
||||||
|
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer acloser()
|
||||||
|
|
||||||
ctx := lcli.ReqContext(cctx)
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
aaddr, err := nodeApi.ActorAddresses(ctx)
|
maddr, err := nodeApi.ActorAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("actor address: %s\n", aaddr)
|
fmt.Printf("Miner: %s\n", maddr)
|
||||||
|
|
||||||
|
pow, err := api.StateMinerPower(ctx, maddr, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
percI := types.BigDiv(types.BigMul(pow.MinerPower, types.NewInt(1000)), pow.TotalPower)
|
||||||
|
fmt.Printf("Power: %s / %s (%0.2f%%)\n", pow.MinerPower, pow.TotalPower, float64(percI.Int64())/1000*100)
|
||||||
|
|
||||||
|
sinfo, err := sectorsInfo(ctx, nodeApi)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Sealed Sectors:\t", sinfo.SealedCount)
|
||||||
|
fmt.Println("Sealing Sectors:\t", sinfo.SealingCount)
|
||||||
|
fmt.Println("Pending Sectors:\t", sinfo.PendingCount)
|
||||||
|
fmt.Println("Failed Sectors:\t", sinfo.FailedCount)
|
||||||
|
|
||||||
// TODO: grab actr state / info
|
// TODO: grab actr state / info
|
||||||
// * Sector size
|
// * Sector size
|
||||||
// * Sealed sectors (count / bytes)
|
// * Sealed sectors (count / bytes)
|
||||||
@ -32,3 +62,42 @@ var infoCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SectorsInfo struct {
|
||||||
|
TotalCount int
|
||||||
|
SealingCount int
|
||||||
|
FailedCount int
|
||||||
|
SealedCount int
|
||||||
|
PendingCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
func sectorsInfo(ctx context.Context, napi api.StorageMiner) (*SectorsInfo, error) {
|
||||||
|
sectors, err := napi.SectorsList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := SectorsInfo{
|
||||||
|
TotalCount: len(sectors),
|
||||||
|
}
|
||||||
|
for _, s := range sectors {
|
||||||
|
st, err := napi.SectorsStatus(ctx, s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch st.State {
|
||||||
|
case sectorstate.Sealed:
|
||||||
|
out.SealedCount++
|
||||||
|
case sectorstate.Pending:
|
||||||
|
out.PendingCount++
|
||||||
|
case sectorstate.Sealing:
|
||||||
|
out.SealingCount++
|
||||||
|
case sectorstate.Failed:
|
||||||
|
out.FailedCount++
|
||||||
|
case sectorstate.Unknown:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &out, nil
|
||||||
|
}
|
||||||
|
@ -289,7 +289,7 @@ func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID, c
|
|||||||
From: owner,
|
From: owner,
|
||||||
Value: collateral,
|
Value: collateral,
|
||||||
|
|
||||||
Method: actors.SMAMethods.CreateStorageMiner,
|
Method: actors.SPAMethods.CreateStorageMiner,
|
||||||
Params: params,
|
Params: params,
|
||||||
|
|
||||||
GasLimit: types.NewInt(10000),
|
GasLimit: types.NewInt(10000),
|
||||||
@ -309,6 +309,10 @@ func createStorageMiner(ctx context.Context, api api.FullNode, peerid peer.ID, c
|
|||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mw.Receipt.ExitCode != 0 {
|
||||||
|
return address.Undef, xerrors.Errorf("create storage miner failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
addr, err = address.NewFromBytes(mw.Receipt.Return)
|
addr, err = address.NewFromBytes(mw.Receipt.Return)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return address.Undef, err
|
return address.Undef, err
|
||||||
|
@ -89,7 +89,7 @@ var sectorsStagedListCmd = &cli.Command{
|
|||||||
defer closer()
|
defer closer()
|
||||||
ctx := lcli.ReqContext(cctx)
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
staged, err := nodeApi.SectorsStagedList(ctx)
|
staged, err := nodeApi.SectorsList(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/node/modules/lp2p"
|
"github.com/filecoin-project/go-lotus/node/modules/lp2p"
|
||||||
)
|
)
|
||||||
|
|
||||||
const topic = "/fil/headnotifs/bafy2bzacedjqrkfbuafakygo6vlkrqozvsju2d5k6g24ry3mjjfxwrvet2636"
|
const topic = "/fil/headnotifs/bafy2bzacecyfz2wfi5a6d4epch6nmedrlan3mdfswgv3y74an5aeqxaq5gqlu"
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
var upgrader = websocket.Upgrader{
|
||||||
WriteBufferSize: 1024,
|
WriteBufferSize: 1024,
|
||||||
@ -49,7 +49,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pi, err := addrutil.ParseAddresses(ctx, []string{
|
pi, err := addrutil.ParseAddresses(ctx, []string{
|
||||||
"/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWAShT7qd3oM7QPC8AsQffs6ThH69fZGui4xCW68E35rDP",
|
"/ip4/147.75.80.29/tcp/1347/p2p/12D3KooWGdsbvHwscFKT1kqBeeooPe6EneJvjXzTrWSzwKhc1ssn",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -67,7 +67,7 @@ func main() {
|
|||||||
actors.LaneState{},
|
actors.LaneState{},
|
||||||
actors.PCAUpdateChannelStateParams{},
|
actors.PCAUpdateChannelStateParams{},
|
||||||
actors.PaymentInfo{},
|
actors.PaymentInfo{},
|
||||||
actors.StorageMarketState{},
|
actors.StoragePowerState{},
|
||||||
actors.CreateStorageMinerParams{},
|
actors.CreateStorageMinerParams{},
|
||||||
actors.IsMinerParam{},
|
actors.IsMinerParam{},
|
||||||
actors.PowerLookupParams{},
|
actors.PowerLookupParams{},
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -94,8 +95,22 @@ func (sb *SectorBuilder) SealStatus(sector uint64) (SectorSealingStatus, error)
|
|||||||
return sectorbuilder.GetSectorSealingStatusByID(sb.handle, sector)
|
return sectorbuilder.GetSectorSealingStatusByID(sb.handle, sector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SectorBuilder) GetAllStagedSectors() ([]StagedSectorMetadata, error) {
|
func (sb *SectorBuilder) GetAllStagedSectors() ([]uint64, error) {
|
||||||
return sectorbuilder.GetAllStagedSectors(sb.handle)
|
sectors, err := sectorbuilder.GetAllStagedSectors(sb.handle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := make([]uint64, len(sectors))
|
||||||
|
for i, v := range sectors {
|
||||||
|
out[i] = v.SectorID
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(out, func(i, j int) bool {
|
||||||
|
return out[i] < out[j]
|
||||||
|
})
|
||||||
|
|
||||||
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]byte, error) {
|
func (sb *SectorBuilder) GeneratePoSt(sectorInfo SortedSectorInfo, challengeSeed [CommLen]byte, faults []uint64) ([]byte, error) {
|
||||||
|
@ -70,7 +70,7 @@ class StorageNode extends React.Component {
|
|||||||
async loadInfo() {
|
async loadInfo() {
|
||||||
const version = await this.state.client.call("Filecoin.Version", [])
|
const version = await this.state.client.call("Filecoin.Version", [])
|
||||||
const peers = await this.state.client.call("Filecoin.NetPeers", [])
|
const peers = await this.state.client.call("Filecoin.NetPeers", [])
|
||||||
const [actor] = await this.state.client.call("Filecoin.ActorAddresses", [])
|
const actor = await this.state.client.call("Filecoin.ActorAddress", [])
|
||||||
|
|
||||||
const stActor = await this.props.fullConn.call('Filecoin.StateGetActor', [actor, null])
|
const stActor = await this.props.fullConn.call('Filecoin.StateGetActor', [actor, null])
|
||||||
const actorState = await this.props.fullConn.call('Filecoin.StateReadState', [stActor, null])
|
const actorState = await this.props.fullConn.call('Filecoin.StateReadState', [stActor, null])
|
||||||
@ -80,9 +80,9 @@ class StorageNode extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async stagedList() {
|
async stagedList() {
|
||||||
let stagedList = await this.state.client.call("Filecoin.SectorsStagedList", [])
|
let stagedList = await this.state.client.call("Filecoin.SectorsList", [])
|
||||||
let staged = await stagedList
|
let staged = await stagedList
|
||||||
.map(sector => this.state.client.call("Filecoin.SectorsStatus", [sector.SectorID]))
|
.map(sector => this.state.client.call("Filecoin.SectorsStatus", [sector]))
|
||||||
.reduce(async (p, n) => [...await p, await n], Promise.resolve([]))
|
.reduce(async (p, n) => [...await p, await n], Promise.resolve([]))
|
||||||
|
|
||||||
let statusCounts = staged.reduce((p, n) => p.map((e, i) => e + (i === n.State ? 1 : 0) ), [0, 0, 0, 0, 0])
|
let statusCounts = staged.reduce((p, n) => p.map((e, i) => e + (i === n.State ? 1 : 0) ), [0, 0, 0, 0, 0])
|
||||||
|
@ -27,6 +27,7 @@ type api struct {
|
|||||||
fx.In
|
fx.In
|
||||||
|
|
||||||
full.ChainAPI
|
full.ChainAPI
|
||||||
|
full.SyncAPI
|
||||||
full.MpoolAPI
|
full.MpoolAPI
|
||||||
full.WalletAPI
|
full.WalletAPI
|
||||||
full.StateAPI
|
full.StateAPI
|
||||||
@ -154,13 +155,13 @@ func (m *Miner) mine(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
base, err := m.GetBestMiningCandidate()
|
base, err := m.GetBestMiningCandidate(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get best mining candidate: %s", err)
|
log.Errorf("failed to get best mining candidate: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if base.ts.Equals(lastBase.ts) && len(lastBase.tickets) == len(base.tickets) {
|
if base.ts.Equals(lastBase.ts) && len(lastBase.tickets) == len(base.tickets) {
|
||||||
log.Error("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets))
|
log.Errorf("BestMiningCandidate from the previous round: %s (tkts:%d)", lastBase.ts.Cids(), len(lastBase.tickets))
|
||||||
time.Sleep(build.BlockDelay * time.Second)
|
time.Sleep(build.BlockDelay * time.Second)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -183,7 +184,7 @@ func (m *Miner) mine(ctx context.Context) {
|
|||||||
"time", time.Now(), "duration", time.Now().Sub(btime))
|
"time", time.Now(), "duration", time.Now().Sub(btime))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := m.api.ChainSubmitBlock(ctx, b); err != nil {
|
if err := m.api.SyncSubmitBlock(ctx, b); err != nil {
|
||||||
log.Errorf("failed to submit newly mined block: %s", err)
|
log.Errorf("failed to submit newly mined block: %s", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -198,8 +199,8 @@ type MiningBase struct {
|
|||||||
tickets []*types.Ticket
|
tickets []*types.Ticket
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
|
func (m *Miner) GetBestMiningCandidate(ctx context.Context) (*MiningBase, error) {
|
||||||
bts, err := m.api.ChainHead(context.TODO())
|
bts, err := m.api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -209,7 +210,16 @@ func (m *Miner) GetBestMiningCandidate() (*MiningBase, error) {
|
|||||||
return m.lastWork, nil
|
return m.lastWork, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if types.BigCmp(bts.Weight(), m.lastWork.ts.Weight()) <= 0 {
|
btsw, err := m.api.ChainTipSetWeight(ctx, bts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ltsw, err := m.api.ChainTipSetWeight(ctx, m.lastWork.ts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if types.BigCmp(btsw, ltsw) <= 0 {
|
||||||
return m.lastWork, nil
|
return m.lastWork, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package hello
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
@ -26,7 +27,7 @@ func init() {
|
|||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
HeaviestTipSet []cid.Cid
|
HeaviestTipSet []cid.Cid
|
||||||
HeaviestTipSetWeight uint64
|
HeaviestTipSetWeight types.BigInt
|
||||||
GenesisHash cid.Cid
|
GenesisHash cid.Cid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +84,10 @@ func (hs *Service) SayHello(ctx context.Context, pid peer.ID) error {
|
|||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
hts := hs.cs.GetHeaviestTipSet()
|
hts := hs.cs.GetHeaviestTipSet()
|
||||||
weight := hs.cs.Weight(hts)
|
weight, err := hs.cs.Weight(ctx, hts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
gen, err := hs.cs.GetGenesis()
|
gen, err := hs.cs.GetGenesis()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -19,25 +18,12 @@ type ChainAPI struct {
|
|||||||
WalletAPI
|
WalletAPI
|
||||||
|
|
||||||
Chain *store.ChainStore
|
Chain *store.ChainStore
|
||||||
PubSub *pubsub.PubSub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ChainAPI) ChainNotify(ctx context.Context) (<-chan []*store.HeadChange, error) {
|
func (a *ChainAPI) ChainNotify(ctx context.Context) (<-chan []*store.HeadChange, error) {
|
||||||
return a.Chain.SubHeadChanges(ctx), nil
|
return a.Chain.SubHeadChanges(ctx), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *ChainAPI) ChainSubmitBlock(ctx context.Context, blk *types.BlockMsg) error {
|
|
||||||
// TODO: should we have some sort of fast path to adding a local block?
|
|
||||||
|
|
||||||
b, err := blk.Serialize()
|
|
||||||
if err != nil {
|
|
||||||
return xerrors.Errorf("serializing block for pubsub publishing failed: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: anything else to do here?
|
|
||||||
return a.PubSub.Publish("/fil/blocks", b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
func (a *ChainAPI) ChainHead(context.Context) (*types.TipSet, error) {
|
||||||
return a.Chain.GetHeaviestTipSet(), nil
|
return a.Chain.GetHeaviestTipSet(), nil
|
||||||
}
|
}
|
||||||
@ -174,3 +160,7 @@ func (a *ChainAPI) ChainGetGenesis(ctx context.Context) (*types.TipSet, error) {
|
|||||||
|
|
||||||
return types.NewTipSet([]*types.BlockHeader{genb})
|
return types.NewTipSet([]*types.BlockHeader{genb})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *ChainAPI) ChainTipSetWeight(ctx context.Context, ts *types.TipSet) (types.BigInt, error) {
|
||||||
|
return a.Chain.Weight(ctx, ts)
|
||||||
|
}
|
||||||
|
@ -92,7 +92,7 @@ func (a *StateAPI) StatePledgeCollateral(ctx context.Context, ts *types.TipSet)
|
|||||||
ret, aerr := a.StateManager.Call(ctx, &types.Message{
|
ret, aerr := a.StateManager.Call(ctx, &types.Message{
|
||||||
From: actors.StorageMarketAddress,
|
From: actors.StorageMarketAddress,
|
||||||
To: actors.StorageMarketAddress,
|
To: actors.StorageMarketAddress,
|
||||||
Method: actors.SMAMethods.PledgeCollateralForSize,
|
Method: actors.SPAMethods.PledgeCollateralForSize,
|
||||||
|
|
||||||
Params: param,
|
Params: param,
|
||||||
}, ts)
|
}, ts)
|
||||||
@ -209,7 +209,7 @@ func (a *StateAPI) StateWaitMsg(ctx context.Context, msg cid.Cid) (*api.MsgWait,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
func (a *StateAPI) StateListMiners(ctx context.Context, ts *types.TipSet) ([]address.Address, error) {
|
||||||
var state actors.StorageMarketState
|
var state actors.StoragePowerState
|
||||||
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
if _, err := a.StateManager.LoadActorState(ctx, actors.StorageMarketAddress, &state, ts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,18 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/api"
|
"github.com/filecoin-project/go-lotus/api"
|
||||||
"github.com/filecoin-project/go-lotus/chain"
|
"github.com/filecoin-project/go-lotus/chain"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
|
||||||
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SyncAPI struct {
|
type SyncAPI struct {
|
||||||
fx.In
|
fx.In
|
||||||
|
|
||||||
Syncer *chain.Syncer
|
Syncer *chain.Syncer
|
||||||
|
PubSub *pubsub.PubSub
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SyncAPI) SyncState(ctx context.Context) (*api.SyncState, error) {
|
func (a *SyncAPI) SyncState(ctx context.Context) (*api.SyncState, error) {
|
||||||
@ -23,3 +28,42 @@ func (a *SyncAPI) SyncState(ctx context.Context) (*api.SyncState, error) {
|
|||||||
Height: ss.Height,
|
Height: ss.Height,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) error {
|
||||||
|
// TODO: should we have some sort of fast path to adding a local block?
|
||||||
|
bmsgs, err := a.Syncer.ChainStore().LoadMessagesFromCids(blk.BlsMessages)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to load bls messages: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
smsgs, err := a.Syncer.ChainStore().LoadSignedMessagesFromCids(blk.SecpkMessages)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to load secpk message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fb := &types.FullBlock{
|
||||||
|
Header: blk.Header,
|
||||||
|
BlsMessages: bmsgs,
|
||||||
|
SecpkMessages: smsgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.Syncer.ValidateMsgMeta(fb); err != nil {
|
||||||
|
xerrors.Errorf("provided messages did not match block: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts, err := types.NewTipSet([]*types.BlockHeader{blk.Header})
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("somehow failed to make a tipset out of a single block: %w", err)
|
||||||
|
}
|
||||||
|
if err := a.Syncer.Sync(ctx, ts); err != nil {
|
||||||
|
return xerrors.Errorf("sync to submitted block failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := blk.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("serializing block for pubsub publishing failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: anything else to do here?
|
||||||
|
return a.PubSub.Publish("/fil/blocks", b)
|
||||||
|
}
|
||||||
|
@ -26,8 +26,8 @@ type StorageMinerAPI struct {
|
|||||||
Miner *storage.Miner
|
Miner *storage.Miner
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StorageMinerAPI) ActorAddresses(context.Context) ([]address.Address, error) {
|
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
|
||||||
return []address.Address{sm.SectorBuilderConfig.Miner}, nil
|
return sm.SectorBuilderConfig.Miner, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) (uint64, error) {
|
func (sm *StorageMinerAPI) StoreGarbageData(ctx context.Context) (uint64, error) {
|
||||||
@ -47,7 +47,7 @@ func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid uint64) (secto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List all staged sectors
|
// List all staged sectors
|
||||||
func (sm *StorageMinerAPI) SectorsStagedList(context.Context) ([]sectorbuilder.StagedSectorMetadata, error) {
|
func (sm *StorageMinerAPI) SectorsList(context.Context) ([]uint64, error) {
|
||||||
return sm.SectorBuilder.GetAllStagedSectors()
|
return sm.SectorBuilder.GetAllStagedSectors()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
scripts/deploy-miner.sh
Executable file
16
scripts/deploy-miner.sh
Executable file
@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
HOST=$1
|
||||||
|
|
||||||
|
ssh "$HOST" 'lotus wallet new bls > addr'
|
||||||
|
ssh "$HOST" 'curl http://147.75.80.29:777/sendcoll?address=$(cat addr)' &
|
||||||
|
ssh "$HOST" 'curl http://147.75.80.29:777/sendcoll?address=$(cat addr)' &
|
||||||
|
ssh "$HOST" 'curl http://147.75.80.29:777/send?address=$(cat addr)' &
|
||||||
|
wait
|
||||||
|
|
||||||
|
echo "SYNC WAIT"
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
ssh "$HOST" 'lotus sync wait'
|
||||||
|
ssh "$HOST" 'lotus-storage-miner init --owner=$(cat addr)'
|
||||||
|
ssh "$HOST" 'systemctl start lotus-storage-miner' &
|
23
scripts/deploy-node.sh
Executable file
23
scripts/deploy-node.sh
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
HOST=$1
|
||||||
|
|
||||||
|
# upload binaries
|
||||||
|
# TODO: destroy
|
||||||
|
|
||||||
|
ssh "$HOST" 'systemctl stop lotus-storage-miner'
|
||||||
|
ssh "$HOST" 'systemctl stop lotus-daemon'
|
||||||
|
|
||||||
|
ssh "$HOST" 'mkdir -p .lotus .lotusstorage' &
|
||||||
|
scp "./lotus" "$HOST:/usr/local/bin" &
|
||||||
|
scp "./lotus-storage-miner" "$HOST:/usr/local/bin" &
|
||||||
|
scp -C scripts/daemon.service "${HOST}:/etc/systemd/system/lotus-daemon.service" &
|
||||||
|
scp -C scripts/sminer.service "${HOST}:/etc/systemd/system/lotus-storage-miner.service" &
|
||||||
|
wait
|
||||||
|
|
||||||
|
ssh "$HOST" 'systemctl daemon-reload'
|
||||||
|
ssh "$HOST" 'systemctl start lotus-daemon' &
|
||||||
|
wait
|
||||||
|
|
||||||
|
|
||||||
|
# setup miner actor
|
Loading…
Reference in New Issue
Block a user