Skip to content

Commit 7437e46

Browse files
authored
[TT-1824] decode all events in all contracts (#1287)
1 parent 2a8e6cd commit 7437e46

31 files changed

+1257
-43
lines changed

seth/.changeset/v1.50.8.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix a bug, which resulted in not decoding events emitted from contracts other than the the transaction entrypoint, even if we had their ABIs

seth/Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
build:
33
solc --abi --overwrite -o contracts/abi contracts/NetworkDebugContract.sol
44
solc --bin --overwrite -o contracts/bin contracts/NetworkDebugContract.sol
5-
abigen --bin=contracts/bin/NetworkDebugContract.bin --abi=contracts/abi/NetworkDebugContract.abi --pkg=network_debug_contract --out=contracts/bind/debug/NetworkDebugContract.go
5+
abigen --bin=contracts/bin/NetworkDebugContract.bin --abi=contracts/abi/NetworkDebugContract.abi --pkg=network_debug_contract --out=contracts/bind/NetworkDebugContract/NetworkDebugContract.go
66
solc --abi --overwrite -o contracts/abi contracts/NetworkDebugSubContract.sol
77
solc --bin --overwrite -o contracts/bin contracts/NetworkDebugSubContract.sol
8-
abigen --bin=contracts/bin/NetworkDebugSubContract.bin --abi=contracts/abi/NetworkDebugSubContract.abi --pkg=network_debug_sub_contract --out=contracts/bind/sub/NetworkDebugSubContract.go
8+
abigen --bin=contracts/bin/NetworkDebugSubContract.bin --abi=contracts/abi/NetworkDebugSubContract.abi --pkg=network_debug_sub_contract --out=contracts/bind/NetworkDebugSubContract/NetworkDebugSubContract.go
9+
10+
solc --abi --overwrite -o contracts/abi contracts/TestContractOne.sol
11+
solc --bin --overwrite -o contracts/bin contracts/TestContractOne.sol
12+
abigen --bin=contracts/bin/TestContractOne.bin --abi=contracts/abi/TestContractOne.abi --pkg=unique_event_one --out=contracts/bind/TestContractOne/TestContractOne.go
13+
solc --abi --overwrite -o contracts/abi contracts/TestContractTwo.sol
14+
solc --bin --overwrite -o contracts/bin contracts/TestContractTwo.sol
15+
abigen --bin=contracts/bin/TestContractTwo.bin --abi=contracts/abi/TestContractTwo.abi --pkg=unique_event_two --out=contracts/bind/TestContractTwo/TestContractTwo.go
916

1017
.PHONY: AnvilSync
1118
AnvilSync:

seth/client.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,25 +1222,29 @@ func (t TransactionLog) GetData() []byte {
12221222
return t.Data
12231223
}
12241224

1225-
func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, a abi.ABI) ([]DecodedTransactionLog, error) {
1226-
l.Trace().Msg("Decoding events")
1225+
func (m *Client) decodeContractLogs(l zerolog.Logger, logs []types.Log, allABIs []*abi.ABI) ([]DecodedTransactionLog, error) {
1226+
l.Trace().Msg("Decoding ALL events")
12271227
var eventsParsed []DecodedTransactionLog
12281228
for _, lo := range logs {
1229-
for _, evSpec := range a.Events {
1230-
if evSpec.ID.Hex() == lo.Topics[0].Hex() {
1231-
d := TransactionLog{lo.Topics, lo.Data}
1232-
l.Trace().Str("Name", evSpec.RawName).Str("Signature", evSpec.Sig).Msg("Unpacking event")
1233-
eventsMap, topicsMap, err := decodeEventFromLog(l, a, evSpec, d)
1234-
if err != nil {
1235-
return nil, errors.Wrap(err, ErrDecodeLog)
1236-
}
1237-
parsedEvent := decodedLogFromMaps(&DecodedTransactionLog{}, eventsMap, topicsMap)
1238-
if decodedTransactionLog, ok := parsedEvent.(*DecodedTransactionLog); ok {
1239-
decodedTransactionLog.Signature = evSpec.Sig
1240-
m.mergeLogMeta(decodedTransactionLog, lo)
1241-
eventsParsed = append(eventsParsed, *decodedTransactionLog)
1242-
l.Trace().Interface("Log", parsedEvent).Msg("Transaction log")
1243-
} else {
1229+
ABI_LOOP:
1230+
for _, a := range allABIs {
1231+
for _, evSpec := range a.Events {
1232+
if evSpec.ID.Hex() == lo.Topics[0].Hex() {
1233+
d := TransactionLog{lo.Topics, lo.Data}
1234+
l.Trace().Str("Name", evSpec.RawName).Str("Signature", evSpec.Sig).Msg("Unpacking event")
1235+
eventsMap, topicsMap, err := decodeEventFromLog(l, *a, evSpec, d)
1236+
if err != nil {
1237+
return nil, errors.Wrap(err, ErrDecodeLog)
1238+
}
1239+
parsedEvent := decodedLogFromMaps(&DecodedTransactionLog{}, eventsMap, topicsMap)
1240+
decodedTransactionLog, ok := parsedEvent.(*DecodedTransactionLog)
1241+
if ok {
1242+
decodedTransactionLog.Signature = evSpec.Sig
1243+
m.mergeLogMeta(decodedTransactionLog, lo)
1244+
eventsParsed = append(eventsParsed, *decodedTransactionLog)
1245+
l.Trace().Interface("Log", parsedEvent).Msg("Transaction log")
1246+
break ABI_LOOP
1247+
}
12441248
l.Trace().
12451249
Str("Actual type", fmt.Sprintf("%T", decodedTransactionLog)).
12461250
Msg("Failed to cast decoded event to DecodedCommonLog")

seth/client_main_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import (
1212
"github.com/stretchr/testify/require"
1313

1414
"github.com/smartcontractkit/chainlink-testing-framework/seth"
15-
network_debug_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/debug"
15+
network_debug_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/NetworkDebugContract"
16+
network_sub_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/NetworkDebugSubContract"
1617
link_token "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/link"
17-
network_sub_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/sub"
1818
)
1919

2020
/*

seth/client_trace_test.go

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import (
1717
"github.com/stretchr/testify/require"
1818

1919
"github.com/smartcontractkit/chainlink-testing-framework/seth"
20-
network_debug_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/debug"
20+
network_debug_contract "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/NetworkDebugContract"
21+
"github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/TestContractOne"
22+
"github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/TestContractTwo"
2123
link_token "github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/link"
2224
"github.com/smartcontractkit/chainlink-testing-framework/seth/contracts/bind/link_token_interface"
2325
"github.com/smartcontractkit/chainlink-testing-framework/seth/test_utils"
@@ -1786,6 +1788,79 @@ func TestTraceVariousCallTypesAndNestingLevels(t *testing.T) {
17861788
require.Equal(t, 4, c.Tracer.GetDecodedCalls(decodedTx.Hash)[8].NestingLevel, "expected nesting level to be 4")
17871789
}
17881790

1791+
func TestNestedEvents(t *testing.T) {
1792+
c := newClientWithContractMapFromEnv(t)
1793+
SkipAnvil(t, c)
1794+
1795+
tx, txErr := TestEnv.DebugContract.TraceNestedEvents(c.NewTXOpts())
1796+
require.NoError(t, txErr, "transaction should have succeeded")
1797+
decoded, decodeErr := c.Decode(tx, txErr)
1798+
require.NoError(t, decodeErr, "transaction should have succeeded")
1799+
1800+
expectedLogs := []seth.DecodedCommonLog{
1801+
{
1802+
Signature: "UniqueSubDebugEvent()",
1803+
Address: TestEnv.DebugSubContractAddress,
1804+
EventData: map[string]interface{}{},
1805+
Topics: []string{"0xe0b03c5e88196d907268b0babc690e041bdc7fcc1abf4bbf1e363e28c17e6b9b"},
1806+
},
1807+
{
1808+
Signature: "UniqueDebugEvent()",
1809+
Address: TestEnv.DebugContractAddress,
1810+
EventData: map[string]interface{}{},
1811+
Topics: []string{"0xa0f7c7c1fff15178b5db3e56860767f0889c56b591bd2d9ba3121b491347d74c"},
1812+
},
1813+
}
1814+
1815+
require.Equal(t, 2, len(decoded.Events), "expected 2 events")
1816+
var actualEvents []seth.DecodedCommonLog
1817+
for _, event := range decoded.Events {
1818+
actualEvents = append(actualEvents, event.DecodedCommonLog)
1819+
}
1820+
1821+
require.EqualValues(t, expectedLogs, actualEvents, "decoded events do not match")
1822+
}
1823+
1824+
func TestSameEventTwoABIs(t *testing.T) {
1825+
c := newClientWithContractMapFromEnv(t)
1826+
SkipAnvil(t, c)
1827+
1828+
contractAbi, err := TestContractOne.UniqueEventOneMetaData.GetAbi()
1829+
require.NoError(t, err, "failed to get contract ABI")
1830+
oneData, err := c.DeployContract(c.NewTXOpts(), "TestContractOne", *contractAbi, common.FromHex(TestContractOne.UniqueEventOneMetaData.Bin))
1831+
require.NoError(t, err, "failed to deploy contract")
1832+
1833+
contractAbi, err = TestContractTwo.UniqueEventTwoMetaData.GetAbi()
1834+
require.NoError(t, err, "failed to get contract ABI")
1835+
_, err = c.DeployContract(c.NewTXOpts(), "TestContractTwo", *contractAbi, common.FromHex(TestContractTwo.UniqueEventTwoMetaData.Bin))
1836+
require.NoError(t, err, "failed to deploy contract")
1837+
1838+
oneInstance, err := TestContractOne.NewUniqueEventOne(oneData.Address, c.Client)
1839+
require.NoError(t, err, "failed to create contract instance")
1840+
decoded, txErr := c.Decode(oneInstance.ExecuteFirstOperation(c.NewTXOpts(), big.NewInt(1), big.NewInt(2)))
1841+
require.NoError(t, txErr, "transaction should have succeeded")
1842+
1843+
expectedLogs := []seth.DecodedCommonLog{
1844+
{
1845+
Signature: "NonUniqueEvent(int256,int256)",
1846+
Address: oneData.Address,
1847+
EventData: map[string]interface{}{
1848+
"a": big.NewInt(1),
1849+
"b": big.NewInt(2),
1850+
},
1851+
Topics: []string{"0x192aedde7837c0cbfb2275e082ba2391de36cf5a893681e9dac2cced6947614e", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000002"},
1852+
},
1853+
}
1854+
1855+
require.Equal(t, 1, len(decoded.Events), "expected 1 event")
1856+
var actualEvents []seth.DecodedCommonLog
1857+
for _, event := range decoded.Events {
1858+
actualEvents = append(actualEvents, event.DecodedCommonLog)
1859+
}
1860+
1861+
require.EqualValues(t, expectedLogs, actualEvents, "decoded events do not match")
1862+
}
1863+
17891864
func removeGasDataFromDecodedCalls(decodedCall map[string][]*seth.DecodedCall) {
17901865
for _, decodedCalls := range decodedCall {
17911866
for _, call := range decodedCalls {

seth/contract_store.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ func (c *ContractStore) GetABI(name string) (*abi.ABI, bool) {
4444
return &abi, ok
4545
}
4646

47+
func (c *ContractStore) GetAllABIs() []*abi.ABI {
48+
c.mu.Lock()
49+
defer c.mu.Unlock()
50+
51+
var allABIs []*abi.ABI
52+
for _, a := range c.ABIs {
53+
alias := a
54+
allABIs = append(allABIs, &alias)
55+
}
56+
57+
return allABIs
58+
}
59+
4760
func (c *ContractStore) AddABI(name string, abi abi.ABI) {
4861
if !strings.HasSuffix(name, ".abi") {
4962
name = name + ".abi"

seth/contract_store_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,23 @@ func TestSmokeContractABIStore(t *testing.T) {
2222
{
2323
name: "can load the ABI only from ABI files",
2424
abiPath: "./contracts/abi",
25-
expectedABICount: 5,
25+
expectedABICount: 8,
2626
},
2727
{
2828
name: "can load the ABI from ABI files and from gethwrappers",
2929
abiPath: "./contracts/abi",
3030
gethWrappersPaths: []string{"./contracts/bind"},
31-
expectedABICount: 10,
31+
expectedABICount: 11,
3232
},
3333
{
3434
name: "can load the ABI only from gethwrappers",
3535
gethWrappersPaths: []string{"./contracts/bind"},
36-
expectedABICount: 5,
36+
expectedABICount: 7,
3737
},
3838
{
3939
name: "can load the ABI from 2 gethwrappers folders",
4040
gethWrappersPaths: []string{"./contracts/bind", "./contracts/bind2"},
41-
expectedABICount: 6,
41+
expectedABICount: 8,
4242
},
4343
{
4444
name: "can't open the ABI path",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.19;
3+
4+
abstract contract AbstractContractWithEvent {
5+
event NonUniqueEvent(int256 indexed a, int256 indexed b);
6+
}

seth/contracts/NetworkDebugContract.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ contract NetworkDebugContract {
3131
event ThreeIndexEvent(uint256 indexed roundId, address indexed startedBy, uint256 indexed startedAt);
3232
event ThreeIndexAndOneNonIndexedEvent(uint256 indexed roundId, address indexed startedBy, uint256 indexed startedAt, string dataId);
3333
event CallbackEvent(int256 indexed a);
34+
event UniqueDebugEvent();
3435

3536
/* Struct events */
3637

@@ -113,6 +114,11 @@ contract NetworkDebugContract {
113114
return x + y;
114115
}
115116

117+
function traceNestedEvents() public {
118+
subContract.traceUniqueEvent();
119+
emit UniqueDebugEvent();
120+
}
121+
116122
/* Events */
117123

118124
function emitNoIndexEventString() public {

seth/contracts/NetworkDebugSubContract.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ contract NetworkDebugSubContract {
1818
event OneIndexEvent(uint indexed a);
1919
event TwoIndexEvent(uint256 indexed roundId, address indexed startedBy);
2020
event ThreeIndexEvent(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
21+
event UniqueSubDebugEvent();
2122

2223
/* Struct events */
2324

@@ -50,6 +51,10 @@ contract NetworkDebugSubContract {
5051
return x + 3;
5152
}
5253

54+
function traceUniqueEvent() public {
55+
emit UniqueSubDebugEvent();
56+
}
57+
5358
function alwaysRevertsCustomError(uint256 x, uint256 y) public {
5459
revert CustomErr({
5560
available: x,

0 commit comments

Comments
 (0)