slash consensus fault needs to also be a method on the miner
This commit is contained in:
parent
fe020d9fd1
commit
197a2a3025
@ -17,7 +17,11 @@ const RandomnessLookback = 20
|
||||
const ProvingPeriodDuration = 2 * 60 // an hour, for now
|
||||
const PoSTChallangeTime = 1 * 60
|
||||
|
||||
const PowerCollateralProportion = 0.2
|
||||
const PerCapitaCollateralProportion = 0.05
|
||||
const PowerCollateralProportion = 20
|
||||
const PerCapitaCollateralProportion = 5
|
||||
const CollateralPrecision = 100
|
||||
|
||||
const TotalFilecoin = 2000000000
|
||||
const FilecoinPrecision = 1000000000000000000
|
||||
|
||||
// TODO: Move other important consts here
|
||||
|
@ -3,6 +3,7 @@ package actors
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||
@ -121,9 +122,10 @@ type maMethods struct {
|
||||
PaymentVerifyInclusion uint64
|
||||
PaymentVerifySector uint64
|
||||
AddFaults uint64
|
||||
SlashConsensusFault uint64
|
||||
}
|
||||
|
||||
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
|
||||
var MAMethods = maMethods{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
|
||||
|
||||
func (sma StorageMinerActor) Exports() []interface{} {
|
||||
return []interface{}{
|
||||
@ -146,6 +148,7 @@ func (sma StorageMinerActor) Exports() []interface{} {
|
||||
17: sma.PaymentVerifyInclusion,
|
||||
18: sma.PaymentVerifySector,
|
||||
19: nil,
|
||||
20: sma.SlashConsensusFault,
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,3 +705,57 @@ func (sma StorageMinerActor) PaymentVerifySector(act *types.Actor, vmctx types.V
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type MinerSlashConsensusFault struct {
|
||||
Slasher address.Address
|
||||
AtHeight uint64
|
||||
SlashedCollateral types.BigInt
|
||||
}
|
||||
|
||||
func (sma StorageMinerActor) SlashConsensusFault(act *types.Actor, vmctx types.VMContext, params *MinerSlashConsensusFault) ([]byte, ActorError) {
|
||||
if vmctx.Message().From != StorageMarketAddress {
|
||||
return nil, aerrors.New(1, "SlashConsensusFault may only be called by the storage market actor")
|
||||
}
|
||||
|
||||
slashedCollateral := params.SlashedCollateral
|
||||
if types.BigCmp(slashedCollateral, act.Balance) < 0 {
|
||||
slashedCollateral = act.Balance
|
||||
}
|
||||
|
||||
// Some of the slashed collateral should be paid to the slasher
|
||||
// GROWTH_RATE determines how fast the slasher share of slashed collateral will increase as block elapses
|
||||
// current GROWTH_RATE results in SLASHER_SHARE reaches 1 after 30 blocks
|
||||
// TODO: define arithmetic precision and rounding for this operation
|
||||
blockElapsed := vmctx.BlockHeight() - params.AtHeight
|
||||
growthRate := 1.26
|
||||
initialShare := 0.001
|
||||
|
||||
// REVIEW: floating point precision loss anyone?
|
||||
slasherPortion := initialShare * math.Pow(growthRate, float64(blockElapsed))
|
||||
if slasherPortion > 1 {
|
||||
slasherPortion = 1
|
||||
}
|
||||
|
||||
const precision = 1000000
|
||||
slasherShare := types.BigDiv(types.BigMul(types.NewInt(uint64(precision*slasherPortion)), slashedCollateral), types.NewInt(precision))
|
||||
burnPortion := types.BigSub(slashedCollateral, slasherShare)
|
||||
|
||||
_, err := vmctx.Send(vmctx.Message().From, 0, slasherShare, nil)
|
||||
if err != nil {
|
||||
return nil, aerrors.Wrap(err, "failed to pay slasher")
|
||||
}
|
||||
|
||||
_, err = vmctx.Send(BurntFundsAddress, 0, burnPortion, nil)
|
||||
if err != nil {
|
||||
return nil, aerrors.Wrap(err, "failed to burn funds")
|
||||
}
|
||||
|
||||
// TODO: this still allows the miner to commit sectors and submit posts,
|
||||
// their users could potentially be unaffected, but the miner will never be
|
||||
// able to mine a block again
|
||||
// One potential issue: the miner will have to pay back the slashed
|
||||
// collateral to continue submitting PoSts, which includes pledge
|
||||
// collateral that they no longer really 'need'
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -3,18 +3,17 @@ package actors
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
"github.com/filecoin-project/go-lotus/chain/actors/aerrors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
"github.com/filecoin-project/go-lotus/chain/types"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
xerrors "golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
type StorageMarketActor struct{}
|
||||
@ -64,6 +63,21 @@ func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.V
|
||||
return nil, aerrors.New(1, "Unsupported sector size")
|
||||
}
|
||||
|
||||
var self StorageMarketState
|
||||
old := vmctx.Storage().GetHead()
|
||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reqColl, err := pledgeCollateralForSize(vmctx, types.NewInt(0), self.TotalStorage, self.MinerCount+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if types.BigCmp(vmctx.Message().Value, reqColl) < 0 {
|
||||
return nil, aerrors.Newf(1, "not enough funds passed to cover required miner collateral (needed %s, got %s)", reqColl, vmctx.Message().Value)
|
||||
}
|
||||
|
||||
encoded, err := CreateExecParams(StorageMinerCodeCid, &StorageMinerConstructorParams{
|
||||
Owner: params.Owner,
|
||||
Worker: params.Worker,
|
||||
@ -81,13 +95,7 @@ func (sma StorageMarketActor) CreateStorageMiner(act *types.Actor, vmctx types.V
|
||||
|
||||
naddr, nerr := address.NewFromBytes(ret)
|
||||
if nerr != nil {
|
||||
return nil, aerrors.Absorb(nerr, 1, "could not read address of new actor")
|
||||
}
|
||||
|
||||
var self StorageMarketState
|
||||
old := vmctx.Storage().GetHead()
|
||||
if err := vmctx.Storage().Get(old, &self); err != nil {
|
||||
return nil, err
|
||||
return nil, aerrors.Absorb(nerr, 2, "could not read address of new actor")
|
||||
}
|
||||
|
||||
ncid, err := MinerSetAdd(context.TODO(), vmctx, self.Miners, naddr)
|
||||
@ -178,21 +186,21 @@ func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.
|
||||
worker, oerr := address.NewFromBytes(rval)
|
||||
if oerr != nil {
|
||||
// REVIEW: should this be fatal? i can't think of a real situation that would get us here
|
||||
return nil, aerrors.Escalate(oerr, "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 {
|
||||
return nil, aerrors.Absorb(err, 3, "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 {
|
||||
return nil, aerrors.Absorb(err, 4, "block2 did not have valid signature")
|
||||
return nil, aerrors.Absorb(err, 5, "block2 did not have valid signature")
|
||||
}
|
||||
|
||||
// see the "Consensus Faults" section of the faults spec (faults.md)
|
||||
// for details on these slashing conditions.
|
||||
if !shouldSlash(params.Block1, params.Block2) {
|
||||
return nil, aerrors.New(5, "blocks do not prove a slashable offense")
|
||||
return nil, aerrors.New(6, "blocks do not prove a slashable offense")
|
||||
}
|
||||
|
||||
var self StorageMarketState
|
||||
@ -209,12 +217,7 @@ func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.
|
||||
if has, err := MinerSetHas(context.TODO(), vmctx, self.Miners, miner); err != nil {
|
||||
return nil, aerrors.Wrapf(err, "failed to check miner in set")
|
||||
} else if !has {
|
||||
return nil, aerrors.New(6, "either already slashed or not a miner")
|
||||
}
|
||||
|
||||
minerBalance, err := vmctx.GetBalance(miner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, aerrors.New(7, "either already slashed or not a miner")
|
||||
}
|
||||
|
||||
minerPower, err := powerLookup(context.TODO(), vmctx, &self, miner)
|
||||
@ -222,36 +225,23 @@ func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slashedCollateral := pledgeCollateralForSize(minerPower, self.TotalStorage, self.MinerCount)
|
||||
if types.BigCmp(slashedCollateral, minerBalance) < 0 {
|
||||
slashedCollateral = minerBalance
|
||||
}
|
||||
|
||||
// Some of the slashed collateral should be paid to the slasher
|
||||
// GROWTH_RATE determines how fast the slasher share of slashed collateral will increase as block elapses
|
||||
// current GROWTH_RATE results in SLASHER_SHARE reaches 1 after 30 blocks
|
||||
// TODO: define arithmetic precision and rounding for this operation
|
||||
blockElapsed := vmctx.BlockHeight() - params.Block1.Height
|
||||
growthRate := 1.26
|
||||
initialShare := 0.001
|
||||
|
||||
// REVIEW: floating point precision loss anyone?
|
||||
slasherPortion := initialShare * math.Pow(growthRate, float64(blockElapsed))
|
||||
if slasherPortion > 1 {
|
||||
slasherPortion = 1
|
||||
}
|
||||
|
||||
slasherShare := types.BigDiv(types.BigMul(types.NewInt(uint64(1000000*slasherPortion)), slashedCollateral), types.NewInt(1000000))
|
||||
burnPortion := types.BigSub(slashedCollateral, slasherShare)
|
||||
|
||||
_, err = vmctx.Send(vmctx.Message().From, 0, slasherShare, nil)
|
||||
slashedCollateral, err := pledgeCollateralForSize(vmctx, minerPower, self.TotalStorage, self.MinerCount)
|
||||
if err != nil {
|
||||
return nil, aerrors.Wrap(err, "failed to pay slasher")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = vmctx.Send(BurntFundsAddress, 0, burnPortion, nil)
|
||||
enc, err := SerializeParams(&MinerSlashConsensusFault{
|
||||
Slasher: vmctx.Message().From,
|
||||
AtHeight: params.Block1.Height,
|
||||
SlashedCollateral: slashedCollateral,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, aerrors.Wrap(err, "failed to burn funds")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = vmctx.Send(miner, MAMethods.SlashConsensusFault, types.NewInt(0), enc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Remove the miner from the list of network miners
|
||||
@ -264,6 +254,15 @@ func (sma StorageMarketActor) SlashConsensusFault(act *types.Actor, vmctx types.
|
||||
|
||||
self.TotalStorage = types.BigSub(self.TotalStorage, minerPower)
|
||||
|
||||
nroot, err := vmctx.Storage().Put(&self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := vmctx.Storage().Commit(old, nroot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -374,22 +373,59 @@ func (sma StorageMarketActor) PledgeCollateralForSize(act *types.Actor, vmctx ty
|
||||
return nil, err
|
||||
}
|
||||
|
||||
totalCollateral := pledgeCollateralForSize(param.Size, self.TotalStorage, self.MinerCount)
|
||||
totalCollateral, err := pledgeCollateralForSize(vmctx, param.Size, self.TotalStorage, self.MinerCount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return totalCollateral.Bytes(), nil
|
||||
}
|
||||
|
||||
func pledgeCollateralForSize(size, totalStorage types.BigInt, minerCount uint64) types.BigInt {
|
||||
func pledgeCollateralForSize(vmctx types.VMContext, size, totalStorage types.BigInt, minerCount uint64) (types.BigInt, aerrors.ActorError) {
|
||||
netBalance, err := vmctx.GetBalance(NetworkAddress)
|
||||
if err != nil {
|
||||
return types.EmptyInt, err
|
||||
}
|
||||
|
||||
availableFilecoin := types.NewInt(5000000) // TODO: get actual available filecoin amount
|
||||
// TODO: the spec says to also grab 'total vested filecoin' and include it as available
|
||||
// If we don't factor that in, we effectively assume all of the locked up filecoin is 'available'
|
||||
// the blocker on that right now is that its hard to tell how much filecoin is unlocked
|
||||
|
||||
totalPowerCollateral := types.BigDiv(types.BigMul(availableFilecoin, types.NewInt(uint64(float64(100*build.PowerCollateralProportion)))), types.NewInt(100))
|
||||
totalPerCapitaCollateral := types.BigDiv(types.BigMul(availableFilecoin, types.NewInt(uint64(float64(100*build.PowerCollateralProportion)))), types.NewInt(100))
|
||||
availableFilecoin := types.BigSub(
|
||||
types.BigMul(types.NewInt(build.TotalFilecoin), types.NewInt(build.FilecoinPrecision)),
|
||||
netBalance,
|
||||
)
|
||||
|
||||
powerCollateral := types.BigDiv(types.BigMul(totalPowerCollateral, size), totalStorage)
|
||||
perCapCollateral := types.BigDiv(totalPerCapitaCollateral, types.NewInt(minerCount))
|
||||
totalPowerCollateral := types.BigDiv(
|
||||
types.BigMul(
|
||||
availableFilecoin,
|
||||
types.NewInt(build.PowerCollateralProportion),
|
||||
),
|
||||
types.NewInt(build.CollateralPrecision),
|
||||
)
|
||||
|
||||
return types.BigAdd(powerCollateral, perCapCollateral)
|
||||
totalPerCapitaCollateral := types.BigDiv(
|
||||
types.BigMul(
|
||||
availableFilecoin,
|
||||
types.NewInt(build.PerCapitaCollateralProportion),
|
||||
),
|
||||
types.NewInt(build.CollateralPrecision),
|
||||
)
|
||||
|
||||
powerCollateral := types.BigDiv(
|
||||
types.BigMul(
|
||||
totalPowerCollateral,
|
||||
size,
|
||||
),
|
||||
totalStorage,
|
||||
)
|
||||
|
||||
perCapCollateral := types.BigDiv(
|
||||
totalPerCapitaCollateral,
|
||||
types.NewInt(minerCount),
|
||||
)
|
||||
|
||||
return types.BigAdd(powerCollateral, perCapCollateral), nil
|
||||
}
|
||||
|
||||
func MinerSetHas(ctx context.Context, vmctx types.VMContext, rcid cid.Cid, maddr address.Address) (bool, aerrors.ActorError) {
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
. "github.com/filecoin-project/go-lotus/chain/actors"
|
||||
"github.com/filecoin-project/go-lotus/chain/address"
|
||||
@ -13,6 +14,7 @@ import (
|
||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
hamt "github.com/ipfs/go-hamt-ipld"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -22,7 +24,7 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
||||
var ownerAddr, workerAddr address.Address
|
||||
|
||||
opts := []HarnessOpt{
|
||||
HarnessAddr(&ownerAddr, 100000),
|
||||
HarnessAddr(&ownerAddr, 1000000),
|
||||
HarnessAddr(&workerAddr, 100000),
|
||||
}
|
||||
|
||||
@ -30,7 +32,11 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
||||
|
||||
var minerAddr address.Address
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
||||
// cheating the bootstrapping problem
|
||||
cheatStorageMarketTotal(t, h)
|
||||
|
||||
ret, _ := h.InvokeWithValue(t, ownerAddr, StorageMarketAddress, SMAMethods.CreateStorageMiner,
|
||||
types.NewInt(500000),
|
||||
&CreateStorageMinerParams{
|
||||
Owner: ownerAddr,
|
||||
Worker: workerAddr,
|
||||
@ -92,6 +98,47 @@ func TestStorageMarketCreateAndSlashMiner(t *testing.T) {
|
||||
})
|
||||
ApplyOK(t, ret)
|
||||
}
|
||||
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.PowerLookup,
|
||||
&PowerLookupParams{Miner: minerAddr})
|
||||
assert.Equal(t, ret.ExitCode, byte(1))
|
||||
}
|
||||
|
||||
{
|
||||
ret, _ := h.Invoke(t, ownerAddr, StorageMarketAddress, SMAMethods.IsMiner, &IsMinerParam{minerAddr})
|
||||
ApplyOK(t, ret)
|
||||
assert.Equal(t, ret.Return, cbg.CborBoolFalse)
|
||||
}
|
||||
}
|
||||
|
||||
func cheatStorageMarketTotal(t *testing.T, h *Harness) {
|
||||
t.Helper()
|
||||
|
||||
sma, err := h.vm.StateTree().GetActor(StorageMarketAddress)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cst := hamt.CSTFromBstore(h.cs.Blockstore())
|
||||
|
||||
var smastate StorageMarketState
|
||||
if err := cst.Get(context.TODO(), sma.Head, &smastate); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
smastate.TotalStorage = types.NewInt(10000)
|
||||
|
||||
c, err := cst.Put(context.TODO(), &smastate)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
sma.Head = c
|
||||
|
||||
if err := h.vm.StateTree().SetActor(StorageMarketAddress, sma); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func fakeBlock(t *testing.T, minerAddr address.Address, ts uint64) *types.BlockHeader {
|
||||
|
@ -47,6 +47,22 @@ func Newf(retCode uint8, format string, args ...interface{}) ActorError {
|
||||
}
|
||||
}
|
||||
|
||||
func Fatal(message string, args ...interface{}) ActorError {
|
||||
return &actorError{
|
||||
fatal: true,
|
||||
msg: message,
|
||||
frame: xerrors.Caller(1),
|
||||
}
|
||||
}
|
||||
|
||||
func Fatalf(format string, args ...interface{}) ActorError {
|
||||
return &actorError{
|
||||
fatal: true,
|
||||
msg: fmt.Sprintf(format, args...),
|
||||
frame: xerrors.Caller(1),
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap extens chain of errors with a message
|
||||
func Wrap(err ActorError, message string) ActorError {
|
||||
if err == nil {
|
||||
|
@ -2697,7 +2697,7 @@ func (t *SlashConsensusFaultParams) UnmarshalCBOR(r io.Reader) error {
|
||||
}
|
||||
|
||||
if extra != 2 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields (got %d)", extra)
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.t.Block1 (types.BlockHeader)
|
||||
@ -2787,3 +2787,75 @@ func (t *PledgeCollateralParams) UnmarshalCBOR(r io.Reader) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MinerSlashConsensusFault) MarshalCBOR(w io.Writer) error {
|
||||
if t == nil {
|
||||
_, err := w.Write(cbg.CborNull)
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write([]byte{131}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.Slasher (address.Address)
|
||||
if err := t.Slasher.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.AtHeight (uint64)
|
||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, t.AtHeight)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// t.t.SlashedCollateral (types.BigInt)
|
||||
if err := t.SlashedCollateral.MarshalCBOR(w); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MinerSlashConsensusFault) UnmarshalCBOR(r io.Reader) error {
|
||||
br := cbg.GetPeeker(r)
|
||||
|
||||
maj, extra, err := cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajArray {
|
||||
return fmt.Errorf("cbor input should be of type array")
|
||||
}
|
||||
|
||||
if extra != 3 {
|
||||
return fmt.Errorf("cbor input had wrong number of fields")
|
||||
}
|
||||
|
||||
// t.t.Slasher (address.Address)
|
||||
|
||||
{
|
||||
|
||||
if err := t.Slasher.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
// t.t.AtHeight (uint64)
|
||||
|
||||
maj, extra, err = cbg.CborReadHeader(br)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if maj != cbg.MajUnsignedInt {
|
||||
return fmt.Errorf("wrong type for uint64 field")
|
||||
}
|
||||
t.AtHeight = extra
|
||||
// t.t.SlashedCollateral (types.BigInt)
|
||||
|
||||
{
|
||||
|
||||
if err := t.SlashedCollateral.UnmarshalCBOR(br); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -240,11 +240,17 @@ func (h *Harness) SendFunds(t testing.TB, from address.Address, to address.Addre
|
||||
func (h *Harness) Invoke(t testing.TB, from address.Address, to address.Address,
|
||||
method uint64, params cbg.CBORMarshaler) (*vm.ApplyRet, *state.StateTree) {
|
||||
t.Helper()
|
||||
return h.InvokeWithValue(t, from, to, method, types.NewInt(0), params)
|
||||
}
|
||||
|
||||
func (h *Harness) InvokeWithValue(t testing.TB, from address.Address, to address.Address,
|
||||
method uint64, value types.BigInt, params cbg.CBORMarshaler) (*vm.ApplyRet, *state.StateTree) {
|
||||
t.Helper()
|
||||
return h.Apply(t, types.Message{
|
||||
To: to,
|
||||
From: from,
|
||||
Method: method,
|
||||
Value: types.NewInt(0),
|
||||
Value: value,
|
||||
Params: DumpObject(t, params),
|
||||
GasPrice: types.NewInt(1),
|
||||
GasLimit: types.NewInt(testGasLimit),
|
||||
|
@ -98,15 +98,29 @@ func MakeInitialStateTree(bs bstore.Blockstore, actmap map[address.Address]types
|
||||
return nil, xerrors.Errorf("set storage market actor: %w", err)
|
||||
}
|
||||
|
||||
netAmt := types.Fil(types.NewInt(build.TotalFilecoin))
|
||||
for _, amt := range actmap {
|
||||
netAmt = types.BigSub(netAmt, amt)
|
||||
}
|
||||
|
||||
err = state.SetActor(actors.NetworkAddress, &types.Actor{
|
||||
Code: actors.AccountActorCodeCid,
|
||||
Balance: types.NewInt(100000000000),
|
||||
Balance: netAmt,
|
||||
Head: emptyobject,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("set network account actor: %w", err)
|
||||
}
|
||||
|
||||
err = state.SetActor(actors.BurntFundsAddress, &types.Actor{
|
||||
Code: actors.AccountActorCodeCid,
|
||||
Balance: types.NewInt(0),
|
||||
Head: emptyobject,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("set burnt funds account actor: %w", err)
|
||||
}
|
||||
|
||||
for a, v := range actmap {
|
||||
err = state.SetActor(a, &types.Actor{
|
||||
Code: actors.AccountActorCodeCid,
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"github.com/filecoin-project/go-lotus/build"
|
||||
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
"github.com/polydawn/refmt/obj/atlas"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
@ -41,6 +43,10 @@ func NewInt(i uint64) BigInt {
|
||||
return BigInt{big.NewInt(0).SetUint64(i)}
|
||||
}
|
||||
|
||||
func Fil(i BigInt) BigInt {
|
||||
return BigMul(i, NewInt(build.FilecoinPrecision))
|
||||
}
|
||||
|
||||
func BigFromBytes(b []byte) BigInt {
|
||||
i := big.NewInt(0).SetBytes(b)
|
||||
return BigInt{i}
|
||||
|
@ -73,6 +73,7 @@ func main() {
|
||||
actors.UpdateStorageParams{},
|
||||
actors.SlashConsensusFaultParams{},
|
||||
actors.PledgeCollateralParams{},
|
||||
actors.MinerSlashConsensusFault{},
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
Loading…
Reference in New Issue
Block a user