Skip to content

Commit

Permalink
Adjust event parsing to account for event keys
Browse files Browse the repository at this point in the history
  • Loading branch information
archseer committed Apr 5, 2024
1 parent 20b41fb commit 96ee08d
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 60 deletions.
3 changes: 2 additions & 1 deletion packages-ts/starknet-gauntlet-multisig/src/wrapper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ export const wrapCommand = <UI, CI>(
const txInfo = (await this.provider.provider.getTransactionReceipt(
tx.hash,
)) as InvokeTransactionReceiptResponse
proposalId = Number(num.hexToDecimalString((txInfo.events[0] as any).data[1]))
// TODO: use contract.parseEvents?
proposalId = Number(num.hexToDecimalString((txInfo.events[0] as any).keys[2])) // 0 == event_id, 1 == executor, 2 == nonce/proposal_id
}

const data = await this.afterExecute(result, proposalId)
Expand Down
6 changes: 3 additions & 3 deletions packages-ts/starknet-gauntlet-ocr2/src/lib/encoding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { feltsToBytes } from '@chainlink/starknet-gauntlet'
export const decodeOffchainConfigFromEventData = (data: string[]): encoding.OffchainConfig => {
// The ConfigSet event is defined as:
// fn ConfigSet(
// previous_config_block_number: u64,
// latest_config_digest: felt252,
// previous_config_block_number: u64, (key)
// latest_config_digest: felt252, (key)
// config_count: u64,
// oracles: Array<OracleConfig>,
// f: u8,
// onchain_config: Array<felt252>,
// offchain_config_version: u64,
// offchain_config: Array<felt252>,
//)
const oraclesLenIndex = 3
const oraclesLenIndex = 1
const oraclesLen = Number(BigInt(data[oraclesLenIndex]))
const oracleStructSize = 2
const fIndex = oraclesLenIndex + oraclesLen * oracleStructSize + 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ describe('OCR2 Contract', () => {
// reconstruct signers array from event
const eventSigners: bigint[] = []
for (let i = 0; i < signers.length; i++) {
const signer = BigInt(eventData[4 + 2 * i]) // split according to event structure
const signer = BigInt(eventData[2 + 2 * i]) // split according to event structure
eventSigners.push(signer)
}

Expand Down
32 changes: 15 additions & 17 deletions relayer/pkg/chainlink/ocr2/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (c *Client) LinkAvailableForPayment(ctx context.Context, address *felt.Felt
return ans, nil
}

func (c *Client) fetchEventsFromBlock(ctx context.Context, address *felt.Felt, eventType string, blockNum uint64) (eventsAsFeltArrs [][]*felt.Felt, err error) {
func (c *Client) fetchEventsFromBlock(ctx context.Context, address *felt.Felt, eventType string, blockNum uint64) (events []starknetrpc.EmittedEvent, err error) {
block := starknetrpc.WithBlockNumber(blockNum)

eventKey := starknetutils.GetSelectorFromNameFelt(eventType)
Expand All @@ -205,32 +205,30 @@ func (c *Client) fetchEventsFromBlock(ctx context.Context, address *felt.Felt, e
ChunkSize: 10,
},
}
events, err := c.r.Events(ctx, input)
chunk, err := c.r.Events(ctx, input)
events = chunk.Events

// TODO: check events.isLastPage, query more if needed

if err != nil {
return eventsAsFeltArrs, errors.Wrap(err, "couldn't fetch events for block")
return events, errors.Wrap(err, "couldn't fetch events for block")
}

for _, event := range events.Events {
eventsAsFeltArrs = append(eventsAsFeltArrs, event.Data)
}
if len(eventsAsFeltArrs) == 0 {
if len(events) == 0 {
return nil, errors.New("events not found in the block")
}
return eventsAsFeltArrs, nil
return events, nil
}

func (c *Client) ConfigFromEventAt(ctx context.Context, address *felt.Felt, blockNum uint64) (cc ContractConfig, err error) {
eventsAsFeltArrs, err := c.fetchEventsFromBlock(ctx, address, "ConfigSet", blockNum)
events, err := c.fetchEventsFromBlock(ctx, address, "ConfigSet", blockNum)
if err != nil {
return cc, errors.Wrap(err, "failed to fetch config_set events")
}
if len(eventsAsFeltArrs) != 1 {
return cc, fmt.Errorf("expected to find one config_set event in block %d for address %s but found %d", blockNum, address, len(eventsAsFeltArrs))
if len(events) != 1 {
return cc, fmt.Errorf("expected to find one config_set event in block %d for address %s but found %d", blockNum, address, len(events))
}
configAtEvent := eventsAsFeltArrs[0]
configAtEvent := events[0]
config, err := ParseConfigSetEvent(configAtEvent)
if err != nil {
return cc, errors.Wrap(err, "couldn't parse config event")
Expand All @@ -243,16 +241,16 @@ func (c *Client) ConfigFromEventAt(ctx context.Context, address *felt.Felt, bloc

// NewTransmissionsFromEventsAt finds events of type new_transmission emitted by the contract address in a given block number.
func (c *Client) NewTransmissionsFromEventsAt(ctx context.Context, address *felt.Felt, blockNum uint64) (events []NewTransmissionEvent, err error) {
eventsAsFeltArrs, err := c.fetchEventsFromBlock(ctx, address, "NewTransmission", blockNum)
rawEvents, err := c.fetchEventsFromBlock(ctx, address, "NewTransmission", blockNum)
if err != nil {
return nil, errors.Wrap(err, "failed to fetch new_transmission events")
}
if len(eventsAsFeltArrs) == 0 {
return nil, fmt.Errorf("expected to find at least one new_transmission event in block %d for address %s but found %d", blockNum, address, len(eventsAsFeltArrs))
if len(rawEvents) == 0 {
return nil, fmt.Errorf("expected to find at least one new_transmission event in block %d for address %s but found %d", blockNum, address, len(rawEvents))
}
events = []NewTransmissionEvent{}
for _, felts := range eventsAsFeltArrs {
event, err := ParseNewTransmissionEvent(felts)
for _, rawEvent := range rawEvents {
event, err := ParseNewTransmissionEvent(rawEvent)
if err != nil {
return nil, errors.Wrap(err, "couldn't parse new_transmission event")
}
Expand Down
2 changes: 1 addition & 1 deletion relayer/pkg/chainlink/ocr2/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet"
)

const BLOCK_OUTPUT = `{"result": {"events": [ {"from_address": "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489", "keys": ["0x9a144bf4a6a8fd083c93211e163e59221578efcc86b93f8c97c620e7b9608a"], "data": ["0x0", "0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c", "0x1", "0x4", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603730", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603734", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603731", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603735", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603732", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603736", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603733", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603737", "0x1", "0x3", "0x1", "0x0", "0xf4240", "0x2", "0x15", "0x263", "0x880a0d9e61d1080d88ee16f1880bcc1960b2080cab5ee01288090dfc04a30", "0x53a0201024220af400004fa5d02cd5170b5261032e71f2847ead36159cf8d", "0xee68affc3c8520904220af400004fa5d02cd5170b5261032e71f2847ead361", "0x59cf8dee68affc3c8520914220af400004fa5d02cd5170b5261032e71f2847", "0xead36159cf8dee68affc3c8520924220af400004fa5d02cd5170b5261032e7", "0x1f2847ead36159cf8dee68affc3c8520934a42307830346363316266613939", "0x65323832653433346165663238313563613137333337613932336364326336", "0x31636630633764653562333236643761383630333733304a42307830346363", "0x31626661393965323832653433346165663238313563613137333337613932", "0x33636432633631636630633764653562333236643761383630333733314a42", "0x30783034636331626661393965323832653433346165663238313563613137", "0x33333761393233636432633631636630633764653562333236643761383630", "0x333733324a4230783034636331626661393965323832653433346165663238", "0x31356361313733333761393233636432633631636630633764653562333236", "0x643761383630333733335200608094ebdc03688084af5f708084af5f788084", "0xaf5f82018c010a202ac49e648a1f84da5a143eeab68c8402c65a1567e63971", "0x7f5732d5e6310c2c761220a6c1ae85186dc981dc61cd14d7511ee5ab70258a", "0x10ac4e03e4d4991761b2c0a61a1090696dc7afed7f61a26887e78e683a1c1a", "0x10a29e5fa535f2edea7afa9acb4fd349b31a10d1b88713982955d79fa0e422", "0x685a748b1a10a07e0118cc38a71d2a9d60bf52938b4a"]}]}}`
const BLOCK_OUTPUT = `{"result": {"events": [ {"from_address": "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489", "keys": ["0x9a144bf4a6a8fd083c93211e163e59221578efcc86b93f8c97c620e7b9608a", "0x0", "0x4b791b801cf0d7b6a2f9e59daf15ec2dd7d9cdc3bc5e037bada9c86e4821c"], "data": ["0x1", "0x4", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603730", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603734", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603731", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603735", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603732", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603736", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603733", "0x4cc1bfa99e282e434aef2815ca17337a923cd2c61cf0c7de5b326d7a8603737", "0x1", "0x3", "0x1", "0x0", "0xf4240", "0x2", "0x15", "0x263", "0x880a0d9e61d1080d88ee16f1880bcc1960b2080cab5ee01288090dfc04a30", "0x53a0201024220af400004fa5d02cd5170b5261032e71f2847ead36159cf8d", "0xee68affc3c8520904220af400004fa5d02cd5170b5261032e71f2847ead361", "0x59cf8dee68affc3c8520914220af400004fa5d02cd5170b5261032e71f2847", "0xead36159cf8dee68affc3c8520924220af400004fa5d02cd5170b5261032e7", "0x1f2847ead36159cf8dee68affc3c8520934a42307830346363316266613939", "0x65323832653433346165663238313563613137333337613932336364326336", "0x31636630633764653562333236643761383630333733304a42307830346363", "0x31626661393965323832653433346165663238313563613137333337613932", "0x33636432633631636630633764653562333236643761383630333733314a42", "0x30783034636331626661393965323832653433346165663238313563613137", "0x33333761393233636432633631636630633764653562333236643761383630", "0x333733324a4230783034636331626661393965323832653433346165663238", "0x31356361313733333761393233636432633631636630633764653562333236", "0x643761383630333733335200608094ebdc03688084af5f708084af5f788084", "0xaf5f82018c010a202ac49e648a1f84da5a143eeab68c8402c65a1567e63971", "0x7f5732d5e6310c2c761220a6c1ae85186dc981dc61cd14d7511ee5ab70258a", "0x10ac4e03e4d4991761b2c0a61a1090696dc7afed7f61a26887e78e683a1c1a", "0x10a29e5fa535f2edea7afa9acb4fd349b31a10d1b88713982955d79fa0e422", "0x685a748b1a10a07e0118cc38a71d2a9d60bf52938b4a"]}]}}`
const ocr2ContractAddress = "0xd43963a4e875a361f5d164b2e70953598eb4f45fde86924082d51b4d78e489" // matches BLOCK_OUTPUT event

func TestOCR2Client(t *testing.T) {
Expand Down
39 changes: 23 additions & 16 deletions relayer/pkg/chainlink/ocr2/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/smartcontractkit/libocr/offchainreporting2/types"

starknetrpc "github.com/NethermindEth/starknet.go/rpc"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/chainlink/ocr2/medianreport"
"github.com/smartcontractkit/chainlink-starknet/relayer/pkg/starknet"
)
Expand Down Expand Up @@ -40,33 +41,38 @@ type NewTransmissionEvent struct {
}

// ParseNewTransmissionEvent is decoding binary felt data as the NewTransmissionEvent type
func ParseNewTransmissionEvent(eventData []*felt.Felt) (NewTransmissionEvent, error) {
func ParseNewTransmissionEvent(event starknetrpc.EmittedEvent) (NewTransmissionEvent, error) {
eventData := event.Data
{
const observationsLenIndex = 5
const constNumOfElements = 11
const observationsLenIndex = 3
const constNumOfElements = 9
const constNumOfKeys = 2

if len(eventData) < constNumOfElements {
return NewTransmissionEvent{}, errors.New("invalid: event data")
}

if len(event.Keys) < constNumOfKeys {
return NewTransmissionEvent{}, errors.New("invalid: event data")
}

observationsLen := eventData[observationsLenIndex].BigInt(big.NewInt(0)).Uint64()
if len(eventData) != constNumOfElements+int(observationsLen) {
return NewTransmissionEvent{}, errors.New("invalid: event data")
}
}

// keys[0] == event_id
// round_id
roundId := uint32(event.Keys[1].BigInt(big.NewInt(0)).Uint64())
// transmitter
transmitter := event.Keys[2]

index := 0
roundId := uint32(eventData[index].BigInt(big.NewInt(0)).Uint64())

// answer
index++
latestAnswer := eventData[index].BigInt(big.NewInt(0))

// transmitter
index++
transmitter := eventData[index]

// observation_timestamp
index++
unixTime := eventData[index].BigInt(big.NewInt(0)).Int64()
Expand Down Expand Up @@ -130,9 +136,10 @@ func ParseNewTransmissionEvent(eventData []*felt.Felt) (NewTransmissionEvent, er
}

// ParseConfigSetEvent is decoding binary felt data as the libocr ContractConfig type
func ParseConfigSetEvent(eventData []*felt.Felt) (types.ContractConfig, error) {
func ParseConfigSetEvent(event starknetrpc.EmittedEvent) (types.ContractConfig, error) {
eventData := event.Data
{
const oraclesLenIdx = 3
const oraclesLenIdx = 1
if len(eventData) < oraclesLenIdx {
return types.ContractConfig{}, errors.New("invalid: event data")
}
Expand All @@ -157,15 +164,15 @@ func ParseConfigSetEvent(eventData []*felt.Felt) (types.ContractConfig, error) {
}
}

index := 0
// previous_config_block_number - skip
// keys[0] == event_id
// keys[1] == previous_config_block_number - skip

// latest_config_digest
index++
digest := eventData[index].Bytes()
digest := event.Keys[2].Bytes()

index := 0

// config_count
index++
configCount := eventData[index].BigInt(big.NewInt(0)).Uint64()

// oracles_len
Expand Down
68 changes: 47 additions & 21 deletions relayer/pkg/chainlink/ocr2/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

starknetrpc "github.com/NethermindEth/starknet.go/rpc"
starknetutils "github.com/NethermindEth/starknet.go/utils"

"github.com/smartcontractkit/libocr/offchainreporting2/types"
Expand All @@ -18,28 +19,37 @@ import (
)

var (
// NewTransmission
newTransmissionEventKeysRaw = []string{
"0x9", // event_id
"0x1", // round_id
"0x2c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d", // transmitter
}
newTransmissionEventRaw = []string{
"0x1",
"0x63",
"0x2c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d",
"0x1",
"0x10203000000000000000000000000000000000000000000000000000000",
"0x4",
"0x63", // answer
"0x1", // observation_timestamp
"0x10203000000000000000000000000000000000000000000000000000000", // observers
"0x4", // len(observations)
"0x63",
"0x63",
"0x63",
"0x63",
"0x1",
"0x1",
"0x485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453",
"0x1",
"0x1",
"0x1", // juels_per_fee_coin
"0x1", // gas_price
"0x485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453", // config_digest
"0x1", // epoch_and_round
"0x1", // reimbursement
}

// ConfigSet
configSetEventKeysRaw = []string{
"0x10", // event_id
"0x0", // previous_block_number
"0x485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453", // lastest_config_digest
}
configSetEventRaw = []string{
"0x0",
"0x485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453",
"0x1",
"0x4",
"0x1", // config_count
"0x4", // len(oracles)
"0x21e867aa6e6c545949a9c6f9f5401b70007bd93675857a0a7d5345b8bffcbf0",
"0x2c0dd77ce74b1667dc6fa782bbafaef5becbe2d04b052726ab236daeb52ac5d",
"0x64642f34e68436f45757b920f4cdfbdff82728844d740bac672a19ad72011ca",
Expand All @@ -48,24 +58,32 @@ var (
"0x2f14e18cc198dd5133c8a9aa92992fc1a462f703401716f402d0ee383b54faa",
"0x4fcf11b05ebd00a207030c04836defbec3d37a3f77e581f2d0962a20a55adcd",
"0x5c35686f78db31d9d896bb425b3fd99be19019f8aeaf0f7a8767867903341d4",
"0x1",
"0x3",
"0x1", // f
"0x3", // len(onchain_config)
"0x1",
"0xa",
"0x3b9aca00",
"0x2",
"0x2",
"0x2", // offchain_config_version
"0x2", // len(offchain_config)
"0x1",
"0x1",
}
)

func TestNewTransmissionEvent_Parse(t *testing.T) {
eventKeys, err := starknetutils.HexArrToFelt(newTransmissionEventKeysRaw)
assert.NoError(t, err)
eventData, err := starknetutils.HexArrToFelt(newTransmissionEventRaw)
assert.NoError(t, err)
require.Equal(t, len(newTransmissionEventRaw), len(eventData))

e, err := ParseNewTransmissionEvent(eventData)
event := starknetrpc.EmittedEvent{
Event: starknetrpc.Event{
Keys: eventKeys,
Data: eventData,
},
}
e, err := ParseNewTransmissionEvent(event)
assert.NoError(t, err)

require.Equal(t, e.RoundId, uint32(1))
Expand Down Expand Up @@ -95,11 +113,19 @@ func TestNewTransmissionEvent_Parse(t *testing.T) {
}

func TestConfigSetEvent_Parse(t *testing.T) {
eventKeys, err := starknetutils.HexArrToFelt(configSetEventKeysRaw)
assert.NoError(t, err)
eventData, err := starknetutils.HexArrToFelt(configSetEventRaw)
assert.NoError(t, err)
require.Equal(t, len(configSetEventRaw), len(eventData))

e, err := ParseConfigSetEvent(eventData)
event := starknetrpc.EmittedEvent{
Event: starknetrpc.Event{
Keys: eventKeys,
Data: eventData,
},
}
e, err := ParseConfigSetEvent(event)
assert.NoError(t, err)

configDigest := XXXMustBytesToConfigDigest(starknet.XXXMustHexDecodeString("000485341c18461d70eac6ded4b8b17147f173308ddd56216a86f9ec4d994453"))
Expand Down

0 comments on commit 96ee08d

Please sign in to comment.