Skip to content

Commit d648725

Browse files
committed
add passthrough encoder
1 parent 3210bf2 commit d648725

File tree

1 file changed

+117
-7
lines changed

1 file changed

+117
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,129 @@
11
package ocr3
22

33
import (
4+
"bytes"
45
"context"
6+
"encoding/binary"
7+
"encoding/hex"
8+
"fmt"
59

6-
"google.golang.org/protobuf/proto"
7-
8-
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types"
10+
consensustypes "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types"
911
"github.com/smartcontractkit/chainlink-common/pkg/values"
1012
)
1113

1214
type ValueMapEncoder struct{}
1315

14-
func (v ValueMapEncoder) Encode(_ context.Context, input values.Map) ([]byte, error) {
15-
opts := proto.MarshalOptions{Deterministic: true}
16-
return opts.Marshal(values.Proto(&input))
16+
type ReportV1Metadata struct {
17+
Version uint8
18+
WorkflowExecutionID [32]byte
19+
Timestamp uint32
20+
DonID uint32
21+
DonConfigVersion uint32
22+
WorkflowCID [32]byte
23+
WorkflowName [10]byte
24+
WorkflowOwner [20]byte
25+
ReportID [2]byte
26+
}
27+
28+
func (rm ReportV1Metadata) Encode() ([]byte, error) {
29+
buf := new(bytes.Buffer)
30+
err := binary.Write(buf, binary.BigEndian, rm)
31+
if err != nil {
32+
return nil, err
33+
}
34+
return buf.Bytes(), nil
35+
}
36+
37+
func (v ValueMapEncoder) Encode(ctx context.Context, input values.Map) ([]byte, error) {
38+
metaMap, ok := input.Underlying["INTERNAL_METADATA"]
39+
if !ok {
40+
return nil, fmt.Errorf("expected metadata field to be present: %s", "INTERNAL_METADATA")
41+
}
42+
43+
dataMap, ok := input.Underlying["0"]
44+
if !ok {
45+
return nil, fmt.Errorf("expected metadata field to be present: %s", "0")
46+
}
47+
48+
var meta consensustypes.Metadata
49+
err := metaMap.UnwrapTo(&meta)
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
var data []byte
55+
err = dataMap.UnwrapTo(&data)
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
return prependMetadataFields(meta, data)
61+
}
62+
63+
func prependMetadataFields(meta consensustypes.Metadata, userPayload []byte) ([]byte, error) {
64+
var err error
65+
var result []byte
66+
67+
// 1. Version (1 byte)
68+
if meta.Version > 255 {
69+
return nil, fmt.Errorf("version must be between 0 and 255")
70+
}
71+
result = append(result, byte(meta.Version))
72+
73+
// 2. Execution ID (32 bytes)
74+
if result, err = decodeAndAppend(meta.ExecutionID, 32, result, "ExecutionID"); err != nil {
75+
return nil, err
76+
}
77+
78+
// 3. Timestamp (4 bytes)
79+
tsBytes := make([]byte, 4)
80+
binary.BigEndian.PutUint32(tsBytes, meta.Timestamp)
81+
result = append(result, tsBytes...)
82+
83+
// 4. DON ID (4 bytes)
84+
donIDBytes := make([]byte, 4)
85+
binary.BigEndian.PutUint32(donIDBytes, meta.DONID)
86+
result = append(result, donIDBytes...)
87+
88+
// 5. DON config version (4 bytes)
89+
cfgVersionBytes := make([]byte, 4)
90+
binary.BigEndian.PutUint32(cfgVersionBytes, meta.DONConfigVersion)
91+
result = append(result, cfgVersionBytes...)
92+
93+
// 6. Workflow ID / spec hash (32 bytes)
94+
if result, err = decodeAndAppend(meta.WorkflowID, 32, result, "WorkflowID"); err != nil {
95+
return nil, err
96+
}
97+
98+
// 7. Workflow Name (10 bytes)
99+
if result, err = decodeAndAppend(meta.WorkflowName, 10, result, "WorkflowName"); err != nil {
100+
return nil, err
101+
}
102+
103+
// 8. Workflow Owner (20 bytes)
104+
if result, err = decodeAndAppend(meta.WorkflowOwner, 20, result, "WorkflowOwner"); err != nil {
105+
return nil, err
106+
}
107+
108+
// 9. Report ID (2 bytes)
109+
if result, err = decodeAndAppend(meta.ReportID, 2, result, "ReportID"); err != nil {
110+
return nil, err
111+
}
112+
113+
return append(result, userPayload...), nil
17114
}
18115

19-
var _ types.Encoder = (*ValueMapEncoder)(nil)
116+
func decodeAndAppend(id string, expectedLen int, prevResult []byte, logName string) ([]byte, error) {
117+
b, err := hex.DecodeString(id)
118+
if err != nil {
119+
return nil, fmt.Errorf("failed to hex-decode %s (%s): %w", logName, id, err)
120+
}
121+
if len(b) > expectedLen {
122+
return nil, fmt.Errorf("incorrect length for id %s (%s), expected at most %d bytes, got %d", logName, id, expectedLen, len(b))
123+
}
124+
if len(b) < expectedLen {
125+
padding := make([]byte, expectedLen-len(b))
126+
b = append(b, padding...)
127+
}
128+
return append(prevResult, b...), nil
129+
}

0 commit comments

Comments
 (0)