Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gas outputs): Add Height and ActorName #270

Merged
merged 10 commits into from
Dec 3, 2020
Merged

Conversation

hsanjuan
Copy link
Contributor

Gas outputs are very important for many base-fee and gas-usage related views.

The table has no height, which means it needs to be joined with blocks all the
time on something like state_root to get a timestamp. This is likely
innefficient.

Additionally, it needs to be joined with actors to get the actor code. Since
we are "deriving" and already include redundant info, we might also get this
one. This allows easy filtering of messages by actor type and method.

Gas outputs are very important for many base-fee and gas-usage related views.

The table has no height, which means it needs to be joined with blocks all the
time on something like state_root to get a timestamp. This is likely
innefficient.

Additionally, it needs to be joined with actors to get the actor code. Since
we are "deriving" and already include redundant info, we might also get this
one. This allows easy filtering of messages by actor type and method.
@hsanjuan hsanjuan requested review from iand and frrist November 26, 2020 16:30
model/derived/gasoutputs.go Show resolved Hide resolved
@@ -12,6 +12,7 @@ import (

type GasOutputs struct {
tableName struct{} `pg:"derived_gas_outputs"` //nolint: structcheck,unused
Height int64 `pg:",pk,use_zero,notnull"`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need to backfill the value for this column.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The value corresponds to the height of the message I think (not that of the receipts).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's the height of the message. Backfilling is a problem. With the current version it will take some time. With the new in-order processing it takes <1s per tipset, but that's still ~211000 seconds = ~2.4 days unless we shard the processing.

An alternative is to figure out a query that can update this table by joining with messages. That will still be slow to run, several hours at least.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Custom in-order processing that just does messages and just updates this should be faster (?). That said, 2.4 days should be ok.

Comment on lines +139 to +163
child, err := node.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(item.Height+1), types.NewTipSetKey())
if err != nil {
return xerrors.Errorf("Failed to load child tipset: %w", err)
}

st, err := state.LoadStateTree(node.Store(), child.ParentState())
if err != nil {
return xerrors.Errorf("load state tree when gas outputs for %s: %w", item.Cid, err)
}

dstAddr, err := address.NewFromString(item.To)
if err != nil {
return xerrors.Errorf("parse to address failed for gas outputs in %s: %w", item.Cid, err)
}

var dstActorCode cid.Cid
dstActor, err := st.GetActor(dstAddr)
if err != nil {
if !errors.Is(err, types.ErrActorNotFound) {
return xerrors.Errorf("get destination actor for gas outputs %s failed: %w", item.Cid, err)
}
} else {
dstActorCode = dstActor.Code
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish there was a better way, but this should be ok if the state is cached at some layer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#249 is much more efficient but will be a few days before it's ready. Currently checking that the data it produces matches the existing data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, still need to support it in the "standard" way which I trust will become way faster with store improvement and block caching at some point.

@iand
Copy link
Contributor

iand commented Nov 27, 2020

Can we drop the message size column? Is it useful?

@hsanjuan
Copy link
Contributor Author

Can we drop the message size column? Is it useful?

I haven't used it for anything, but it seems like it could give an interesting metric.

Comment on lines 9 to 10
ALTER TABLE public.derived_gas_outputs ADD COLUMN height bigint;
ALTER TABLE public.derived_gas_outputs ADD COLUMN actor_name text;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe constraints need to be added for these new columns since neither are null-able, and height is a primary key.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean height should be made primary key along with cid?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have a look to the latest commits because I am not sure I know what I'm doing with the migrations..

Comment on lines +135 to +138
// Note: this item will only be processed if there are receipts for
// it, which means there should be a tipset at height+1. This is only
// used to get the destination actor code, so we don't care about side
// chains.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps its worth adding a check to ensure child != item? Alternatively, null rounds can be handled via: https://github.com/filecoin-project/sentinel-visor/pull/214/files#diff-a771f3c826cfe5ebe05c1a003873af47456ee3e16188c1e5d0a1162c0b3e27acR40

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that I just want to extract the dstActorCode, is it a problem if child == parent? The actor code will be the same even if it comes from a slightly wrong state. But maybe I'm missing something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the destination actor may no exist in child (when child == parent) if this is the first message being sent to the destination actor. But based on the below code maybe that isn't an issue -- We just won't know the designation actor code if the actor is created in a block preceding a null round.

up := batch(`
ALTER TABLE public.derived_gas_outputs ADD COLUMN height bigint NOT NULL;
ALTER TABLE public.derived_gas_outputs ADD COLUMN actor_name text NOT NULL;
ALTER TABLE public.derived_gas_outputs ADD PRIMARY KEY (height);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

Comment on lines +135 to +138
// Note: this item will only be processed if there are receipts for
// it, which means there should be a tipset at height+1. This is only
// used to get the destination actor code, so we don't care about side
// chains.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the destination actor may no exist in child (when child == parent) if this is the first message being sent to the destination actor. But based on the below code maybe that isn't an issue -- We just won't know the designation actor code if the actor is created in a block preceding a null round.

@frrist frrist added the kind/enhancement Improvement to an existing feature label Dec 2, 2020
Comment on lines 12 to 13
ALTER TABLE public.derived_gas_outputs ADD PRIMARY KEY (cid, height);
`)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iand can shall we leave like this, or add state_root too?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add state_root - I'll do it

@hsanjuan hsanjuan requested a review from iand December 3, 2020 11:49
up := batch(`
ALTER TABLE public.derived_gas_outputs ADD COLUMN height bigint NOT NULL;
ALTER TABLE public.derived_gas_outputs ADD COLUMN actor_name text NOT NULL;
ALTER TABLE public.derived_gas_outputs DROP CONSTRAINT derived_gas_outputs_pkey;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also see in other migrations we do _pk instead of _pkey, should I change that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pkey is the convention used by postgres when you create a primary key

@iand iand changed the title Feat(gas outputs): Add Height and ActorName feat(gas outputs): Add Height and ActorName Dec 3, 2020
@iand iand merged commit 627e829 into master Dec 3, 2020
@iand iand deleted the feat/gas-outputs-columns branch December 3, 2020 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Improvement to an existing feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants