Skip to content

Commit 46f0d8f

Browse files
metering for consensus cap (#1099)
* metering for consensus cap * Adding MeterableCapability iface * clean up * removing MeterableCapability iface in favor of MeteringUnit struct * fixing tests * values.ByteSizeOfMap --> private utility * updating access pattern to metering.unit * metering.XyzMeteringUnit --> metering.XyzUnit
1 parent 00dd182 commit 46f0d8f

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

pkg/capabilities/consensus/ocr3/capability.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import (
77
"time"
88

99
"github.com/jonboulle/clockwork"
10+
"google.golang.org/protobuf/proto"
1011

1112
"github.com/smartcontractkit/chainlink-common/pkg/capabilities"
1213
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/requests"
1314
"github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types"
1415
"github.com/smartcontractkit/chainlink-common/pkg/logger"
16+
"github.com/smartcontractkit/chainlink-common/pkg/metering"
1517
"github.com/smartcontractkit/chainlink-common/pkg/services"
1618
"github.com/smartcontractkit/chainlink-common/pkg/values"
1719
)
@@ -212,6 +214,7 @@ func (o *capability) Execute(ctx context.Context, r capabilities.CapabilityReque
212214
if err != nil {
213215
return capabilities.CapabilityResponse{}, err
214216
}
217+
inputLenBytes := byteSizeOfMap(r.Inputs)
215218

216219
config, err := o.ValidateConfig(r.Config)
217220
if err != nil {
@@ -224,8 +227,14 @@ func (o *capability) Execute(ctx context.Context, r capabilities.CapabilityReque
224227
}
225228

226229
response := <-ch
230+
outputLenBytes := byteSizeOfMap(response.Value)
227231
return capabilities.CapabilityResponse{
228232
Value: response.Value,
233+
Metadata: capabilities.ResponseMetadata{
234+
Metering: []capabilities.MeteringNodeDetail{
235+
{SpendUnit: metering.PayloadUnit.Name, SpendValue: fmt.Sprintf("%d", inputLenBytes+outputLenBytes)},
236+
},
237+
},
229238
}, response.Err
230239
}
231240

@@ -276,3 +285,14 @@ func (o *capability) queueRequestForProcessing(
276285
o.reqHandler.SendRequest(ctx, r)
277286
return callbackCh, nil
278287
}
288+
289+
// byteSizeOfMap is a utility to get the wire-size
290+
// of a values.Map.
291+
func byteSizeOfMap(m *values.Map) int {
292+
if m == nil {
293+
return 0
294+
}
295+
pbVal := values.Proto(m)
296+
size := proto.Size(pbVal)
297+
return size
298+
}

pkg/capabilities/consensus/ocr3/capability_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ func TestOCR3Capability(t *testing.T) {
139139
assert.NoError(t, resp.Err)
140140

141141
assert.Equal(t, mresp, resp.Value)
142+
assert.Equal(t, "payload", resp.Metadata.Metering[0].SpendUnit)
143+
assert.Equal(t, "122", resp.Metadata.Metering[0].SpendValue)
142144
})
143145
}
144146
}
@@ -459,7 +461,7 @@ func TestOCR3Capability_RespondsToLateRequest(t *testing.T) {
459461
Value: obsv,
460462
}
461463

462-
assert.Equal(t, expectedCapabilityResponse, response)
464+
assert.Equal(t, expectedCapabilityResponse.Value, response.Value)
463465
}
464466

465467
func TestOCR3Capability_RespondingToLateRequestDoesNotBlockOnSlowResponseConsumer(t *testing.T) {
@@ -519,7 +521,7 @@ func TestOCR3Capability_RespondingToLateRequestDoesNotBlockOnSlowResponseConsume
519521
Value: obsv,
520522
}
521523

522-
assert.Equal(t, expectedCapabilityResponse, resp)
524+
assert.Equal(t, expectedCapabilityResponse.Value, resp.Value)
523525
}
524526

525527
type asyncCapabilityResponse struct {
@@ -531,7 +533,7 @@ func executeAsync(ctx context.Context, request capabilities.CapabilityRequest, t
531533
respCh := make(chan asyncCapabilityResponse, 1)
532534
go func() {
533535
resp, err := toExecute(ctx, request)
534-
respCh <- asyncCapabilityResponse{CapabilityResponse: capabilities.CapabilityResponse{Value: resp.Value}, Err: err}
536+
respCh <- asyncCapabilityResponse{CapabilityResponse: capabilities.CapabilityResponse{Value: resp.Value, Metadata: resp.Metadata}, Err: err}
535537
close(respCh)
536538
}()
537539

pkg/metering/units.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package metering
2+
3+
var (
4+
PayloadUnit = unit{Name: "payload", Unit: "bytes"}
5+
6+
// ComputeUnit is an example. The compute cap will eventually be obsoleted
7+
// by the CRE No-DAG SDK.
8+
ComputeUnit = unit{Name: "compute", Unit: "seconds"}
9+
)
10+
11+
// unit provides exported Name and unit fields for
12+
// capability devs to consume when implementing
13+
// metering. Do not export.
14+
type unit struct {
15+
// Name of the Metering Unit, i.e. payload, compute, storage
16+
Name string
17+
18+
// Unit of the Metering Unit, i.e. bytes, seconds
19+
Unit string
20+
}

0 commit comments

Comments
 (0)