From 08b99ff413335be19d922ecccc3e731bf54ee2f6 Mon Sep 17 00:00:00 2001 From: jsign Date: Tue, 14 Jan 2020 21:24:08 -0300 Subject: [PATCH] new api to calculate arbitrary forks revert and applys Signed-off-by: jsign --- api/api_full.go | 1 + api/apistruct/struct.go | 35 ++++++++++++++++++++--------------- chain/store/store.go | 24 ++++++++++++++++++++++++ node/impl/full/chain.go | 4 ++++ 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/api/api_full.go b/api/api_full.go index 996d4abbe..d6efc17ed 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -37,6 +37,7 @@ type FullNode interface { ChainTipSetWeight(context.Context, *types.TipSet) (types.BigInt, error) ChainGetNode(ctx context.Context, p string) (interface{}, error) ChainGetMessage(context.Context, cid.Cid) (*types.Message, error) + ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error) // syncer SyncState(context.Context) (*SyncState, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index fbaff4b66..94321b4a6 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -40,21 +40,22 @@ type FullNodeStruct struct { CommonStruct Internal struct { - ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"` - ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` - ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"` - ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` - ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"` - ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"` - ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` - ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"` - ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"` - ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"` - 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"` - ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"` + ChainNotify func(context.Context) (<-chan []*store.HeadChange, error) `perm:"read"` + ChainHead func(context.Context) (*types.TipSet, error) `perm:"read"` + ChainGetRandomness func(context.Context, types.TipSetKey, int64) ([]byte, error) `perm:"read"` + ChainGetBlock func(context.Context, cid.Cid) (*types.BlockHeader, error) `perm:"read"` + ChainGetTipSet func(context.Context, types.TipSetKey) (*types.TipSet, error) `perm:"read"` + ChainGetBlockMessages func(context.Context, cid.Cid) (*api.BlockMessages, error) `perm:"read"` + ChainGetParentReceipts func(context.Context, cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"` + ChainGetParentMessages func(context.Context, cid.Cid) ([]api.Message, error) `perm:"read"` + ChainGetTipSetByHeight func(context.Context, uint64, *types.TipSet) (*types.TipSet, error) `perm:"read"` + ChainReadObj func(context.Context, cid.Cid) ([]byte, error) `perm:"read"` + 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"` + ChainGetMessage func(context.Context, cid.Cid) (*types.Message, error) `perm:"read"` + ChainGetPath func(context.Context, types.TipSetKey, types.TipSetKey) ([]*store.HeadChange, error) `perm:"read"` SyncState func(context.Context) (*api.SyncState, error) `perm:"read"` SyncSubmitBlock func(ctx context.Context, blk *types.BlockMsg) error `perm:"write"` @@ -355,6 +356,10 @@ func (c *FullNodeStruct) ChainGetMessage(ctx context.Context, mc cid.Cid) (*type return c.Internal.ChainGetMessage(ctx, mc) } +func (c *FullNodeStruct) ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error) { + return c.Internal.ChainGetPath(ctx, from, to) +} + func (c *FullNodeStruct) SyncState(ctx context.Context) (*api.SyncState, error) { return c.Internal.SyncState(ctx) } diff --git a/chain/store/store.go b/chain/store/store.go index 5bd1bfdf5..9545dedac 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -730,6 +730,30 @@ func (cs *ChainStore) readMsgMetaCids(mmc cid.Cid) ([]cid.Cid, []cid.Cid, error) return blscids, secpkcids, nil } +func (cs *ChainStore) GetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*HeadChange, error) { + fts, err := cs.LoadTipSet(from) + if err != nil { + return nil, xerrors.Errorf("loading from tipset %s: %w", from, err) + } + tts, err := cs.LoadTipSet(to) + if err != nil { + return nil, xerrors.Errorf("loading to tipset %s: %w", to, err) + } + revert, apply, err := cs.ReorgOps(fts, tts) + if err != nil { + return nil, xerrors.Errorf("error getting tipset branches: %w", err) + } + + path := make([]*HeadChange, len(revert)+len(apply)) + for i, r := range revert { + path[i] = &HeadChange{Type: HCRevert, Val: r} + } + for j, i := 0, len(apply)-1; i >= 0; j, i = j+1, i-1 { + path[j+len(revert)] = &HeadChange{Type: HCApply, Val: apply[i]} + } + return path, nil +} + func (cs *ChainStore) MessagesForBlock(b *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { blscids, secpkcids, err := cs.readMsgMetaCids(b.Messages) if err != nil { diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index b8622421b..58b87362b 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -83,6 +83,10 @@ func (a *ChainAPI) ChainGetBlockMessages(ctx context.Context, msg cid.Cid) (*api }, nil } +func (a *ChainAPI) ChainGetPath(ctx context.Context, from types.TipSetKey, to types.TipSetKey) ([]*store.HeadChange, error) { + return a.Chain.GetPath(ctx, from, to) +} + func (a *ChainAPI) ChainGetParentMessages(ctx context.Context, bcid cid.Cid) ([]api.Message, error) { b, err := a.Chain.GetBlock(bcid) if err != nil {