fix account balances to make tests pass

This commit is contained in:
whyrusleeping 2019-09-12 18:06:06 -07:00
parent 2d5b88ce84
commit 3154374132
8 changed files with 91 additions and 74 deletions

View File

@ -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,

View File

@ -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)
} }
} }

View File

@ -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)
} }

View File

@ -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)

View File

@ -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 {

View File

@ -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 {

View File

@ -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{},
) )

View File

@ -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)