From 00b31d119e2d30b8629d0d37099a12be42d1ee24 Mon Sep 17 00:00:00 2001 From: Warren He Date: Mon, 8 Apr 2024 14:45:10 -0700 Subject: [PATCH 1/6] analyzer: move addresses into util/addresses --- analyzer/evmverifier/evmverifier.go | 4 ++-- analyzer/runtime/extract.go | 11 ++++++----- analyzer/runtime/runtime.go | 4 ++-- .../addresses}/addresses.go | 18 +++++++++--------- 4 files changed, 19 insertions(+), 18 deletions(-) rename analyzer/{uncategorized => util/addresses}/addresses.go (67%) diff --git a/analyzer/evmverifier/evmverifier.go b/analyzer/evmverifier/evmverifier.go index 3b5b02275..83c7c1b7f 100644 --- a/analyzer/evmverifier/evmverifier.go +++ b/analyzer/evmverifier/evmverifier.go @@ -13,7 +13,7 @@ import ( "github.com/oasisprotocol/nexus/analyzer/evmverifier/sourcify" "github.com/oasisprotocol/nexus/analyzer/item" "github.com/oasisprotocol/nexus/analyzer/queries" - uncategorized "github.com/oasisprotocol/nexus/analyzer/uncategorized" + "github.com/oasisprotocol/nexus/analyzer/util/addresses" "github.com/oasisprotocol/nexus/common" "github.com/oasisprotocol/nexus/config" "github.com/oasisprotocol/nexus/log" @@ -137,7 +137,7 @@ func (p *processor) GetItems(ctx context.Context, limit uint64) ([]contract, err // Find contracts that are verified in Sourcify and not yet verified in Nexus. var items []contract for ethAddr, sourcifyLevel := range sourcifyLevels { - oasisAddr, err := uncategorized.StringifyEthAddress(ethAddr.Bytes()) + oasisAddr, err := addresses.FromEthAddress(ethAddr.Bytes()) if err != nil { p.logger.Warn("failed to stringify eth address from sourcify", "err", err, "eth_address", ethAddr) continue diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index c8d9a0d44..a4f24e47f 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -29,6 +29,7 @@ import ( evm "github.com/oasisprotocol/nexus/analyzer/runtime/evm" uncategorized "github.com/oasisprotocol/nexus/analyzer/uncategorized" "github.com/oasisprotocol/nexus/analyzer/util" + "github.com/oasisprotocol/nexus/analyzer/util/addresses" apiTypes "github.com/oasisprotocol/nexus/api/v1/types" "github.com/oasisprotocol/nexus/common" "github.com/oasisprotocol/nexus/log" @@ -196,7 +197,7 @@ func extractAddressPreimage(as *sdkTypes.AddressSpec) (*AddressPreimageData, err } func registerAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageData, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { - addr, err := uncategorized.StringifyAddressSpec(as) + addr, err := addresses.FromAddressSpec(as) if err != nil { return "", err } @@ -213,7 +214,7 @@ func registerAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageD } func registerEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageData, ethAddr []byte) (apiTypes.Address, error) { - addr, err := uncategorized.StringifyEthAddress(ethAddr) + addr, err := addresses.FromEthAddress(ethAddr) if err != nil { return "", err } @@ -230,7 +231,7 @@ func registerEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageDa } func registerRelatedSdkAddress(relatedAddresses map[apiTypes.Address]bool, sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { - addr, err := uncategorized.StringifySdkAddress(sdkAddr) + addr, err := addresses.FromSdkAddress(sdkAddr) if err != nil { return "", err } @@ -413,7 +414,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime amount = body.Amount.Amount if body.To != nil { // This is the address of an account in the consensus layer only; we do not register it as a preimage. - if to, err = uncategorized.StringifySdkAddress(body.To); err != nil { + if to, err = addresses.FromSdkAddress(body.To); err != nil { return fmt.Errorf("to: %w", err) } } else { @@ -450,7 +451,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime blockTransactionData.Body = body amount = body.Amount.Amount // This is the address of an account in the consensus layer only; we do not register it as a preimage. - if to, err = uncategorized.StringifySdkAddress(&body.To); err != nil { + if to, err = addresses.FromSdkAddress(&body.To); err != nil { return fmt.Errorf("to: %w", err) } blockTransactionData.RelatedAccountAddresses[to] = true diff --git a/analyzer/runtime/runtime.go b/analyzer/runtime/runtime.go index 86853fbe7..bf7b5a7d2 100644 --- a/analyzer/runtime/runtime.go +++ b/analyzer/runtime/runtime.go @@ -14,7 +14,7 @@ import ( "github.com/oasisprotocol/nexus/analyzer/queries" evm "github.com/oasisprotocol/nexus/analyzer/runtime/evm" "github.com/oasisprotocol/nexus/analyzer/runtime/static" - uncategorized "github.com/oasisprotocol/nexus/analyzer/uncategorized" + "github.com/oasisprotocol/nexus/analyzer/util/addresses" apiTypes "github.com/oasisprotocol/nexus/api/v1/types" "github.com/oasisprotocol/nexus/common" "github.com/oasisprotocol/nexus/config" @@ -369,7 +369,7 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) { // Insert events. for _, eventData := range data.EventData { - eventRelatedAddresses := uncategorized.ExtractAddresses(eventData.RelatedAddresses) + eventRelatedAddresses := addresses.Extract(eventData.RelatedAddresses) batch.Queue( queries.RuntimeEventInsert, m.runtime, diff --git a/analyzer/uncategorized/addresses.go b/analyzer/util/addresses/addresses.go similarity index 67% rename from analyzer/uncategorized/addresses.go rename to analyzer/util/addresses/addresses.go index ad962585c..cadf0307c 100644 --- a/analyzer/uncategorized/addresses.go +++ b/analyzer/util/addresses/addresses.go @@ -1,4 +1,4 @@ -package common +package addresses import ( "fmt" @@ -17,7 +17,7 @@ import ( // addr -> bech32 string oasis address // addrTextBytes -> bech32 []byte oasis address -func StringifySdkAddress(sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { +func FromSdkAddress(sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { addrTextBytes, err := sdkAddr.MarshalText() if err != nil { return "", fmt.Errorf("address marshal text: %w", err) @@ -25,26 +25,26 @@ func StringifySdkAddress(sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { return apiTypes.Address(addrTextBytes), nil } -func StringifyAddressSpec(as *sdkTypes.AddressSpec) (apiTypes.Address, error) { +func FromAddressSpec(as *sdkTypes.AddressSpec) (apiTypes.Address, error) { sdkAddr, err := as.Address() if err != nil { return "", fmt.Errorf("derive address: %w", err) } - return StringifySdkAddress(&sdkAddr) + return FromSdkAddress(&sdkAddr) } -func StringifyOcAddress(ocAddr address.Address) (apiTypes.Address, error) { +func FromOCAddress(ocAddr address.Address) (apiTypes.Address, error) { sdkAddr := (sdkTypes.Address)(ocAddr) - return StringifySdkAddress(&sdkAddr) + return FromSdkAddress(&sdkAddr) } -func StringifyEthAddress(ethAddr []byte) (apiTypes.Address, error) { +func FromEthAddress(ethAddr []byte) (apiTypes.Address, error) { ctx := sdkTypes.AddressV0Secp256k1EthContext ocAddr := address.NewAddress(ctx, ethAddr) - return StringifyOcAddress(ocAddr) + return FromOCAddress(ocAddr) } -func ExtractAddresses(accounts map[apiTypes.Address]bool) []string { +func Extract(accounts map[apiTypes.Address]bool) []string { addrs := make([]string, len(accounts)) i := 0 for a := range accounts { From 7888c019f0e0436e45a03f2d100edd7397054f44 Mon Sep 17 00:00:00 2001 From: Warren He Date: Tue, 9 Apr 2024 11:10:42 -0700 Subject: [PATCH 2/6] runtime: switch to map[Address]struct{} --- analyzer/runtime/extract.go | 68 ++++++++++++++-------------- analyzer/util/addresses/addresses.go | 2 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index a4f24e47f..3b683acf8 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -57,7 +57,7 @@ type BlockTransactionData struct { Raw []byte RawResult []byte SignerData []*BlockTransactionSignerData - RelatedAccountAddresses map[apiTypes.Address]bool + RelatedAccountAddresses map[apiTypes.Address]struct{} Fee common.BigInt GasLimit uint64 Method string @@ -93,7 +93,7 @@ type EventData struct { EvmLogName *string EvmLogSignature *ethCommon.Hash EvmLogParams []*apiTypes.EvmAbiParam - RelatedAddresses map[apiTypes.Address]bool + RelatedAddresses map[apiTypes.Address]struct{} } // ScopedSdkEvent is a one-of container for SDK events. @@ -230,35 +230,35 @@ func registerEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageDa return addr, nil } -func registerRelatedSdkAddress(relatedAddresses map[apiTypes.Address]bool, sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { +func registerRelatedSdkAddress(relatedAddresses map[apiTypes.Address]struct{}, sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { addr, err := addresses.FromSdkAddress(sdkAddr) if err != nil { return "", err } - relatedAddresses[addr] = true + relatedAddresses[addr] = struct{}{} return addr, nil } -func registerRelatedAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]bool, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { +func registerRelatedAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]struct{}, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { addr, err := registerAddressSpec(addressPreimages, as) if err != nil { return "", err } - relatedAddresses[addr] = true + relatedAddresses[addr] = struct{}{} return addr, nil } -func registerRelatedEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]bool, ethAddr []byte) (apiTypes.Address, error) { +func registerRelatedEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]struct{}, ethAddr []byte) (apiTypes.Address, error) { addr, err := registerEthAddress(addressPreimages, ethAddr) if err != nil { return "", err } - relatedAddresses[addr] = true + relatedAddresses[addr] = struct{}{} return addr, nil } @@ -323,7 +323,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime rawNonTxEvents = append(rawNonTxEvents, e) } } - nonTxEvents, err := extractEvents(&blockData, map[apiTypes.Address]bool{}, rawNonTxEvents) + nonTxEvents, err := extractEvents(&blockData, map[apiTypes.Address]struct{}{}, rawNonTxEvents) if err != nil { return nil, fmt.Errorf("extract non-tx events: %w", err) } @@ -343,7 +343,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime // Inaccurate: Re-serialize signed tx to estimate original size. blockTransactionData.Size = len(blockTransactionData.Raw) blockTransactionData.RawResult = cbor.Marshal(txr.Result) - blockTransactionData.RelatedAccountAddresses = map[apiTypes.Address]bool{} + blockTransactionData.RelatedAccountAddresses = map[apiTypes.Address]struct{}{} tx, err := uncategorized.OpenUtxNoVerify(&txr.Tx) if err != nil { logger.Error("error decoding tx, skipping tx-specific analysis", @@ -422,7 +422,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime // Ref: https://github.com/oasisprotocol/oasis-sdk/blob/runtime-sdk/v0.8.4/runtime-sdk/src/modules/consensus_accounts/mod.rs#L462 to = blockTransactionData.SignerData[0].Address } - blockTransactionData.RelatedAccountAddresses[to] = true + blockTransactionData.RelatedAccountAddresses[to] = struct{}{} return nil }, ConsensusAccountsDelegate: func(body *consensusaccounts.Delegate) error { @@ -454,7 +454,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime if to, err = addresses.FromSdkAddress(&body.To); err != nil { return fmt.Errorf("to: %w", err) } - blockTransactionData.RelatedAccountAddresses[to] = true + blockTransactionData.RelatedAccountAddresses[to] = struct{}{} return nil }, ConsensusAccountsUndelegate: func(body *consensusaccounts.Undelegate) error { @@ -726,7 +726,7 @@ func tryParseErrorMessage(errorModule string, errorCode uint32, msg string) *str return &sanitizedMsg } -func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Address]bool, eventsRaw []nodeapi.RuntimeEvent) ([]*EventData, error) { //nolint:gocyclo +func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Address]struct{}, eventsRaw []nodeapi.RuntimeEvent) ([]*EventData, error) { //nolint:gocyclo extractedEvents := []*EventData{} if err := VisitSdkEvents(eventsRaw, &SdkEventHandler{ Core: func(event *core.Event) error { @@ -754,7 +754,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeAccountsTransfer, Body: event.Transfer, WithScope: ScopedSdkEvent{Accounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -767,7 +767,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeAccountsBurn, Body: event.Burn, WithScope: ScopedSdkEvent{Accounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{ownerAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{ownerAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -780,7 +780,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeAccountsMint, Body: event.Mint, WithScope: ScopedSdkEvent{Accounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{ownerAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{ownerAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -801,7 +801,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeConsensusAccountsDeposit, Body: event.Deposit, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -819,7 +819,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeConsensusAccountsWithdraw, Body: event.Withdraw, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -838,7 +838,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeConsensusAccountsDelegate, Body: event.Delegate, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -855,7 +855,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeConsensusAccountsUndelegateStart, Body: event.UndelegateStart, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, // We cannot set EvmLogSignature here because topics[0] is not the log signature for anonymous events. } extractedEvents = append(extractedEvents, &eventData) @@ -873,7 +873,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeConsensusAccountsUndelegateDone, Body: event.UndelegateDone, WithScope: ScopedSdkEvent{ConsensusAccounts: event}, - RelatedAddresses: map[apiTypes.Address]bool{fromAddr: true, toAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{fromAddr: {}, toAddr: {}}, } extractedEvents = append(extractedEvents, &eventData) } @@ -888,7 +888,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad Type: apiTypes.RuntimeEventTypeEvmLog, Body: event, WithScope: ScopedSdkEvent{EVM: event}, - RelatedAddresses: map[apiTypes.Address]bool{eventAddr: true}, + RelatedAddresses: map[apiTypes.Address]struct{}{eventAddr: {}}, } if err1 = VisitEVMEvent(event, &EVMEventHandler{ ERC20Transfer: func(fromECAddr ethCommon.Address, toECAddr ethCommon.Address, value *big.Int) error { @@ -899,7 +899,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("from: %w", err2) } - eventData.RelatedAddresses[fromAddr] = true + eventData.RelatedAddresses[fromAddr] = struct{}{} registerTokenDecrease(blockData.TokenBalanceChanges, eventAddr, fromAddr, value) } if !toZero { @@ -907,7 +907,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("to: %w", err2) } - eventData.RelatedAddresses[toAddr] = true + eventData.RelatedAddresses[toAddr] = struct{}{} registerTokenIncrease(blockData.TokenBalanceChanges, eventAddr, toAddr, value) } if _, ok := blockData.PossibleTokens[eventAddr]; !ok { @@ -951,14 +951,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("owner: %w", err2) } - eventData.RelatedAddresses[ownerAddr] = true + eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(spenderECAddr.Bytes(), uncategorized.ZeroEthAddr) { spenderAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, spenderECAddr.Bytes()) if err2 != nil { return fmt.Errorf("spender: %w", err2) } - eventData.RelatedAddresses[spenderAddr] = true + eventData.RelatedAddresses[spenderAddr] = struct{}{} } if _, ok := blockData.PossibleTokens[eventAddr]; !ok { blockData.PossibleTokens[eventAddr] = &evm.EVMPossibleToken{} @@ -996,7 +996,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("from: %w", err2) } - eventData.RelatedAddresses[fromAddr] = true + eventData.RelatedAddresses[fromAddr] = struct{}{} registerTokenDecrease(blockData.TokenBalanceChanges, eventAddr, fromAddr, big.NewInt(1)) } if !toZero { @@ -1005,7 +1005,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("to: %w", err2) } - eventData.RelatedAddresses[toAddr] = true + eventData.RelatedAddresses[toAddr] = struct{}{} registerTokenIncrease(blockData.TokenBalanceChanges, eventAddr, toAddr, big.NewInt(1)) } if _, ok := blockData.PossibleTokens[eventAddr]; !ok { @@ -1059,14 +1059,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("owner: %w", err2) } - eventData.RelatedAddresses[ownerAddr] = true + eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(approvedECAddr.Bytes(), uncategorized.ZeroEthAddr) { approvedAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, approvedECAddr.Bytes()) if err2 != nil { return fmt.Errorf("approved: %w", err2) } - eventData.RelatedAddresses[approvedAddr] = true + eventData.RelatedAddresses[approvedAddr] = struct{}{} } if _, ok := blockData.PossibleTokens[eventAddr]; !ok { blockData.PossibleTokens[eventAddr] = &evm.EVMPossibleToken{} @@ -1101,14 +1101,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("owner: %w", err2) } - eventData.RelatedAddresses[ownerAddr] = true + eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(operatorECAddr.Bytes(), uncategorized.ZeroEthAddr) { operatorAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, operatorECAddr.Bytes()) if err2 != nil { return fmt.Errorf("operator: %w", err2) } - eventData.RelatedAddresses[operatorAddr] = true + eventData.RelatedAddresses[operatorAddr] = struct{}{} } if _, ok := blockData.PossibleTokens[eventAddr]; !ok { blockData.PossibleTokens[eventAddr] = &evm.EVMPossibleToken{} @@ -1141,7 +1141,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("owner: %w", err2) } - eventData.RelatedAddresses[ownerAddr] = true + eventData.RelatedAddresses[ownerAddr] = struct{}{} registerTokenIncrease(blockData.TokenBalanceChanges, wrapperAddr, ownerAddr, amount) registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, wrapperAddr, amount) registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, ownerAddr, amount) @@ -1188,7 +1188,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if err2 != nil { return fmt.Errorf("owner: %w", err2) } - eventData.RelatedAddresses[ownerAddr] = true + eventData.RelatedAddresses[ownerAddr] = struct{}{} registerTokenDecrease(blockData.TokenBalanceChanges, wrapperAddr, ownerAddr, amount) registerTokenIncrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, ownerAddr, amount) registerTokenDecrease(blockData.TokenBalanceChanges, evm.NativeRuntimeTokenAddress, wrapperAddr, amount) diff --git a/analyzer/util/addresses/addresses.go b/analyzer/util/addresses/addresses.go index cadf0307c..143b6ffd9 100644 --- a/analyzer/util/addresses/addresses.go +++ b/analyzer/util/addresses/addresses.go @@ -44,7 +44,7 @@ func FromEthAddress(ethAddr []byte) (apiTypes.Address, error) { return FromOCAddress(ocAddr) } -func Extract(accounts map[apiTypes.Address]bool) []string { +func Extract(accounts map[apiTypes.Address]struct{}) []string { addrs := make([]string, len(accounts)) i := 0 for a := range accounts { From b98d53645e8b65bacd93b9cc665157ce1f71e60b Mon Sep 17 00:00:00 2001 From: Warren He Date: Tue, 9 Apr 2024 12:13:57 -0700 Subject: [PATCH 3/6] util/addresses: rename Extract to SliceFromSet --- analyzer/runtime/runtime.go | 2 +- analyzer/util/addresses/addresses.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/analyzer/runtime/runtime.go b/analyzer/runtime/runtime.go index bf7b5a7d2..e059f269e 100644 --- a/analyzer/runtime/runtime.go +++ b/analyzer/runtime/runtime.go @@ -369,7 +369,7 @@ func (m *processor) queueDbUpdates(batch *storage.QueryBatch, data *BlockData) { // Insert events. for _, eventData := range data.EventData { - eventRelatedAddresses := addresses.Extract(eventData.RelatedAddresses) + eventRelatedAddresses := addresses.SliceFromSet(eventData.RelatedAddresses) batch.Queue( queries.RuntimeEventInsert, m.runtime, diff --git a/analyzer/util/addresses/addresses.go b/analyzer/util/addresses/addresses.go index 143b6ffd9..0ddfc4a6c 100644 --- a/analyzer/util/addresses/addresses.go +++ b/analyzer/util/addresses/addresses.go @@ -44,7 +44,7 @@ func FromEthAddress(ethAddr []byte) (apiTypes.Address, error) { return FromOCAddress(ocAddr) } -func Extract(accounts map[apiTypes.Address]struct{}) []string { +func SliceFromSet(accounts map[apiTypes.Address]struct{}) []string { addrs := make([]string, len(accounts)) i := 0 for a := range accounts { From 8dc3063a2cdf5c66683d7fd84833edde19a9fa9b Mon Sep 17 00:00:00 2001 From: Warren He Date: Tue, 9 Apr 2024 12:23:36 -0700 Subject: [PATCH 4/6] runtime: move registration functions to util/addresses --- analyzer/runtime/extract.go | 183 +++++------------------- analyzer/util/addresses/registration.go | 124 ++++++++++++++++ 2 files changed, 159 insertions(+), 148 deletions(-) create mode 100644 analyzer/util/addresses/registration.go diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index 3b683acf8..b137b45ed 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -17,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" ethCommon "github.com/ethereum/go-ethereum/common" "github.com/oasisprotocol/oasis-core/go/common/cbor" - "github.com/oasisprotocol/oasis-core/go/common/crypto/address" "github.com/oasisprotocol/oasis-core/go/common/quantity" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/accounts" "github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/consensusaccounts" @@ -104,12 +103,6 @@ type ScopedSdkEvent struct { EVM *sdkEVM.Event } -type AddressPreimageData struct { - ContextIdentifier string - ContextVersion int - Data []byte -} - type TokenChangeKey struct { // TokenAddress is the Oasis address of the smart contract of the // compatible (e.g. ERC-20) token. @@ -142,7 +135,7 @@ type BlockData struct { Size int TransactionData []*BlockTransactionData EventData []*EventData - AddressPreimages map[apiTypes.Address]*AddressPreimageData + AddressPreimages map[apiTypes.Address]*addresses.PreimageData TokenBalanceChanges map[TokenChangeKey]*big.Int PossibleTokens map[apiTypes.Address]*evm.EVMPossibleToken // key is oasis bech32 address PossibleNFTs map[NFTKey]*PossibleNFT @@ -157,112 +150,6 @@ type BlockData struct { // 'visit-' -> dataflow from generic parameter to specific callback, no side effects, although callbacks will have side // effects. suitable for processing smaller pieces of data that contribute to aggregated structures -func extractAddressPreimage(as *sdkTypes.AddressSpec) (*AddressPreimageData, error) { - // Adapted from oasis-sdk/client-sdk/go/types/transaction.go. - var ( - ctx address.Context - data []byte - ) - switch { - case as.Signature != nil: - spec := as.Signature - switch { - case spec.Ed25519 != nil: - ctx = sdkTypes.AddressV0Ed25519Context - data, _ = spec.Ed25519.MarshalBinary() - case spec.Secp256k1Eth != nil: - ctx = sdkTypes.AddressV0Secp256k1EthContext - // Use a scheme such that we can compute Secp256k1 addresses from Ethereum - // addresses as this makes things more interoperable. - untaggedPk, _ := spec.Secp256k1Eth.MarshalBinaryUncompressedUntagged() - data = uncategorized.SliceEthAddress(uncategorized.Keccak256(untaggedPk)) - case spec.Sr25519 != nil: - ctx = sdkTypes.AddressV0Sr25519Context - data, _ = spec.Sr25519.MarshalBinary() - default: - panic("address: unsupported public key type") - } - case as.Multisig != nil: - config := as.Multisig - ctx = sdkTypes.AddressV0MultisigContext - data = cbor.Marshal(config) - default: - return nil, fmt.Errorf("malformed AddressSpec") - } - return &AddressPreimageData{ - ContextIdentifier: ctx.Identifier, - ContextVersion: int(ctx.Version), - Data: data, - }, nil -} - -func registerAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageData, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { - addr, err := addresses.FromAddressSpec(as) - if err != nil { - return "", err - } - - if _, ok := addressPreimages[addr]; !ok { - preimageData, err1 := extractAddressPreimage(as) - if err1 != nil { - return "", fmt.Errorf("extract address preimage: %w", err1) - } - addressPreimages[addr] = preimageData - } - - return addr, nil -} - -func registerEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageData, ethAddr []byte) (apiTypes.Address, error) { - addr, err := addresses.FromEthAddress(ethAddr) - if err != nil { - return "", err - } - - if _, ok := addressPreimages[addr]; !ok { - addressPreimages[addr] = &AddressPreimageData{ - ContextIdentifier: sdkTypes.AddressV0Secp256k1EthContext.Identifier, - ContextVersion: int(sdkTypes.AddressV0Secp256k1EthContext.Version), - Data: ethAddr, - } - } - - return addr, nil -} - -func registerRelatedSdkAddress(relatedAddresses map[apiTypes.Address]struct{}, sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { - addr, err := addresses.FromSdkAddress(sdkAddr) - if err != nil { - return "", err - } - - relatedAddresses[addr] = struct{}{} - - return addr, nil -} - -func registerRelatedAddressSpec(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]struct{}, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { - addr, err := registerAddressSpec(addressPreimages, as) - if err != nil { - return "", err - } - - relatedAddresses[addr] = struct{}{} - - return addr, nil -} - -func registerRelatedEthAddress(addressPreimages map[apiTypes.Address]*AddressPreimageData, relatedAddresses map[apiTypes.Address]struct{}, ethAddr []byte) (apiTypes.Address, error) { - addr, err := registerEthAddress(addressPreimages, ethAddr) - if err != nil { - return "", err - } - - relatedAddresses[addr] = struct{}{} - - return addr, nil -} - func findPossibleNFT(possibleNFTs map[NFTKey]*PossibleNFT, contractAddr apiTypes.Address, tokenID *big.Int) *PossibleNFT { key := NFTKey{contractAddr, tokenID} possibleNFT, ok := possibleNFTs[key] @@ -310,7 +197,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime NumTransactions: len(txrs), TransactionData: make([]*BlockTransactionData, 0, len(txrs)), EventData: []*EventData{}, - AddressPreimages: map[apiTypes.Address]*AddressPreimageData{}, + AddressPreimages: map[apiTypes.Address]*addresses.PreimageData{}, TokenBalanceChanges: map[TokenChangeKey]*big.Int{}, PossibleTokens: map[apiTypes.Address]*evm.EVMPossibleToken{}, PossibleNFTs: map[NFTKey]*PossibleNFT{}, @@ -360,7 +247,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime si := si // we have no dangerous uses of &si, but capture the variable just in case (and to make the linter happy) var blockTransactionSignerData BlockTransactionSignerData blockTransactionSignerData.Index = j - addr, err1 := registerRelatedAddressSpec(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, &si.AddressSpec) + addr, err1 := addresses.RegisterRelatedAddressSpec(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, &si.AddressSpec) if err1 != nil { return nil, fmt.Errorf("tx %d signer %d visit address spec: %w", txIndex, j, err1) } @@ -389,7 +276,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime AccountsTransfer: func(body *accounts.Transfer) error { blockTransactionData.Body = body amount = body.Amount.Amount - if to, err = registerRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, &body.To); err != nil { + if to, err = addresses.RegisterRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, &body.To); err != nil { return fmt.Errorf("to: %w", err) } return nil @@ -398,7 +285,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime blockTransactionData.Body = body amount = body.Amount.Amount if body.To != nil { - if to, err = registerRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, body.To); err != nil { + if to, err = addresses.RegisterRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, body.To); err != nil { return fmt.Errorf("to: %w", err) } } else { @@ -464,7 +351,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime // In Undelegate semantics, the inexistent `body.To` is implicitly the account that created this tx, i.e. the delegator R. // Ref: https://github.com/oasisprotocol/oasis-sdk/blob/eb97a8162f84ae81d11d805e6dceeeb016841c27/runtime-sdk/src/modules/consensus_accounts/mod.rs#L465-L465 // However, we instead expose `body.From` as the DB/API `to` for consistency with `Delegate`, and because it is more useful: the delegator R is already indexed in the tx sender field. - if to, err = registerRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, &body.From); err != nil { + if to, err = addresses.RegisterRelatedSdkAddress(blockTransactionData.RelatedAccountAddresses, &body.From); err != nil { return fmt.Errorf("from: %w", err) } // The `amount` (of tokens) is not contained in the body, only `shares` is. There isn't sufficient information @@ -480,7 +367,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime if !txr.Result.IsUnknown() && txr.Result.IsSuccess() && len(*ok) == 20 { // Decode address of newly-created contract // todo: is this rigorous enough? - if to, err = registerRelatedEthAddress(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, *ok); err != nil { + if to, err = addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, *ok); err != nil { return fmt.Errorf("created contract: %w", err) } blockTransactionData.EVMContract = &evm.EVMContractData{ @@ -523,7 +410,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime EVMCall: func(body *sdkEVM.Call, ok *[]byte) error { blockTransactionData.Body = body amount = uncategorized.QuantityFromBytes(body.Value) - if to, err = registerRelatedEthAddress(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, body.Address); err != nil { + if to, err = addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, blockTransactionData.RelatedAccountAddresses, body.Address); err != nil { return fmt.Errorf("address: %w", err) } if evmEncrypted, err2 := evm.EVMMaybeUnmarshalEncryptedData(body.Data, ok); err2 == nil { @@ -742,11 +629,11 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad }, Accounts: func(event *accounts.Event) error { if event.Transfer != nil { - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Transfer.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Transfer.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Transfer.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Transfer.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -759,7 +646,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad extractedEvents = append(extractedEvents, &eventData) } if event.Burn != nil { - ownerAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Burn.Owner) + ownerAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Burn.Owner) if err1 != nil { return fmt.Errorf("owner: %w", err1) } @@ -772,7 +659,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad extractedEvents = append(extractedEvents, &eventData) } if event.Mint != nil { - ownerAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Mint.Owner) + ownerAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Mint.Owner) if err1 != nil { return fmt.Errorf("owner: %w", err1) } @@ -789,11 +676,11 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad ConsensusAccounts: func(event *consensusaccounts.Event) error { if event.Deposit != nil { // NOTE: .From is a _consensus_ addr (not runtime). It's still related though. - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Deposit.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Deposit.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Deposit.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Deposit.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -806,12 +693,12 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad extractedEvents = append(extractedEvents, &eventData) } if event.Withdraw != nil { - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Withdraw.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Withdraw.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } // NOTE: .To is a _consensus_ addr (not runtime). It's still related though. - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Withdraw.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Withdraw.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -826,11 +713,11 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad if event.Delegate != nil { // No dead reckoning needed; balance changes are signalled by other, co-emitted events. // See "LESSON" comment in the code that handles the Delegate tx. - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Delegate.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Delegate.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.Delegate.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.Delegate.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -843,11 +730,11 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad extractedEvents = append(extractedEvents, &eventData) } if event.UndelegateStart != nil { - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateStart.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateStart.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateStart.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateStart.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -861,11 +748,11 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad extractedEvents = append(extractedEvents, &eventData) } if event.UndelegateDone != nil { - fromAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateDone.From) + fromAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateDone.From) if err1 != nil { return fmt.Errorf("from: %w", err1) } - toAddr, err1 := registerRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateDone.To) + toAddr, err1 := addresses.RegisterRelatedSdkAddress(relatedAccountAddresses, &event.UndelegateDone.To) if err1 != nil { return fmt.Errorf("to: %w", err1) } @@ -880,7 +767,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad return nil }, EVM: func(event *sdkEVM.Event) error { - eventAddr, err1 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, event.Address) + eventAddr, err1 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, event.Address) if err1 != nil { return fmt.Errorf("event address: %w", err1) } @@ -895,7 +782,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad fromZero := bytes.Equal(fromECAddr.Bytes(), uncategorized.ZeroEthAddr) toZero := bytes.Equal(toECAddr.Bytes(), uncategorized.ZeroEthAddr) if !fromZero { - fromAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, fromECAddr.Bytes()) + fromAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, fromECAddr.Bytes()) if err2 != nil { return fmt.Errorf("from: %w", err2) } @@ -903,7 +790,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad registerTokenDecrease(blockData.TokenBalanceChanges, eventAddr, fromAddr, value) } if !toZero { - toAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, toECAddr.Bytes()) + toAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, toECAddr.Bytes()) if err2 != nil { return fmt.Errorf("to: %w", err2) } @@ -947,14 +834,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad }, ERC20Approval: func(ownerECAddr ethCommon.Address, spenderECAddr ethCommon.Address, value *big.Int) error { if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { - ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(spenderECAddr.Bytes(), uncategorized.ZeroEthAddr) { - spenderAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, spenderECAddr.Bytes()) + spenderAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, spenderECAddr.Bytes()) if err2 != nil { return fmt.Errorf("spender: %w", err2) } @@ -992,7 +879,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad var fromAddr, toAddr apiTypes.Address if !fromZero { var err2 error - fromAddr, err2 = registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, fromECAddr.Bytes()) + fromAddr, err2 = addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, fromECAddr.Bytes()) if err2 != nil { return fmt.Errorf("from: %w", err2) } @@ -1001,7 +888,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad } if !toZero { var err2 error - toAddr, err2 = registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, toECAddr.Bytes()) + toAddr, err2 = addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, toECAddr.Bytes()) if err2 != nil { return fmt.Errorf("to: %w", err2) } @@ -1055,14 +942,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad }, ERC721Approval: func(ownerECAddr ethCommon.Address, approvedECAddr ethCommon.Address, tokenID *big.Int) error { if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { - ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(approvedECAddr.Bytes(), uncategorized.ZeroEthAddr) { - approvedAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, approvedECAddr.Bytes()) + approvedAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, approvedECAddr.Bytes()) if err2 != nil { return fmt.Errorf("approved: %w", err2) } @@ -1097,14 +984,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad }, ERC721ApprovalForAll: func(ownerECAddr ethCommon.Address, operatorECAddr ethCommon.Address, approved bool) error { if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { - ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } if !bytes.Equal(operatorECAddr.Bytes(), uncategorized.ZeroEthAddr) { - operatorAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, operatorECAddr.Bytes()) + operatorAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, operatorECAddr.Bytes()) if err2 != nil { return fmt.Errorf("operator: %w", err2) } @@ -1137,7 +1024,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad WROSEDeposit: func(ownerECAddr ethCommon.Address, amount *big.Int) error { wrapperAddr := eventAddr // the WROSE wrapper contract is implicitly the address that emitted the contract - ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } @@ -1184,7 +1071,7 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad WROSEWithdrawal: func(ownerECAddr ethCommon.Address, amount *big.Int) error { wrapperAddr := eventAddr // the WROSE wrapper contract is implicitly the address that emitted the contract - ownerAddr, err2 := registerRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) + ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } diff --git a/analyzer/util/addresses/registration.go b/analyzer/util/addresses/registration.go new file mode 100644 index 000000000..b8d7782bd --- /dev/null +++ b/analyzer/util/addresses/registration.go @@ -0,0 +1,124 @@ +package addresses + +import ( + "fmt" + + "github.com/oasisprotocol/oasis-core/go/common/cbor" + "github.com/oasisprotocol/oasis-core/go/common/crypto/address" + sdkTypes "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" + + "github.com/oasisprotocol/nexus/analyzer/uncategorized" + apiTypes "github.com/oasisprotocol/nexus/api/v1/types" +) + +type PreimageData struct { + ContextIdentifier string + ContextVersion int + Data []byte +} + +func extractAddressPreimage(as *sdkTypes.AddressSpec) (*PreimageData, error) { + // Adapted from oasis-sdk/client-sdk/go/types/transaction.go. + var ( + ctx address.Context + data []byte + ) + switch { + case as.Signature != nil: + spec := as.Signature + switch { + case spec.Ed25519 != nil: + ctx = sdkTypes.AddressV0Ed25519Context + data, _ = spec.Ed25519.MarshalBinary() + case spec.Secp256k1Eth != nil: + ctx = sdkTypes.AddressV0Secp256k1EthContext + // Use a scheme such that we can compute Secp256k1 addresses from Ethereum + // addresses as this makes things more interoperable. + untaggedPk, _ := spec.Secp256k1Eth.MarshalBinaryUncompressedUntagged() + data = common.SliceEthAddress(common.Keccak256(untaggedPk)) + case spec.Sr25519 != nil: + ctx = sdkTypes.AddressV0Sr25519Context + data, _ = spec.Sr25519.MarshalBinary() + default: + panic("address: unsupported public key type") + } + case as.Multisig != nil: + config := as.Multisig + ctx = sdkTypes.AddressV0MultisigContext + data = cbor.Marshal(config) + default: + return nil, fmt.Errorf("malformed AddressSpec") + } + return &PreimageData{ + ContextIdentifier: ctx.Identifier, + ContextVersion: int(ctx.Version), + Data: data, + }, nil +} + +func registerAddressSpec(addressPreimages map[apiTypes.Address]*PreimageData, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { + addr, err := FromAddressSpec(as) + if err != nil { + return "", err + } + + if _, ok := addressPreimages[addr]; !ok { + preimageData, err1 := extractAddressPreimage(as) + if err1 != nil { + return "", fmt.Errorf("extract address preimage: %w", err1) + } + addressPreimages[addr] = preimageData + } + + return addr, nil +} + +func registerEthAddress(addressPreimages map[apiTypes.Address]*PreimageData, ethAddr []byte) (apiTypes.Address, error) { + addr, err := FromEthAddress(ethAddr) + if err != nil { + return "", err + } + + if _, ok := addressPreimages[addr]; !ok { + addressPreimages[addr] = &PreimageData{ + ContextIdentifier: sdkTypes.AddressV0Secp256k1EthContext.Identifier, + ContextVersion: int(sdkTypes.AddressV0Secp256k1EthContext.Version), + Data: ethAddr, + } + } + + return addr, nil +} + +func RegisterRelatedSdkAddress(relatedAddresses map[apiTypes.Address]struct{}, sdkAddr *sdkTypes.Address) (apiTypes.Address, error) { + addr, err := FromSdkAddress(sdkAddr) + if err != nil { + return "", err + } + + relatedAddresses[addr] = struct{}{} + + return addr, nil +} + +func RegisterRelatedAddressSpec(addressPreimages map[apiTypes.Address]*PreimageData, relatedAddresses map[apiTypes.Address]struct{}, as *sdkTypes.AddressSpec) (apiTypes.Address, error) { + addr, err := registerAddressSpec(addressPreimages, as) + if err != nil { + return "", err + } + + relatedAddresses[addr] = struct{}{} + + return addr, nil +} + +func RegisterRelatedEthAddress(addressPreimages map[apiTypes.Address]*PreimageData, relatedAddresses map[apiTypes.Address]struct{}, ethAddr []byte) (apiTypes.Address, error) { + addr, err := registerEthAddress(addressPreimages, ethAddr) + if err != nil { + return "", err + } + + relatedAddresses[addr] = struct{}{} + + return addr, nil +} From f1bdf31cc2887ce76611dd6e5a9f4fc5fa7d8683 Mon Sep 17 00:00:00 2001 From: Warren He Date: Tue, 9 Apr 2024 14:02:39 -0700 Subject: [PATCH 5/6] analyzer: move eth into util/eth --- analyzer/runtime/extract.go | 23 +++++++++++---------- analyzer/util/addresses/registration.go | 4 ++-- analyzer/{uncategorized => util/eth}/eth.go | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) rename analyzer/{uncategorized => util/eth}/eth.go (96%) diff --git a/analyzer/runtime/extract.go b/analyzer/runtime/extract.go index b137b45ed..4c80c9d58 100644 --- a/analyzer/runtime/extract.go +++ b/analyzer/runtime/extract.go @@ -29,6 +29,7 @@ import ( uncategorized "github.com/oasisprotocol/nexus/analyzer/uncategorized" "github.com/oasisprotocol/nexus/analyzer/util" "github.com/oasisprotocol/nexus/analyzer/util/addresses" + "github.com/oasisprotocol/nexus/analyzer/util/eth" apiTypes "github.com/oasisprotocol/nexus/api/v1/types" "github.com/oasisprotocol/nexus/common" "github.com/oasisprotocol/nexus/log" @@ -223,7 +224,7 @@ func ExtractRound(blockHeader nodeapi.RuntimeBlockHeader, txrs []nodeapi.Runtime blockTransactionData.Index = txIndex blockTransactionData.Hash = txr.Tx.Hash().Hex() if len(txr.Tx.AuthProofs) == 1 && txr.Tx.AuthProofs[0].Module == "evm.ethereum.v0" { - ethHash := hex.EncodeToString(uncategorized.Keccak256(txr.Tx.Body)) + ethHash := hex.EncodeToString(eth.Keccak256(txr.Tx.Body)) blockTransactionData.EthHash = ðHash } blockTransactionData.Raw = cbor.Marshal(txr.Tx) @@ -779,8 +780,8 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad } if err1 = VisitEVMEvent(event, &EVMEventHandler{ ERC20Transfer: func(fromECAddr ethCommon.Address, toECAddr ethCommon.Address, value *big.Int) error { - fromZero := bytes.Equal(fromECAddr.Bytes(), uncategorized.ZeroEthAddr) - toZero := bytes.Equal(toECAddr.Bytes(), uncategorized.ZeroEthAddr) + fromZero := bytes.Equal(fromECAddr.Bytes(), eth.ZeroEthAddr) + toZero := bytes.Equal(toECAddr.Bytes(), eth.ZeroEthAddr) if !fromZero { fromAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, fromECAddr.Bytes()) if err2 != nil { @@ -833,14 +834,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad return nil }, ERC20Approval: func(ownerECAddr ethCommon.Address, spenderECAddr ethCommon.Address, value *big.Int) error { - if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(ownerECAddr.Bytes(), eth.ZeroEthAddr) { ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } - if !bytes.Equal(spenderECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(spenderECAddr.Bytes(), eth.ZeroEthAddr) { spenderAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, spenderECAddr.Bytes()) if err2 != nil { return fmt.Errorf("spender: %w", err2) @@ -874,8 +875,8 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad return nil }, ERC721Transfer: func(fromECAddr ethCommon.Address, toECAddr ethCommon.Address, tokenID *big.Int) error { - fromZero := bytes.Equal(fromECAddr.Bytes(), uncategorized.ZeroEthAddr) - toZero := bytes.Equal(toECAddr.Bytes(), uncategorized.ZeroEthAddr) + fromZero := bytes.Equal(fromECAddr.Bytes(), eth.ZeroEthAddr) + toZero := bytes.Equal(toECAddr.Bytes(), eth.ZeroEthAddr) var fromAddr, toAddr apiTypes.Address if !fromZero { var err2 error @@ -941,14 +942,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad return nil }, ERC721Approval: func(ownerECAddr ethCommon.Address, approvedECAddr ethCommon.Address, tokenID *big.Int) error { - if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(ownerECAddr.Bytes(), eth.ZeroEthAddr) { ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } - if !bytes.Equal(approvedECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(approvedECAddr.Bytes(), eth.ZeroEthAddr) { approvedAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, approvedECAddr.Bytes()) if err2 != nil { return fmt.Errorf("approved: %w", err2) @@ -983,14 +984,14 @@ func extractEvents(blockData *BlockData, relatedAccountAddresses map[apiTypes.Ad return nil }, ERC721ApprovalForAll: func(ownerECAddr ethCommon.Address, operatorECAddr ethCommon.Address, approved bool) error { - if !bytes.Equal(ownerECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(ownerECAddr.Bytes(), eth.ZeroEthAddr) { ownerAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, ownerECAddr.Bytes()) if err2 != nil { return fmt.Errorf("owner: %w", err2) } eventData.RelatedAddresses[ownerAddr] = struct{}{} } - if !bytes.Equal(operatorECAddr.Bytes(), uncategorized.ZeroEthAddr) { + if !bytes.Equal(operatorECAddr.Bytes(), eth.ZeroEthAddr) { operatorAddr, err2 := addresses.RegisterRelatedEthAddress(blockData.AddressPreimages, relatedAccountAddresses, operatorECAddr.Bytes()) if err2 != nil { return fmt.Errorf("operator: %w", err2) diff --git a/analyzer/util/addresses/registration.go b/analyzer/util/addresses/registration.go index b8d7782bd..cac5ef52d 100644 --- a/analyzer/util/addresses/registration.go +++ b/analyzer/util/addresses/registration.go @@ -7,7 +7,7 @@ import ( "github.com/oasisprotocol/oasis-core/go/common/crypto/address" sdkTypes "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" - "github.com/oasisprotocol/nexus/analyzer/uncategorized" + "github.com/oasisprotocol/nexus/analyzer/util/eth" apiTypes "github.com/oasisprotocol/nexus/api/v1/types" ) @@ -35,7 +35,7 @@ func extractAddressPreimage(as *sdkTypes.AddressSpec) (*PreimageData, error) { // Use a scheme such that we can compute Secp256k1 addresses from Ethereum // addresses as this makes things more interoperable. untaggedPk, _ := spec.Secp256k1Eth.MarshalBinaryUncompressedUntagged() - data = common.SliceEthAddress(common.Keccak256(untaggedPk)) + data = eth.SliceEthAddress(eth.Keccak256(untaggedPk)) case spec.Sr25519 != nil: ctx = sdkTypes.AddressV0Sr25519Context data, _ = spec.Sr25519.MarshalBinary() diff --git a/analyzer/uncategorized/eth.go b/analyzer/util/eth/eth.go similarity index 96% rename from analyzer/uncategorized/eth.go rename to analyzer/util/eth/eth.go index 17fa4fe65..a80b131d4 100644 --- a/analyzer/uncategorized/eth.go +++ b/analyzer/util/eth/eth.go @@ -1,4 +1,4 @@ -package common +package eth import ( "golang.org/x/crypto/sha3" From 3f69d46adc27f480aab41ee53344c187bdd4db71 Mon Sep 17 00:00:00 2001 From: Warren He Date: Wed, 10 Apr 2024 12:37:49 -0700 Subject: [PATCH 6/6] add changelog --- .changelog/681.internal.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changelog/681.internal.md diff --git a/.changelog/681.internal.md b/.changelog/681.internal.md new file mode 100644 index 000000000..682c1d35c --- /dev/null +++ b/.changelog/681.internal.md @@ -0,0 +1 @@ +analyzer: move some uncategorized code into new packages