Skip to content

Commit 92b6eba

Browse files
committed
(BIDS-2550) handle contract destruction, show correct data
1 parent 4c0463a commit 92b6eba

File tree

3 files changed

+115
-52
lines changed

3 files changed

+115
-52
lines changed

db/bigtable_eth1.go

+113-48
Original file line numberDiff line numberDiff line change
@@ -2018,7 +2018,7 @@ func (bigtable *Bigtable) TransformWithdrawals(block *types.Eth1Block, cache *fr
20182018
return bulkData, bulkMetadataUpdates, nil
20192019
}
20202020

2021-
func (bigtable *Bigtable) GetEth1TxForAddress(prefix string, limit int64) ([]*types.Eth1TransactionIndexed, string, error) {
2021+
func (bigtable *Bigtable) GetEth1TxForAddress(prefix string, limit int64) ([]*types.Eth1TransactionIndexed, []string, error) {
20222022

20232023
tmr := time.AfterFunc(REPORT_TIMEOUT, func() {
20242024
logger.WithFields(logrus.Fields{
@@ -2044,11 +2044,11 @@ func (bigtable *Bigtable) GetEth1TxForAddress(prefix string, limit int64) ([]*ty
20442044
return true
20452045
}, gcp_bigtable.LimitRows(limit))
20462046
if err != nil {
2047-
return nil, "", err
2047+
return nil, nil, err
20482048
}
20492049

20502050
if len(keys) == 0 {
2051-
return data, "", nil
2051+
return data, nil, nil
20522052
}
20532053

20542054
err = bigtable.tableData.ReadRows(ctx, gcp_bigtable.RowList(keys), func(row gcp_bigtable.Row) bool {
@@ -2064,7 +2064,7 @@ func (bigtable *Bigtable) GetEth1TxForAddress(prefix string, limit int64) ([]*ty
20642064
})
20652065
if err != nil {
20662066
logger.WithError(err).WithField("prefix", prefix).WithField("limit", limit).Errorf("error reading rows in bigtable_eth1 / GetEth1TxForAddress")
2067-
return nil, "", err
2067+
return nil, nil, err
20682068
}
20692069

20702070
for _, key := range keys {
@@ -2073,7 +2073,7 @@ func (bigtable *Bigtable) GetEth1TxForAddress(prefix string, limit int64) ([]*ty
20732073
}
20742074
}
20752075

2076-
return data, indexes[len(indexes)-1], nil
2076+
return data, indexes, nil
20772077
}
20782078

20792079
func (bigtable *Bigtable) GetAddressesNamesArMetadata(names *map[string]string, inputMetadata *map[string]*types.ERC20Metadata) (map[string]string, map[string]*types.ERC20Metadata, error) {
@@ -2171,12 +2171,26 @@ func (bigtable *Bigtable) GetAddressTransactionsTableData(address []byte, search
21712171
pageToken = fmt.Sprintf("%s:I:TX:%x:%s:", bigtable.chainId, address, FILTER_TIME)
21722172
}
21732173

2174-
transactions, lastKey, err := BigtableClient.GetEth1TxForAddress(pageToken, 25)
2174+
transactions, keys, err := BigtableClient.GetEth1TxForAddress(pageToken, 25)
21752175
if err != nil {
21762176
return nil, err
21772177
}
21782178

2179-
txIsContractList, err := BigtableClient.GetAddressIsContractAtTransactions(transactions)
2179+
idxs := make([]int64, len(keys))
2180+
for i, k := range keys {
2181+
tx_idx, err := strconv.Atoi(strings.Split(k, ":")[6])
2182+
if err != nil {
2183+
return nil, fmt.Errorf("error parsing Eth1InternalTransactionIndexed tx index: %v", err)
2184+
}
2185+
tx_idx = 10000 - tx_idx
2186+
if tx_idx < 0 {
2187+
return nil, fmt.Errorf("invalid Eth1InternalTransactionIndexed tx index: %d", tx_idx)
2188+
}
2189+
2190+
idxs[i] = int64(tx_idx)
2191+
}
2192+
2193+
txIsContractList, err := BigtableClient.GetAddressIsContractAtTransactions(transactions, idxs)
21802194
if err != nil {
21812195
utils.LogError(err, "error getting contract states", 0)
21822196
}
@@ -2195,17 +2209,13 @@ func (bigtable *Bigtable) GetAddressTransactionsTableData(address []byte, search
21952209
tableData := make([][]interface{}, len(transactions))
21962210
for i, t := range transactions {
21972211
fromName := names[string(t.From)]
2198-
toName := names[string(t.To)]
2199-
if t.IsContractCreation {
2200-
toName = "Contract Creation"
2201-
}
22022212
var isContractInteraction types.ContractInteractionType
22032213
if len(txIsContractList) > i {
22042214
isContractInteraction = txIsContractList[i]
22052215
}
22062216

22072217
from := utils.FormatAddress(t.From, nil, fromName, false, false, !bytes.Equal(t.From, address))
2208-
to := utils.FormatAddress(t.To, nil, toName, false, isContractInteraction != types.CONTRACT_NONE, !bytes.Equal(t.To, address))
2218+
to := utils.FormatAddress(t.To, nil, BigtableClient.GetAddressLabel(names[string(t.To)], isContractInteraction), false, isContractInteraction != types.CONTRACT_NONE, !bytes.Equal(t.To, address))
22092219

22102220
method := bigtable.GetMethodLabel(t.MethodId, isContractInteraction != types.CONTRACT_NONE)
22112221

@@ -2221,9 +2231,14 @@ func (bigtable *Bigtable) GetAddressTransactionsTableData(address []byte, search
22212231
}
22222232
}
22232233

2234+
token := ""
2235+
if len(keys) > 0 {
2236+
token = keys[len(keys)-1]
2237+
}
2238+
22242239
data := &types.DataTableResponse{
22252240
Data: tableData,
2226-
PagingToken: lastKey,
2241+
PagingToken: token,
22272242
}
22282243

22292244
return data, nil
@@ -2529,7 +2544,7 @@ func (bigtable *Bigtable) GetAddressBlobTableData(address []byte, search string,
25292544
return data, nil
25302545
}
25312546

2532-
func (bigtable *Bigtable) GetEth1ItxForAddress(prefix string, limit int64) ([]*types.Eth1InternalTransactionIndexed, string, error) {
2547+
func (bigtable *Bigtable) GetEth1ItxForAddress(prefix string, limit int64) ([]*types.Eth1InternalTransactionIndexed, []string, error) {
25332548

25342549
tmr := time.AfterFunc(REPORT_TIMEOUT, func() {
25352550
logger.WithFields(logrus.Fields{
@@ -2556,10 +2571,10 @@ func (bigtable *Bigtable) GetEth1ItxForAddress(prefix string, limit int64) ([]*t
25562571
return true
25572572
}, gcp_bigtable.LimitRows(limit))
25582573
if err != nil {
2559-
return nil, "", err
2574+
return nil, nil, err
25602575
}
25612576
if len(keys) == 0 {
2562-
return data, "", nil
2577+
return data, nil, nil
25632578
}
25642579

25652580
err = bigtable.tableData.ReadRows(ctx, gcp_bigtable.RowList(keys), func(row gcp_bigtable.Row) bool {
@@ -2579,7 +2594,7 @@ func (bigtable *Bigtable) GetEth1ItxForAddress(prefix string, limit int64) ([]*t
25792594
})
25802595
if err != nil {
25812596
logger.WithError(err).WithField("prefix", prefix).WithField("limit", limit).Errorf("error reading rows in bigtable_eth1 / GetEth1ItxForAddress")
2582-
return nil, "", err
2597+
return nil, nil, err
25832598
}
25842599

25852600
for _, key := range keys {
@@ -2588,7 +2603,7 @@ func (bigtable *Bigtable) GetEth1ItxForAddress(prefix string, limit int64) ([]*t
25882603
}
25892604
}
25902605

2591-
return data, indexes[len(indexes)-1], nil
2606+
return data, indexes, nil
25922607
}
25932608

25942609
func (bigtable *Bigtable) GetAddressInternalTableData(address []byte, search string, pageToken string) (*types.DataTableResponse, error) {
@@ -2607,7 +2622,7 @@ func (bigtable *Bigtable) GetAddressInternalTableData(address []byte, search str
26072622
pageToken = fmt.Sprintf("%s:I:ITX:%x:%s:", bigtable.chainId, address, FILTER_TIME)
26082623
}
26092624

2610-
transactions, lastKey, err := bigtable.GetEth1ItxForAddress(pageToken, 25)
2625+
transactions, keys, err := bigtable.GetEth1ItxForAddress(pageToken, 25)
26112626
if err != nil {
26122627
return nil, err
26132628
}
@@ -2622,14 +2637,46 @@ func (bigtable *Bigtable) GetAddressInternalTableData(address []byte, search str
26222637
return nil, err
26232638
}
26242639

2640+
idxs := make([][2]int64, len(keys))
2641+
for i, k := range keys {
2642+
tx_idx, err := strconv.Atoi(strings.Split(k, ":")[6])
2643+
if err != nil {
2644+
return nil, fmt.Errorf("error parsing Eth1InternalTransactionIndexed tx index: %v", err)
2645+
}
2646+
tx_idx = 10000 - tx_idx
2647+
if tx_idx < 0 {
2648+
return nil, fmt.Errorf("invalid Eth1InternalTransactionIndexed tx index: %d", tx_idx)
2649+
}
2650+
2651+
trace_idx, err := strconv.Atoi(strings.Split(k, ":")[7])
2652+
if err != nil {
2653+
return nil, fmt.Errorf("error parsing Eth1InternalTransactionIndexed trace index: %v", err)
2654+
}
2655+
trace_idx = 100000 - trace_idx
2656+
if tx_idx < 0 {
2657+
return nil, fmt.Errorf("invalid Eth1InternalTransactionIndexed trace index: %d", trace_idx)
2658+
}
2659+
idxs[i] = [2]int64{int64(tx_idx), int64(trace_idx)}
2660+
}
2661+
txIsContractList, err := BigtableClient.GetAddressIsContractAtTransaction(transactions, idxs)
2662+
if err != nil {
2663+
utils.LogError(err, "error getting contract states", 0)
2664+
}
2665+
26252666
tableData := make([][]interface{}, len(transactions))
26262667
for i, t := range transactions {
26272668

26282669
fromName := names[string(t.From)]
26292670
toName := names[string(t.To)]
26302671

2631-
from := utils.FormatAddress(t.From, nil, fromName, false, false, !bytes.Equal(t.From, address))
2632-
to := utils.FormatAddress(t.To, nil, toName, false, false, !bytes.Equal(t.To, address))
2672+
var from_invokesContract, to_invokesContract types.ContractInteractionType
2673+
if len(txIsContractList) > i {
2674+
from_invokesContract = txIsContractList[i][0]
2675+
to_invokesContract = txIsContractList[i][1]
2676+
}
2677+
2678+
from := utils.FormatAddress(t.From, nil, BigtableClient.GetAddressLabel(fromName, from_invokesContract), false, from_invokesContract != types.CONTRACT_NONE, !bytes.Equal(t.From, address))
2679+
to := utils.FormatAddress(t.To, nil, BigtableClient.GetAddressLabel(toName, to_invokesContract), false, to_invokesContract != types.CONTRACT_NONE, !bytes.Equal(t.To, address))
26332680

26342681
tableData[i] = []interface{}{
26352682
utils.FormatTransactionHash(t.ParentHash),
@@ -2643,9 +2690,14 @@ func (bigtable *Bigtable) GetAddressInternalTableData(address []byte, search str
26432690
}
26442691
}
26452692

2693+
token := ""
2694+
if len(keys) > 0 {
2695+
token = keys[len(keys)-1]
2696+
}
2697+
26462698
data := &types.DataTableResponse{
26472699
Data: tableData,
2648-
PagingToken: lastKey,
2700+
PagingToken: token,
26492701
}
26502702

26512703
return data, nil
@@ -2713,12 +2765,16 @@ func (bigtable *Bigtable) GetInternalTransfersForTransaction(transaction []byte,
27132765

27142766
// sort by event id
27152767
keys := make([]int, 0, len(transfers))
2716-
for k := range transfers {
2768+
itransactions := make([]*types.Eth1InternalTransactionIndexed, 0, len(transfers))
2769+
idxs := make([][2]int64, 0, len(transfers))
2770+
for k, v := range transfers {
27172771
keys = append(keys, k)
2772+
itransactions = append(itransactions, v)
2773+
idxs = append(idxs, [2]int64{int64(txIdx), int64(k)})
27182774
}
27192775
sort.Ints(keys)
27202776

2721-
txIsContractList, err := BigtableClient.GetAddressIsContractAtTransaction(transfers, txIdx)
2777+
txIsContractList, err := BigtableClient.GetAddressIsContractAtTransaction(itransactions, idxs)
27222778
if err != nil {
27232779
utils.LogError(err, "error getting contract states", 0)
27242780
}
@@ -2727,15 +2783,13 @@ func (bigtable *Bigtable) GetInternalTransfersForTransaction(transaction []byte,
27272783
t := transfers[k]
27282784

27292785
var from_invokesContract, to_invokesContract types.ContractInteractionType
2730-
if val, ok := txIsContractList[k]; ok {
2731-
from_invokesContract = val[0]
2732-
to_invokesContract = val[1]
2786+
if len(txIsContractList) > 0 {
2787+
from_invokesContract = txIsContractList[i][0]
2788+
to_invokesContract = txIsContractList[i][1]
27332789
}
27342790

2735-
fromName := names[string(t.From)]
2736-
toName := names[string(t.To)]
2737-
from := utils.FormatAddress(t.From, nil, fromName, false, from_invokesContract != types.CONTRACT_NONE, true)
2738-
to := utils.FormatAddress(t.To, nil, toName, false, to_invokesContract != types.CONTRACT_NONE, true)
2791+
from := utils.FormatAddress(t.From, nil, BigtableClient.GetAddressLabel(names[string(t.From)], from_invokesContract), false, from_invokesContract != types.CONTRACT_NONE, true)
2792+
to := utils.FormatAddress(t.To, nil, BigtableClient.GetAddressLabel(names[string(t.To)], to_invokesContract), false, to_invokesContract != types.CONTRACT_NONE, true)
27392793

27402794
data[i] = types.Transfer{
27412795
From: from,
@@ -3802,45 +3856,44 @@ func (bigtable *Bigtable) GetAddressIsContractAtBlock(block *types.Eth1Block) ([
38023856
}
38033857

38043858
// convenience function to get contract interaction status per subtransaction of a transaction
3805-
// assumes all internal transactions belong to the same tx
3806-
func (bigtable *Bigtable) GetAddressIsContractAtTransaction(itransactions map[int]*types.Eth1InternalTransactionIndexed, tx_idx uint) (map[int][2]types.ContractInteractionType, error) {
3859+
// 2nd parameter specifies [tx_idx, trace_idx] for each internal tx
3860+
func (bigtable *Bigtable) GetAddressIsContractAtTransaction(itransactions []*types.Eth1InternalTransactionIndexed, idxs [][2]int64) ([][2]types.ContractInteractionType, error) {
38073861
requests := make([]isContractAtRequest, 0, len(itransactions)*2)
38083862
for i, tx := range itransactions {
38093863
requests = append(requests, isContractAtRequest{
38103864
address: fmt.Sprintf("%x", tx.GetFrom()),
38113865
block: int64(tx.GetBlockNumber()),
3812-
txIdx: int64(tx_idx),
3813-
traceIdx: int64(i),
3866+
txIdx: idxs[i][0],
3867+
traceIdx: idxs[i][1],
38143868
})
38153869
requests = append(requests, isContractAtRequest{
38163870
address: fmt.Sprintf("%x", tx.GetTo()),
38173871
block: int64(tx.GetBlockNumber()),
3818-
txIdx: int64(tx_idx),
3819-
traceIdx: int64(i),
3872+
txIdx: idxs[i][0],
3873+
traceIdx: idxs[i][1],
38203874
})
38213875
}
38223876
results, err := bigtable.GetAddressIsContractAt(requests)
38233877
if err != nil {
38243878
return nil, err
38253879
}
3826-
resultMap := make(map[int][2]types.ContractInteractionType)
3827-
i := 0
3828-
for key := range itransactions {
3829-
resultMap[key] = [2]types.ContractInteractionType{results[i*2], results[i*2+1]}
3830-
i++
3880+
3881+
resultPairs := make([][2]types.ContractInteractionType, len(itransactions))
3882+
for i, v := range results {
3883+
resultPairs[i/2][i%2] = v
38313884
}
3832-
return resultMap, nil
3885+
return resultPairs, nil
38333886
}
38343887

38353888
// convenience function to get contract interaction status per transaction
3836-
func (bigtable *Bigtable) GetAddressIsContractAtTransactions(transactions []*types.Eth1TransactionIndexed) ([]types.ContractInteractionType, error) {
3889+
func (bigtable *Bigtable) GetAddressIsContractAtTransactions(transactions []*types.Eth1TransactionIndexed, idxs []int64) ([]types.ContractInteractionType, error) {
38373890
requests := make([]isContractAtRequest, len(transactions))
38383891
for i, tx := range transactions {
38393892
requests[i] = isContractAtRequest{
3840-
address: fmt.Sprintf("%x", tx.GetTo()),
3841-
block: int64(tx.GetBlockNumber()),
3842-
// unfortunately we don't know the tx index (without querying it for each tx first)
3843-
txIdx: int64(-1),
3893+
address: fmt.Sprintf("%x", tx.GetTo()),
3894+
block: int64(tx.GetBlockNumber()),
3895+
txIdx: idxs[i],
3896+
traceIdx: -1,
38443897
}
38453898
}
38463899
return bigtable.GetAddressIsContractAt(requests)
@@ -4423,6 +4476,18 @@ func (bigtable *Bigtable) GetMethodLabel(id []byte, invokesContract bool) string
44234476
return method
44244477
}
44254478

4479+
// get a method label for its byte signature with defaults
4480+
func (bigtable *Bigtable) GetAddressLabel(id string, invoke_overwrite types.ContractInteractionType) string {
4481+
switch invoke_overwrite {
4482+
case types.CONTRACT_CREATION:
4483+
return "Contract Creation"
4484+
case types.CONTRACT_DESTRUCTION:
4485+
return "Contract Destruction"
4486+
default:
4487+
return id
4488+
}
4489+
}
4490+
44264491
// get an event label for its byte signature with defaults
44274492
func (bigtable *Bigtable) GetEventLabel(id []byte) string {
44284493
label := ""

handlers/eth1Block.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ func GetExecutionBlockPageData(number uint64, limit int) (*types.Eth1BlockPageDa
176176
// set tx to if tx is contract creation
177177
if contractCreation {
178178
tx.To = tx.ContractAddress
179-
names[string(tx.To)] = "Contract Creation"
180179
}
181180

182181
method := "Transfer"
@@ -200,7 +199,7 @@ func GetExecutionBlockPageData(number uint64, limit int) (*types.Eth1BlockPageDa
200199
From: fmt.Sprintf("%#x", tx.From),
201200
FromFormatted: utils.FormatAddressWithLimits(tx.From, names[string(tx.From)], false, "address", 15, 20, true),
202201
To: fmt.Sprintf("%#x", tx.To),
203-
ToFormatted: utils.FormatAddressWithLimits(tx.To, names[string(tx.To)], isContractInteraction != types.CONTRACT_NONE, "address", 15, 20, true),
202+
ToFormatted: utils.FormatAddressWithLimits(tx.To, db.BigtableClient.GetAddressLabel(names[string(tx.To)], isContractInteraction), isContractInteraction != types.CONTRACT_NONE, "address", 15, 20, true),
204203
Value: new(big.Int).SetBytes(tx.Value),
205204
Fee: txFee,
206205
GasPrice: effectiveGasPrice,

handlers/eth1Transactions.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ func getTransactionDataStartingWithPageToken(pageToken string) *types.DataTableR
100100
}
101101
if v.GetTo() == nil {
102102
v.To = v.ContractAddress
103-
names[string(v.GetTo())] = "Contract Creation"
104103
}
105104
var isContractInteraction types.ContractInteractionType
106105
if len(txIsContractList) > i {
@@ -112,7 +111,7 @@ func getTransactionDataStartingWithPageToken(pageToken string) *types.DataTableR
112111
template.HTML(fmt.Sprintf(`<A href="block/%d">%v</A>`, b.GetNumber(), utils.FormatAddCommas(b.GetNumber()))),
113112
utils.FormatTimestamp(b.GetTime().AsTime().Unix()),
114113
utils.FormatAddressWithLimits(v.GetFrom(), names[string(v.GetFrom())], false, "address", visibleDigitsForHash+5, 18, true),
115-
utils.FormatAddressWithLimits(v.GetTo(), names[string(v.GetTo())], isContractInteraction != types.CONTRACT_NONE, "address", 15, 20, true),
114+
utils.FormatAddressWithLimits(v.GetTo(), db.BigtableClient.GetAddressLabel(names[string(v.GetTo())], isContractInteraction), isContractInteraction != types.CONTRACT_NONE, "address", 15, 20, true),
116115
utils.FormatAmountFormatted(new(big.Int).SetBytes(v.GetValue()), utils.Config.Frontend.ElCurrency, 8, 4, true, true, false),
117116
utils.FormatAmountFormatted(db.CalculateTxFeeFromTransaction(v, new(big.Int).SetBytes(b.GetBaseFee())), utils.Config.Frontend.ElCurrency, 8, 4, true, true, false),
118117
})

0 commit comments

Comments
 (0)