Remove StateTransplant, modify StateReplay
This commit is contained in:
parent
89f46cb5cc
commit
2fd4a97698
@ -320,10 +320,9 @@ type FullNode interface {
|
||||
|
||||
// StateCall runs the given message and returns its result without any persisted changes.
|
||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*InvocResult, error)
|
||||
// StateTransplant returns the result of executing the indicated message, assuming it was executed in the indicated tipset.
|
||||
StateTransplant(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||
// StateReplay searches for where the given message was executed, and replays it in that tipset.
|
||||
StateReplay(context.Context, cid.Cid) (*InvocResult, error)
|
||||
// StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
||||
// If no tipset key is provided, the appropriate tipset is looked up.
|
||||
StateReplay(context.Context, types.TipSetKey, cid.Cid) (*InvocResult, error)
|
||||
// StateGetActor returns the indicated actor's nonce and balance.
|
||||
StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error)
|
||||
// StateReadState returns the indicated actor's state.
|
||||
|
@ -188,8 +188,7 @@ type FullNodeStruct struct {
|
||||
StateSectorExpiration func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
|
||||
StateSectorPartition func(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"`
|
||||
StateCall func(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
StateTransplant func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReplay func(context.Context, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReplay func(context.Context, types.TipSetKey, cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateGetActor func(context.Context, address.Address, types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateReadState func(context.Context, address.Address, types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StateWaitMsg func(ctx context.Context, cid cid.Cid, confidence uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
@ -880,12 +879,8 @@ func (c *FullNodeStruct) StateCall(ctx context.Context, msg *types.Message, tsk
|
||||
return c.Internal.StateCall(ctx, msg, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateTransplant(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) {
|
||||
return c.Internal.StateTransplant(ctx, tsk, mc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateReplay(ctx context.Context, mc cid.Cid) (*api.InvocResult, error) {
|
||||
return c.Internal.StateReplay(ctx, mc)
|
||||
func (c *FullNodeStruct) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) {
|
||||
return c.Internal.StateReplay(ctx, tsk, mc)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||
|
105
cli/state.go
105
cli/state.go
@ -60,7 +60,6 @@ var stateCmd = &cli.Command{
|
||||
stateSectorCmd,
|
||||
stateGetActorCmd,
|
||||
stateLookupIDCmd,
|
||||
stateTransplantCmd,
|
||||
stateReplayCmd,
|
||||
stateSectorSizeCmd,
|
||||
stateReadStateCmd,
|
||||
@ -384,108 +383,6 @@ var stateExecTraceCmd = &cli.Command{
|
||||
},
|
||||
}
|
||||
|
||||
var stateTransplantCmd = &cli.Command{
|
||||
Name: "transplant",
|
||||
Usage: "Play a particular message within a tipset",
|
||||
ArgsUsage: "[tipsetKey messageCid]",
|
||||
Flags: []cli.Flag{
|
||||
&cli.BoolFlag{
|
||||
Name: "show-trace",
|
||||
Usage: "print out full execution trace for given message",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "detailed-gas",
|
||||
Usage: "print out detailed gas costs for given message",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
if cctx.Args().Len() < 1 {
|
||||
fmt.Println("usage: [tipset] <message cid>")
|
||||
fmt.Println("The last cid passed will be used as the message CID")
|
||||
fmt.Println("All preceding ones will be used as the tipset")
|
||||
return nil
|
||||
}
|
||||
|
||||
args := cctx.Args().Slice()
|
||||
mcid, err := cid.Decode(args[len(args)-1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("message cid was invalid: %s", err)
|
||||
}
|
||||
|
||||
fapi, closer, err := GetFullNodeAPI(cctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer closer()
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
var ts *types.TipSet
|
||||
{
|
||||
var tscids []cid.Cid
|
||||
for _, s := range args[:len(args)-1] {
|
||||
c, err := cid.Decode(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tipset cid was invalid: %s", err)
|
||||
}
|
||||
tscids = append(tscids, c)
|
||||
}
|
||||
|
||||
if len(tscids) > 0 {
|
||||
var headers []*types.BlockHeader
|
||||
for _, c := range tscids {
|
||||
h, err := fapi.ChainGetBlock(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
headers = append(headers, h)
|
||||
}
|
||||
|
||||
ts, err = types.NewTipSet(headers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
ts, err = fapi.ChainHead(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res, err := fapi.StateTransplant(ctx, ts.Key(), mcid)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("transplant call failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Transplant receipt:")
|
||||
fmt.Printf("Exit code: %d\n", res.MsgRct.ExitCode)
|
||||
fmt.Printf("Return: %x\n", res.MsgRct.Return)
|
||||
fmt.Printf("Gas Used: %d\n", res.MsgRct.GasUsed)
|
||||
|
||||
if cctx.Bool("detailed-gas") {
|
||||
fmt.Printf("Base Fee Burn: %d\n", res.GasCost.BaseFeeBurn)
|
||||
fmt.Printf("Overestimaton Burn: %d\n", res.GasCost.OverEstimationBurn)
|
||||
fmt.Printf("Miner Penalty: %d\n", res.GasCost.MinerPenalty)
|
||||
fmt.Printf("Miner Tip: %d\n", res.GasCost.MinerTip)
|
||||
fmt.Printf("Refund: %d\n", res.GasCost.Refund)
|
||||
}
|
||||
fmt.Printf("Total Message Cost: %d\n", res.GasCost.TotalCost)
|
||||
|
||||
if res.MsgRct.ExitCode != 0 {
|
||||
fmt.Printf("Error message: %q\n", res.Error)
|
||||
}
|
||||
|
||||
if cctx.Bool("show-trace") {
|
||||
fmt.Printf("%s\t%s\t%s\t%d\t%x\t%d\t%x\n", res.Msg.From, res.Msg.To, res.Msg.Value, res.Msg.Method, res.Msg.Params, res.MsgRct.ExitCode, res.MsgRct.Return)
|
||||
printInternalExecutions("\t", res.ExecutionTrace.Subcalls)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var stateReplayCmd = &cli.Command{
|
||||
Name: "replay",
|
||||
Usage: "Replay a particular message",
|
||||
@ -519,7 +416,7 @@ var stateReplayCmd = &cli.Command{
|
||||
|
||||
ctx := ReqContext(cctx)
|
||||
|
||||
res, err := fapi.StateReplay(ctx, mcid)
|
||||
res, err := fapi.StateReplay(ctx, types.EmptyTSK, mcid)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("replay call failed: %w", err)
|
||||
}
|
||||
|
@ -165,7 +165,6 @@
|
||||
* [StateSectorGetInfo](#StateSectorGetInfo)
|
||||
* [StateSectorPartition](#StateSectorPartition)
|
||||
* [StateSectorPreCommitInfo](#StateSectorPreCommitInfo)
|
||||
* [StateTransplant](#StateTransplant)
|
||||
* [StateVMCirculatingSupplyInternal](#StateVMCirculatingSupplyInternal)
|
||||
* [StateVerifiedClientStatus](#StateVerifiedClientStatus)
|
||||
* [StateVerifiedRegistryRootKey](#StateVerifiedRegistryRootKey)
|
||||
@ -4048,7 +4047,8 @@ Response:
|
||||
```
|
||||
|
||||
### StateReplay
|
||||
StateReplay searches for where the given message was executed, and replays it in that tipset.
|
||||
StateReplay replays a given message, assuming it was included in a block in the specified tipset.
|
||||
If no tipset key is provided, the appropriate tipset is looked up.
|
||||
|
||||
|
||||
Perms: read
|
||||
@ -4056,6 +4056,14 @@ Perms: read
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
],
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
@ -4319,98 +4327,6 @@ Response:
|
||||
}
|
||||
```
|
||||
|
||||
### StateTransplant
|
||||
StateTransplant returns the result of executing the indicated message, assuming it was executed in the indicated tipset.
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
{
|
||||
"/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
|
||||
}
|
||||
],
|
||||
{
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"MsgCid": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
"Msg": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"GasUsed": 9
|
||||
},
|
||||
"GasCost": {
|
||||
"Message": {
|
||||
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||
},
|
||||
"GasUsed": "0",
|
||||
"BaseFeeBurn": "0",
|
||||
"OverEstimationBurn": "0",
|
||||
"MinerPenalty": "0",
|
||||
"MinerTip": "0",
|
||||
"Refund": "0",
|
||||
"TotalCost": "0"
|
||||
},
|
||||
"ExecutionTrace": {
|
||||
"Msg": {
|
||||
"Version": 42,
|
||||
"To": "f01234",
|
||||
"From": "f01234",
|
||||
"Nonce": 42,
|
||||
"Value": "0",
|
||||
"GasLimit": 9,
|
||||
"GasFeeCap": "0",
|
||||
"GasPremium": "0",
|
||||
"Method": 1,
|
||||
"Params": "Ynl0ZSBhcnJheQ==",
|
||||
"CID": {
|
||||
"/": "bafy2bzacebbpdegvr3i4cosewthysg5xkxpqfn2wfcz6mv2hmoktwbdxkax4s"
|
||||
}
|
||||
},
|
||||
"MsgRct": {
|
||||
"ExitCode": 0,
|
||||
"Return": "Ynl0ZSBhcnJheQ==",
|
||||
"GasUsed": 9
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000,
|
||||
"GasCharges": null,
|
||||
"Subcalls": null
|
||||
},
|
||||
"Error": "string value",
|
||||
"Duration": 60000000000
|
||||
}
|
||||
```
|
||||
|
||||
### StateVMCirculatingSupplyInternal
|
||||
StateVMCirculatingSupplyInternal returns an approximation of the circulating supply of Filecoin at the given tipset.
|
||||
This is the value reported by the runtime interface to actors code.
|
||||
|
@ -26,7 +26,7 @@ class Block extends React.Component {
|
||||
|
||||
messages = await Promise.all(messages.map(async (msg, i) => {
|
||||
if (msg.receipt.ExitCode !== 0) {
|
||||
let reply = await this.props.conn.call('Filecoin.StateTransplant', [{Cids: [this.props.cid], Blocks: [header], Height: header.Height}, msg.Cid])
|
||||
let reply = await this.props.conn.call('Filecoin.StateReplay', [{Cids: [this.props.cid], Blocks: [header], Height: header.Height}, msg.Cid])
|
||||
if(!reply.Error) {
|
||||
reply.Error = "reply: no error"
|
||||
}
|
||||
|
@ -346,12 +346,34 @@ func (a *StateAPI) StateCall(ctx context.Context, msg *types.Message, tsk types.
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateTransplant(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
|
||||
func (a *StateAPI) StateReplay(ctx context.Context, tsk types.TipSetKey, mc cid.Cid) (*api.InvocResult, error) {
|
||||
msgToReplay := mc
|
||||
var ts *types.TipSet
|
||||
if tsk == types.EmptyTSK {
|
||||
mlkp, err := a.StateSearchMsg(ctx, mc)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("searching for msg %s: %w", mc, err)
|
||||
}
|
||||
if mlkp == nil {
|
||||
return nil, xerrors.Errorf("didn't find msg %s", mc)
|
||||
}
|
||||
|
||||
msgToReplay = mlkp.Message
|
||||
|
||||
executionTs, err := a.Chain.GetTipSetFromKey(mlkp.TipSet)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
|
||||
ts, err = a.Chain.LoadTipSet(executionTs.Parents())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
} else {
|
||||
ts = a.Chain.GetHeaviestTipSet()
|
||||
}
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, mc)
|
||||
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, msgToReplay)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -362,47 +384,7 @@ func (a *StateAPI) StateTransplant(ctx context.Context, tsk types.TipSetKey, mc
|
||||
}
|
||||
|
||||
return &api.InvocResult{
|
||||
MsgCid: mc,
|
||||
Msg: m,
|
||||
MsgRct: &r.MessageReceipt,
|
||||
GasCost: stmgr.MakeMsgGasCost(m, r),
|
||||
ExecutionTrace: r.ExecutionTrace,
|
||||
Error: errstr,
|
||||
Duration: r.Duration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateReplay(ctx context.Context, mc cid.Cid) (*api.InvocResult, error) {
|
||||
mlkp, err := a.StateSearchMsg(ctx, mc)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("searching for msg %s: %w", mc, err)
|
||||
}
|
||||
if mlkp == nil {
|
||||
return nil, xerrors.Errorf("didn't find msg %s", mc)
|
||||
}
|
||||
|
||||
executionTs, err := a.Chain.GetTipSetFromKey(mlkp.TipSet)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
|
||||
ts, err := a.Chain.LoadTipSet(executionTs.Parents())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("loading parent tipset %s: %w", mlkp.TipSet, err)
|
||||
}
|
||||
|
||||
m, r, err := a.StateManager.Replay(ctx, ts, mlkp.Message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var errstr string
|
||||
if r.ActorErr != nil {
|
||||
errstr = r.ActorErr.Error()
|
||||
}
|
||||
|
||||
return &api.InvocResult{
|
||||
MsgCid: mlkp.Message,
|
||||
MsgCid: msgToReplay,
|
||||
Msg: m,
|
||||
MsgRct: &r.MessageReceipt,
|
||||
GasCost: stmgr.MakeMsgGasCost(m, r),
|
||||
|
Loading…
Reference in New Issue
Block a user