From 81233b894d72717b1451373652e9dd86759e04a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 19 Dec 2019 16:50:18 +0100 Subject: [PATCH] Implement 'chain get' for easier ipld digging --- api/api_full.go | 1 + api/apistruct/struct.go | 5 + chain/actors/actor_miner.go | 10 +- chain/actors/actor_storagepower.go | 16 ++-- chain/actors/cbor_gen.go | 16 ++-- chain/vm/vm.go | 2 +- cli/chain.go | 36 +++++++ cmd/lotus-chainwatch/dot.go | 4 +- go.mod | 1 + go.sum | 44 +++++++++ node/impl/full/chain.go | 145 ++++++++++++++++++++++++++++- 11 files changed, 251 insertions(+), 29 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 06739ade8..d8fec7723 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -35,6 +35,7 @@ type FullNode interface { ChainSetHead(context.Context, *types.TipSet) error ChainGetGenesis(context.Context) (*types.TipSet, error) ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error) + ChainGetNode(ctx context.Context, p string) (interface{}, error) // syncer SyncState(context.Context) (*SyncState, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index eb8327d60..ae52b24d8 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -53,6 +53,7 @@ type FullNodeStruct struct { ChainSetHead func(context.Context, *types.TipSet) error `perm:"admin"` ChainGetGenesis func(context.Context) (*types.TipSet, error) `perm:"read"` ChainTipSetWeight func(context.Context, *types.TipSet) (types.BigInt, error) `perm:"read"` + ChainGetNode func(ctx context.Context, p string) (interface{}, error) `perm:"read"` SyncState func(context.Context) (*api.SyncState, error) `perm:"read"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` @@ -343,6 +344,10 @@ func (c *FullNodeStruct) ChainTipSetWeight(ctx context.Context, ts *types.TipSet return c.Internal.ChainTipSetWeight(ctx, ts) } +func (c *FullNodeStruct) ChainGetNode(ctx context.Context, p string) (interface{}, error) { + return c.Internal.ChainGetNode(ctx, p) +} + func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) { return c.Internal.SyncState(ctx) } diff --git a/chain/actors/actor_miner.go b/chain/actors/actor_miner.go index 0379fda4d..9b3c871a3 100644 --- a/chain/actors/actor_miner.go +++ b/chain/actors/actor_miner.go @@ -391,7 +391,7 @@ func (sma StorageMinerActor) ProveCommitSector(act *types.Actor, vmctx types.VMC } _, err = vmctx.Send(StorageMarketAddress, SMAMethods.ActivateStorageDeals, types.NewInt(0), activateParams) - return nil, err + return nil, aerrors.Wrapf(err, "calling ActivateStorageDeals failed") } func truncateHexPrint(b []byte) string { @@ -953,9 +953,9 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro if !(oldPower.IsZero() && newPower.IsZero()) { enc, err := SerializeParams(&UpdateStorageParams{ - Delta: delta, - NextProvingPeriodEnd: vmctx.BlockHeight() + build.SlashablePowerDelay, - PreviousProvingPeriodEnd: prevSlashingDeadline, + Delta: delta, + NextSlashDeadline: vmctx.BlockHeight() + build.SlashablePowerDelay, + PreviousSlashDeadline: prevSlashingDeadline, }) if err != nil { return err @@ -963,7 +963,7 @@ func onSuccessfulPoSt(self *StorageMinerActorState, vmctx types.VMContext) aerro _, err = vmctx.Send(StoragePowerAddress, SPAMethods.UpdateStorage, types.NewInt(0), enc) if err != nil { - return err + return aerrors.Wrap(err, "updating storage failed") } } diff --git a/chain/actors/actor_storagepower.go b/chain/actors/actor_storagepower.go index 53d021b11..8a6648ca6 100644 --- a/chain/actors/actor_storagepower.go +++ b/chain/actors/actor_storagepower.go @@ -267,9 +267,9 @@ func shouldSlash(block1, block2 *types.BlockHeader) bool { } type UpdateStorageParams struct { - Delta types.BigInt - NextProvingPeriodEnd uint64 - PreviousProvingPeriodEnd uint64 + Delta types.BigInt + NextSlashDeadline uint64 + PreviousSlashDeadline uint64 } func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMContext, params *UpdateStorageParams) ([]byte, ActorError) { @@ -289,10 +289,10 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte self.TotalStorage = types.BigAdd(self.TotalStorage, params.Delta) - previousBucket := params.PreviousProvingPeriodEnd % build.SlashablePowerDelay - nextBucket := params.NextProvingPeriodEnd % build.SlashablePowerDelay + previousBucket := params.PreviousSlashDeadline % build.SlashablePowerDelay + nextBucket := params.NextSlashDeadline % build.SlashablePowerDelay - if previousBucket == nextBucket && params.PreviousProvingPeriodEnd != 0 { + if previousBucket == nextBucket && params.PreviousSlashDeadline != 0 { nroot, err := vmctx.Storage().Put(&self) if err != nil { return nil, err @@ -310,10 +310,10 @@ func (spa StoragePowerActor) UpdateStorage(act *types.Actor, vmctx types.VMConte return nil, aerrors.HandleExternalError(eerr, "loading proving buckets amt") } - if params.PreviousProvingPeriodEnd != 0 { // delete from previous bucket + if params.PreviousSlashDeadline != 0 { // delete from previous bucket err := deleteMinerFromBucket(vmctx, buckets, previousBucket) if err != nil { - return nil, err + return nil, aerrors.Wrapf(err, "delete from bucket %d, next %d", previousBucket, nextBucket) } } diff --git a/chain/actors/cbor_gen.go b/chain/actors/cbor_gen.go index c9111394e..dac7ef456 100644 --- a/chain/actors/cbor_gen.go +++ b/chain/actors/cbor_gen.go @@ -2866,13 +2866,13 @@ func (t *UpdateStorageParams) MarshalCBOR(w io.Writer) error { return err } - // t.NextProvingPeriodEnd (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextProvingPeriodEnd))); err != nil { + // t.NextSlashDeadline (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.NextSlashDeadline))); err != nil { return err } - // t.PreviousProvingPeriodEnd (uint64) (uint64) - if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousProvingPeriodEnd))); err != nil { + // t.PreviousSlashDeadline (uint64) (uint64) + if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.PreviousSlashDeadline))); err != nil { return err } return nil @@ -2902,7 +2902,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error { } } - // t.NextProvingPeriodEnd (uint64) (uint64) + // t.NextSlashDeadline (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -2911,8 +2911,8 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.NextProvingPeriodEnd = uint64(extra) - // t.PreviousProvingPeriodEnd (uint64) (uint64) + t.NextSlashDeadline = uint64(extra) + // t.PreviousSlashDeadline (uint64) (uint64) maj, extra, err = cbg.CborReadHeader(br) if err != nil { @@ -2921,7 +2921,7 @@ func (t *UpdateStorageParams) UnmarshalCBOR(r io.Reader) error { if maj != cbg.MajUnsignedInt { return fmt.Errorf("wrong type for uint64 field") } - t.PreviousProvingPeriodEnd = uint64(extra) + t.PreviousSlashDeadline = uint64(extra) return nil } diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 7c1c5a802..b478c43d4 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -467,7 +467,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*ApplyRet, ret, actorErr, vmctx := vm.send(ctx, msg, nil, msgGasCost) if aerrors.IsFatal(actorErr) { - return nil, xerrors.Errorf("fatal error: %w", actorErr) + return nil, xerrors.Errorf("[from=%s,to=%s,n=%d,m=%d,h=%d] fatal error: %w", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) } if actorErr != nil { log.Warnf("[from=%s,to=%s,n=%d,m=%d,h=%d] Send actor error: %+v", msg.From, msg.To, msg.Nonce, msg.Method, vm.blockHeight, actorErr) diff --git a/cli/chain.go b/cli/chain.go index e61fc1a3a..cb4133d49 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -25,6 +25,7 @@ var chainCmd = &cli.Command{ chainGetMsgCmd, chainSetHeadCmd, chainListCmd, + chainGetCmd, }, } @@ -336,6 +337,41 @@ var chainListCmd = &cli.Command{ }, } +var chainGetCmd = &cli.Command{ + Name: "get", + Usage: "Get chain DAG node by path", + Description: `Get ipld node under a specified path: + + lotus chain get /ipfs/[cid]/some/path + + Note: + You can use special path elements to traverse through some data structures: + - /ipfs/[cid]/@H:elem - get 'elem' from hamt + - /ipfs/[cid]/@Ha:t01 - get element under Addr(t01).Bytes + - /ipfs/[cid]/@A:10 - get 10th amt element +`, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + nd, err := api.ChainGetNode(ctx, cctx.Args().First()) + if err != nil { + return err + } + + b, err := json.MarshalIndent(nd, "", "\t") + if err != nil { + return err + } + fmt.Println(string(b)) + return nil + }, +} + func printTipSet(format string, ts *types.TipSet) { format = strings.ReplaceAll(format, "", fmt.Sprint(ts.Height())) format = strings.ReplaceAll(format, "