Skip to content

Commit 01a3ec2

Browse files
authored
feat: add more fields in fevm transaction (#1255)
* Add new fields for fevm transaction * Get the Actor from DataSource API
1 parent ba88e74 commit 01a3ec2

File tree

5 files changed

+120
-1
lines changed

5 files changed

+120
-1
lines changed

chain/datasource/datasource.go

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/filecoin-project/lily/chain/actors/adt/diff"
3232
"github.com/filecoin-project/lily/chain/actors/builtin/miner"
3333
"github.com/filecoin-project/lily/lens"
34+
"github.com/filecoin-project/lily/lens/util"
3435
"github.com/filecoin-project/lily/metrics"
3536
"github.com/filecoin-project/lily/tasks"
3637
)
@@ -65,7 +66,7 @@ func init() {
6566
executedTsCacheSize = getCacheSizeFromEnv(executedTsCacheSizeEnv, 4)
6667
diffPreCommitCacheSize = getCacheSizeFromEnv(diffPreCommitCacheSizeEnv, 500)
6768
diffSectorCacheSize = getCacheSizeFromEnv(diffSectorCacheSizeEnv, 500)
68-
actorCacheSize = getCacheSizeFromEnv(actorCacheSizeEnv, 1000)
69+
actorCacheSize = getCacheSizeFromEnv(actorCacheSizeEnv, 5000)
6970
}
7071

7172
var _ tasks.DataSource = (*DataSource)(nil)
@@ -221,6 +222,55 @@ func (t *DataSource) Actor(ctx context.Context, addr address.Address, tsk types.
221222
return act, err
222223
}
223224

225+
// ActorInfo retrieves information about an actor at the given address within
226+
// the context of a specific tipset. It first checks a cache for the requested
227+
// information and returns it if available, otherwise it fetches the actor's
228+
// details from the statetree. The retrieved actor information is cached
229+
// for future access. If the actor information is successfully retrieved,
230+
// it includes the actor's state and relevant metadata such as family and name.
231+
// If the actor is not found or an error occurs during retrieval, the function
232+
// returns an error.
233+
func (t *DataSource) ActorInfo(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*tasks.ActorInfo, error) {
234+
metrics.RecordInc(ctx, metrics.DataSourceActorCacheRead)
235+
ctx, span := otel.Tracer("").Start(ctx, "DataSource.ActorInfo")
236+
if span.IsRecording() {
237+
span.SetAttributes(attribute.String("tipset", tsk.String()))
238+
span.SetAttributes(attribute.String("address", addr.String()))
239+
}
240+
defer span.End()
241+
242+
// Includes a prefix to prevent duplication of key names in the cache
243+
key, keyErr := asKey(KeyPrefix{"ActorInfo"}, addr, tsk)
244+
if keyErr == nil {
245+
value, found := t.actorCache.Get(key)
246+
if found {
247+
metrics.RecordInc(ctx, metrics.DataSourceActorCacheHit)
248+
return value.(*tasks.ActorInfo), nil
249+
}
250+
}
251+
252+
act, err := t.Actor(ctx, addr, tsk)
253+
actorInfo := tasks.ActorInfo{}
254+
if err == nil {
255+
if act.Address == nil {
256+
act.Address = &addr
257+
}
258+
actorInfo.Actor = act
259+
actorName, actorFamily, err := util.ActorNameAndFamilyFromCode(act.Code)
260+
if err == nil {
261+
actorInfo.ActorFamily = actorFamily
262+
actorInfo.ActorName = actorName
263+
}
264+
}
265+
266+
// Save the ActorInfo into cache
267+
if err == nil && keyErr == nil {
268+
t.actorCache.Add(key, &actorInfo)
269+
}
270+
271+
return &actorInfo, err
272+
}
273+
224274
func (t *DataSource) MinerPower(ctx context.Context, addr address.Address, ts *types.TipSet) (*api.MinerPower, error) {
225275
ctx, span := otel.Tracer("").Start(ctx, "DataSource.MinerPower")
226276
if span.IsRecording() {
@@ -528,3 +578,11 @@ func asKey(strs ...fmt.Stringer) (string, error) {
528578
}
529579
return sb.String(), nil
530580
}
581+
582+
type KeyPrefix struct {
583+
Prefix string
584+
}
585+
586+
func (k KeyPrefix) String() string {
587+
return k.Prefix + ":"
588+
}

model/fevm/transaction.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ type FEVMTransaction struct {
4949
R string `pg:",notnull"`
5050
// Transaction’s signature. Outputs of an ECDSA signature.
5151
S string `pg:",notnull"`
52+
// Filecoin Address of the sender.
53+
FromFilecoinAddress string `pg:",notnull"`
54+
// Filecoin Address of the receiver.
55+
ToFilecoinAddress string `pg:",notnull"`
56+
// Human-readable identifier of sender (From).
57+
FromActorName string `pg:",notnull"`
58+
// Human-readable identifier of receiver (To).
59+
ToActorName string `pg:",notnull"`
60+
// On-chain message triggering the message.
61+
MessageCid string `pg:",pk,notnull"`
5262
}
5363

5464
func (f *FEVMTransaction) Persist(ctx context.Context, s model.StorageBatch, version model.Version) error {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package v1
2+
3+
func init() {
4+
patches.Register(
5+
31,
6+
`
7+
ALTER TABLE {{ .SchemaName | default "public"}}.fevm_transactions
8+
ADD COLUMN IF NOT EXISTS "from_filecoin_address" text;
9+
ALTER TABLE {{ .SchemaName | default "public"}}.fevm_transactions
10+
ADD COLUMN IF NOT EXISTS "to_filecoin_address" text;
11+
12+
ALTER TABLE {{ .SchemaName | default "public"}}.fevm_transactions
13+
ADD COLUMN IF NOT EXISTS "from_actor_name" text;
14+
ALTER TABLE {{ .SchemaName | default "public"}}.fevm_transactions
15+
ADD COLUMN IF NOT EXISTS "to_actor_name" text;
16+
17+
ALTER TABLE {{ .SchemaName | default "public"}}.fevm_transactions
18+
ADD COLUMN IF NOT EXISTS "message_cid" text;
19+
20+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.fevm_transactions.from_filecoin_address IS 'Filecoin Address of the sender.';
21+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.fevm_transactions.to_filecoin_address IS 'Filecoin Address of the receiver.';
22+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.fevm_transactions.from_actor_name IS 'Fully-versioned human-readable identifier of sender (From).';
23+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.fevm_transactions.to_actor_name IS 'Fully-versioned human-readable identifier of receiver (To).';
24+
COMMENT ON COLUMN {{ .SchemaName | default "public"}}.fevm_transactions.message_cid IS 'Filecoin Message Cid';
25+
`,
26+
)
27+
}

tasks/api.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ type ActorStateChangeDiff map[address.Address]ActorStateChange
4848

4949
type ActorStatesByType map[string][]*types.ActorV5
5050

51+
type ActorInfo struct {
52+
Actor *types.Actor
53+
ActorName string
54+
ActorFamily string
55+
}
56+
5157
type DataSource interface {
5258
TipSet(ctx context.Context, tsk types.TipSetKey) (*types.TipSet, error)
5359
Actor(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error)
5460
ActorState(ctx context.Context, addr address.Address, ts *types.TipSet) (*api.ActorState, error)
61+
ActorInfo(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*ActorInfo, error)
5562
CirculatingSupply(ctx context.Context, ts *types.TipSet) (api.CirculatingSupply, error)
5663
MinerPower(ctx context.Context, addr address.Address, ts *types.TipSet) (*api.MinerPower, error)
5764
ActorStateChanges(ctx context.Context, ts, pts *types.TipSet) (ActorStateChangeDiff, error)

tasks/fevm/transaction/tasks.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ func (p *Task) ProcessTipSets(ctx context.Context, current *types.TipSet, execut
6262
if message.Message == nil {
6363
continue
6464
}
65+
fromActorInfo, err := p.node.ActorInfo(ctx, message.Message.From, current.Key())
66+
if err != nil {
67+
continue
68+
}
69+
6570
if !util.IsEVMMessage(ctx, p.node, message.Message, current.Key()) {
6671
continue
6772
}
@@ -99,6 +104,9 @@ func (p *Task) ProcessTipSets(ctx context.Context, current *types.TipSet, execut
99104
V: txn.V.String(),
100105
R: txn.R.String(),
101106
S: txn.S.String(),
107+
FromFilecoinAddress: fromActorInfo.Actor.Address.String(),
108+
FromActorName: fromActorInfo.ActorName,
109+
MessageCid: message.Cid.String(),
102110
}
103111

104112
if txn.BlockHash != nil {
@@ -110,8 +118,17 @@ func (p *Task) ProcessTipSets(ctx context.Context, current *types.TipSet, execut
110118
if txn.TransactionIndex != nil {
111119
txnObj.TransactionIndex = uint64(*txn.TransactionIndex)
112120
}
121+
122+
// Sometime the the "To" field could be nil
113123
if txn.To != nil {
114124
txnObj.To = txn.To.String()
125+
126+
// Get the Actor from ActorInfo
127+
toActorInfo, err := p.node.ActorInfo(ctx, message.Message.To, current.Key())
128+
if err == nil && toActorInfo.Actor != nil && toActorInfo.Actor.Address != nil {
129+
txnObj.ToActorName = toActorInfo.ActorName
130+
txnObj.ToFilecoinAddress = toActorInfo.Actor.Address.String()
131+
}
115132
}
116133

117134
if len(txn.AccessList) > 0 {

0 commit comments

Comments
 (0)