fix account balances to make tests pass
This commit is contained in:
parent
2d5b88ce84
commit
3154374132
@ -21,7 +21,7 @@ type StorageMarketActor struct{}
|
|||||||
type smaMethods struct {
|
type smaMethods struct {
|
||||||
Constructor uint64
|
Constructor uint64
|
||||||
CreateStorageMiner uint64
|
CreateStorageMiner uint64
|
||||||
SlashConsensusFault uint64
|
ArbitrateConsensusFault uint64
|
||||||
UpdateStorage uint64
|
UpdateStorage uint64
|
||||||
GetTotalStorage uint64
|
GetTotalStorage uint64
|
||||||
PowerLookup uint64
|
PowerLookup uint64
|
||||||
@ -35,7 +35,7 @@ func (sma StorageMarketActor) Exports() []interface{} {
|
|||||||
return []interface{}{
|
return []interface{}{
|
||||||
//1: sma.StorageMarketConstructor,
|
//1: sma.StorageMarketConstructor,
|
||||||
2: sma.CreateStorageMiner,
|
2: sma.CreateStorageMiner,
|
||||||
3: sma.SlashConsensusFault,
|
3: sma.ArbitrateConsensusFault,
|
||||||
4: sma.UpdateStorage,
|
4: sma.UpdateStorage,
|
||||||
5: sma.GetTotalStorage,
|
5: sma.GetTotalStorage,
|
||||||
6: sma.PowerLookup,
|
6: sma.PowerLookup,
|
||||||
@ -124,56 +124,12 @@ func SupportedSectorSize(ssize types.BigInt) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type SlashConsensusFaultParams struct {
|
type ArbitrateConsensusFaultParams struct {
|
||||||
Block1 *types.BlockHeader
|
Block1 *types.BlockHeader
|
||||||
Block2 *types.BlockHeader
|
Block2 *types.BlockHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
func cidArrContains(a []cid.Cid, b cid.Cid) bool {
|
func (sma StorageMarketActor) ArbitrateConsensusFault(act *types.Actor, vmctx types.VMContext, params *ArbitrateConsensusFaultParams) ([]byte, ActorError) {
|
||||||
for _, c := range a {
|
|
||||||
if b == c {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldSlash(block1, block2 *types.BlockHeader) bool {
|
|
||||||
// First slashing condition, blocks have the same ticket round
|
|
||||||
if block1.Height == block2.Height {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Second slashing condition requires having access to the parent tipset blocks
|
|
||||||
// This might not always be available, needs some thought on the best way to deal with this
|
|
||||||
|
|
||||||
|
|
||||||
// Second slashing condition, miner ignored own block when mining
|
|
||||||
// Case A: block2 could have been in block1's parent set but is not
|
|
||||||
b1ParentHeight := block1.Height - len(block1.Tickets)
|
|
||||||
|
|
||||||
block1ParentTipSet := block1.Parents
|
|
||||||
if !cidArrContains(block1.Parents, block2.Cid()) &&
|
|
||||||
b1ParentHeight == block2.Height &&
|
|
||||||
block1ParentTipSet.ParentCids == block2.ParentCids {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case B: block1 could have been in block2's parent set but is not
|
|
||||||
block2ParentTipSet := parentOf(block2)
|
|
||||||
if !block2Parent.contains(block1) &&
|
|
||||||
block2ParentTipSet.Height == block1.Height &&
|
|
||||||
block2ParentTipSet.ParentCids == block1.ParentCids {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.VMContext, params *SlashConsensusFaultParams) ([]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")
|
||||||
}
|
}
|
||||||
@ -266,6 +222,50 @@ func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cidArrContains(a []cid.Cid, b cid.Cid) bool {
|
||||||
|
for _, c := range a {
|
||||||
|
if b == c {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldSlash(block1, block2 *types.BlockHeader) bool {
|
||||||
|
// First slashing condition, blocks have the same ticket round
|
||||||
|
if block1.Height == block2.Height {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Second slashing condition requires having access to the parent tipset blocks
|
||||||
|
// This might not always be available, needs some thought on the best way to deal with this
|
||||||
|
|
||||||
|
|
||||||
|
// Second slashing condition, miner ignored own block when mining
|
||||||
|
// Case A: block2 could have been in block1's parent set but is not
|
||||||
|
b1ParentHeight := block1.Height - len(block1.Tickets)
|
||||||
|
|
||||||
|
block1ParentTipSet := block1.Parents
|
||||||
|
if !cidArrContains(block1.Parents, block2.Cid()) &&
|
||||||
|
b1ParentHeight == block2.Height &&
|
||||||
|
block1ParentTipSet.ParentCids == block2.ParentCids {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case B: block1 could have been in block2's parent set but is not
|
||||||
|
block2ParentTipSet := parentOf(block2)
|
||||||
|
if !block2Parent.contains(block1) &&
|
||||||
|
block2ParentTipSet.Height == block1.Height &&
|
||||||
|
block2ParentTipSet.ParentCids == block1.ParentCids {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateStorageParams struct {
|
type UpdateStorageParams struct {
|
||||||
Delta types.BigInt
|
Delta types.BigInt
|
||||||
}
|
}
|
||||||
@ -412,13 +412,18 @@ func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.Big
|
|||||||
types.NewInt(build.CollateralPrecision),
|
types.NewInt(build.CollateralPrecision),
|
||||||
)
|
)
|
||||||
|
|
||||||
powerCollateral := types.BigDiv(
|
// REVIEW: for bootstrapping purposes, we skip the power portion of the
|
||||||
types.BigMul(
|
// collateral if there is no collateral in the network yet
|
||||||
totalPowerCollateral,
|
powerCollateral := types.NewInt(0)
|
||||||
size,
|
if types.BigCmp(totalStorage, types.NewInt(0)) != 0 {
|
||||||
),
|
powerCollateral = types.BigDiv(
|
||||||
totalStorage,
|
types.BigMul(
|
||||||
)
|
totalPowerCollateral,
|
||||||
|
size,
|
||||||
|
),
|
||||||
|
totalStorage,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
perCapCollateral := types.BigDiv(
|
perCapCollateral := types.BigDiv(
|
||||||
totalPerCapitaCollateral,
|
totalPerCapitaCollateral,
|
||||||
|
@ -11,10 +11,12 @@ import (
|
|||||||
. "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"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/go-lotus/chain/vm"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
cid "github.com/ipfs/go-cid"
|
||||||
hamt "github.com/ipfs/go-hamt-ipld"
|
hamt "github.com/ipfs/go-hamt-ipld"
|
||||||
|
bstore "github.com/ipfs/go-ipfs-blockstore"
|
||||||
cbor "github.com/ipfs/go-ipld-cbor"
|
cbor "github.com/ipfs/go-ipld-cbor"
|
||||||
mh "github.com/multiformats/go-multihash"
|
mh "github.com/multiformats/go-multihash"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -33,7 +35,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
var minerAddr address.Address
|
var minerAddr address.Address
|
||||||
{
|
{
|
||||||
// cheating the bootstrapping problem
|
// cheating the bootstrapping problem
|
||||||
cheatStorageMarketTotal(t, h)
|
cheatStorageMarketTotal(t, h.vm, h.cs.Blockstore())
|
||||||
|
|
||||||
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
||||||
types.NewInt(500000),
|
types.NewInt(500000),
|
||||||
@ -91,8 +93,8 @@ 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.SlashConsensusFault,
|
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.ArbitrateConsensusFault,
|
||||||
&SlashConsensusFaultParams{
|
&ArbitrateConsensusFaultParams{
|
||||||
Block1: b1,
|
Block1: b1,
|
||||||
Block2: b2,
|
Block2: b2,
|
||||||
})
|
})
|
||||||
@ -112,15 +114,15 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cheatStorageMarketTotal(t *testing.T, h *Harness) {
|
func cheatStorageMarketTotal(t *testing.T, vm *vm.VM, bs bstore.Blockstore) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
sma, err := h.vm.StateTree().GetActor(StorageMarketAddress)
|
sma, err := vm.StateTree().GetActor(StorageMarketAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cst := hamt.CSTFromBstore(h.cs.Blockstore())
|
cst := hamt.CSTFromBstore(bs)
|
||||||
|
|
||||||
var smastate StorageMarketState
|
var smastate StorageMarketState
|
||||||
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
|
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
|
||||||
@ -136,7 +138,7 @@ func cheatStorageMarketTotal(t *testing.T, h *Harness) {
|
|||||||
|
|
||||||
sma.Head = c
|
sma.Head = c
|
||||||
|
|
||||||
if err := h.vm.StateTree().SetActor(StorageMarketAddress, sma); err != nil {
|
if err := vm.StateTree().SetActor(StorageMarketAddress, sma); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package actors_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/build"
|
"github.com/filecoin-project/go-lotus/build"
|
||||||
@ -29,7 +30,7 @@ func blsaddr(n uint64) address.Address {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address) {
|
func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address, bstore.Blockstore) {
|
||||||
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
|
bs := bstore.NewBlockstore(dstore.NewMapDatastore())
|
||||||
|
|
||||||
from := blsaddr(0)
|
from := blsaddr(0)
|
||||||
@ -55,11 +56,11 @@ func setupVMTestEnv(t *testing.T) (*vm.VM, []address.Address) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
return vm, []address.Address{from, maddr}
|
return vm, []address.Address{from, maddr}, bs
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVMInvokeMethod(t *testing.T) {
|
func TestVMInvokeMethod(t *testing.T) {
|
||||||
vm, addrs := setupVMTestEnv(t)
|
vm, addrs, _ := setupVMTestEnv(t)
|
||||||
from := addrs[0]
|
from := addrs[0]
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@ -107,10 +108,12 @@ func TestVMInvokeMethod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStorageMarketActorCreateMiner(t *testing.T) {
|
func TestStorageMarketActorCreateMiner(t *testing.T) {
|
||||||
vm, addrs := setupVMTestEnv(t)
|
vm, addrs, bs := setupVMTestEnv(t)
|
||||||
from := addrs[0]
|
from := addrs[0]
|
||||||
maddr := addrs[1]
|
maddr := addrs[1]
|
||||||
|
|
||||||
|
cheatStorageMarketTotal(t, vm, bs)
|
||||||
|
|
||||||
params := &StorageMinerConstructorParams{
|
params := &StorageMinerConstructorParams{
|
||||||
Worker: maddr,
|
Worker: maddr,
|
||||||
SectorSize: types.NewInt(build.SectorSize),
|
SectorSize: types.NewInt(build.SectorSize),
|
||||||
@ -129,7 +132,7 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
|
|||||||
Params: enc,
|
Params: enc,
|
||||||
GasPrice: types.NewInt(1),
|
GasPrice: types.NewInt(1),
|
||||||
GasLimit: types.NewInt(10000),
|
GasLimit: types.NewInt(10000),
|
||||||
Value: types.NewInt(0),
|
Value: types.NewInt(50000),
|
||||||
}
|
}
|
||||||
|
|
||||||
ret, err := vm.ApplyMessage(context.TODO(), msg)
|
ret, err := vm.ApplyMessage(context.TODO(), msg)
|
||||||
@ -138,6 +141,7 @@ func TestStorageMarketActorCreateMiner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ret.ExitCode != 0 {
|
if ret.ExitCode != 0 {
|
||||||
|
fmt.Println(ret.ActorErr)
|
||||||
t.Fatal("invocation failed: ", ret.ExitCode)
|
t.Fatal("invocation failed: ", ret.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2664,7 +2664,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *SlashConsensusFaultParams) MarshalCBOR(w io.Writer) error {
|
func (t *ArbitrateConsensusFaultParams) 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
|
||||||
@ -2685,7 +2685,7 @@ func (t *SlashConsensusFaultParams) MarshalCBOR(w io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *SlashConsensusFaultParams) UnmarshalCBOR(r io.Reader) error {
|
func (t *ArbitrateConsensusFaultParams) 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)
|
||||||
|
@ -129,7 +129,7 @@ func NewGenerator() (*ChainGen, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
|
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
|
||||||
worker: types.NewInt(50000),
|
worker: types.NewInt(50000000),
|
||||||
banker: types.NewInt(90000000),
|
banker: types.NewInt(90000000),
|
||||||
}, minercfg, 100000)
|
}, minercfg, 100000)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -200,7 +200,9 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
PeerID: pid,
|
PeerID: pid,
|
||||||
})
|
})
|
||||||
|
|
||||||
rval, err := doExec(ctx, vm, actors.StorageMarketAddress, owner, actors.SMAMethods.CreateStorageMiner, params)
|
// TODO: hardcoding 7000000 here is a little fragile, it changes any
|
||||||
|
// time anyone changes the initial account allocations
|
||||||
|
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.NewInt(7000000), actors.SMAMethods.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)
|
||||||
}
|
}
|
||||||
@ -255,6 +257,10 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) {
|
func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uint64, params []byte) ([]byte, error) {
|
||||||
|
return doExecValue(ctx, vm, to, from, types.NewInt(0), method, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doExecValue(ctx context.Context, vm *vm.VM, to, from address.Address, value types.BigInt, method uint64, params []byte) ([]byte, error) {
|
||||||
act, err := vm.StateTree().GetActor(from)
|
act, err := vm.StateTree().GetActor(from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
|
return nil, xerrors.Errorf("doExec failed to get from actor: %w", err)
|
||||||
@ -267,7 +273,7 @@ func doExec(ctx context.Context, vm *vm.VM, to, from address.Address, method uin
|
|||||||
Params: params,
|
Params: params,
|
||||||
GasLimit: types.NewInt(1000000),
|
GasLimit: types.NewInt(1000000),
|
||||||
GasPrice: types.NewInt(0),
|
GasPrice: types.NewInt(0),
|
||||||
Value: types.NewInt(0),
|
Value: value,
|
||||||
Nonce: act.Nonce,
|
Nonce: act.Nonce,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,7 +72,7 @@ func main() {
|
|||||||
actors.IsMinerParam{},
|
actors.IsMinerParam{},
|
||||||
actors.PowerLookupParams{},
|
actors.PowerLookupParams{},
|
||||||
actors.UpdateStorageParams{},
|
actors.UpdateStorageParams{},
|
||||||
actors.SlashConsensusFaultParams{},
|
actors.ArbitrateConsensusFaultParams{},
|
||||||
actors.PledgeCollateralParams{},
|
actors.PledgeCollateralParams{},
|
||||||
actors.MinerSlashConsensusFault{},
|
actors.MinerSlashConsensusFault{},
|
||||||
)
|
)
|
||||||
|
@ -40,7 +40,7 @@ func MakeGenesisMem(out io.Writer) func(bs dtypes.ChainBlockstore, w *wallet.Wal
|
|||||||
PeerIDs: []peer.ID{"peerID 1"},
|
PeerIDs: []peer.ID{"peerID 1"},
|
||||||
}
|
}
|
||||||
alloc := map[address.Address]types.BigInt{
|
alloc := map[address.Address]types.BigInt{
|
||||||
w: types.NewInt(100000),
|
w: types.NewInt(10000000),
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := gen.MakeGenesisBlock(bs, alloc, gmc, 100000)
|
b, err := gen.MakeGenesisBlock(bs, alloc, gmc, 100000)
|
||||||
|
Loading…
Reference in New Issue
Block a user