@@ -11,12 +11,14 @@ import (
1111
1212 "github.com/ethereum/go-ethereum/common"
1313 "github.com/google/uuid"
14+ "github.com/shopspring/decimal"
1415
1516 "github.com/smartcontractkit/chainlink-common/pkg/capabilities"
1617 "github.com/smartcontractkit/chainlink-common/pkg/logger"
1718 commontypes "github.com/smartcontractkit/chainlink-common/pkg/types"
1819 "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives"
1920
21+ evmtxmgr "github.com/smartcontractkit/chainlink-evm/pkg/txmgr"
2022 "github.com/smartcontractkit/chainlink-framework/capabilities/writetarget"
2123)
2224
2628)
2729
2830type evmTargetStrategy struct {
29- cr commontypes.ContractReader
30- cw commontypes.ContractWriter
31-
31+ cr commontypes.ContractReader
32+ cw commontypes.ContractWriter
33+ txm evmtxmgr. TxManager
3234 lggr logger.Logger
3335 forwarder string
3436
@@ -65,11 +67,15 @@ type Config struct {
6567 GasLimit * uint64
6668}
6769
68- func NewEVMTargetStrategy (cr commontypes.ContractReader , cw commontypes.ContractWriter , forwarder string , gasLimitDefault uint64 , lggr logger.Logger ) * evmTargetStrategy {
70+ func NewEVMTargetStrategy (cr commontypes.ContractReader , cw commontypes.ContractWriter , txm evmtxmgr.TxManager , forwarder string , gasLimitDefault uint64 , lggr logger.Logger ) (* evmTargetStrategy , error ) {
71+ if gasLimitDefault < ForwarderContractLogicGasCost {
72+ return nil , fmt .Errorf ("default gas limit '%d' is lower than forwarder estimate '%d'" , gasLimitDefault , ForwarderContractLogicGasCost )
73+ }
6974 bound := atomic.Bool {}
7075 return & evmTargetStrategy {
7176 cr : cr ,
7277 cw : cw ,
78+ txm : txm ,
7379 lggr : lggr ,
7480 forwarder : forwarder ,
7581 receiverGasMinimum : gasLimitDefault - ForwarderContractLogicGasCost ,
@@ -78,7 +84,7 @@ func NewEVMTargetStrategy(cr commontypes.ContractReader, cw commontypes.Contract
7884 Name : "forwarder" ,
7985 },
8086 bound : & bound ,
81- }
87+ }, nil
8288}
8389
8490func (t * evmTargetStrategy ) QueryTransmissionState (ctx context.Context , reportID uint16 , request capabilities.CapabilityRequest ) (* writetarget.TransmissionState , error ) {
@@ -171,6 +177,38 @@ func (t *evmTargetStrategy) QueryTransmissionState(ctx context.Context, reportID
171177 }, fmt .Errorf ("unexpected transmission state: %v" , transmissionInfo .State )
172178}
173179
180+ func (t * evmTargetStrategy ) GetEstimateFee (ctx context.Context , report []byte , reportContext []byte , signatures [][]byte ,
181+ request capabilities.CapabilityRequest ) (commontypes.EstimateFee , error ) {
182+ r , err := getEVMRequest (request )
183+ if err != nil {
184+ return commontypes.EstimateFee {}, err
185+ }
186+
187+ req := getRawReport (r )
188+ t .lggr .Debugw ("Transaction raw report" , "report" , hex .EncodeToString (req .RawReport ))
189+
190+ meta := commontypes.TxMeta {WorkflowExecutionID : & request .Metadata .WorkflowExecutionID }
191+ if r .Config .GasLimit != nil {
192+ meta .GasLimit = new (big.Int ).SetUint64 (* r .Config .GasLimit )
193+ }
194+
195+ value := big .NewInt (0 )
196+ return t .cw .GetEstimateFee (ctx , contractName , method , req , t .forwarder , & meta , value )
197+ }
198+
199+ func (t * evmTargetStrategy ) GetTransactionFee (ctx context.Context , transactionID string ) (decimal.Decimal , error ) {
200+ fee , err := t .txm .GetTransactionFee (ctx , transactionID )
201+ if err != nil {
202+ return decimal.Decimal {}, err
203+ }
204+ return decimal .New (fee .TransactionFee .Int64 (), - 18 ), nil
205+ }
206+
207+ var (
208+ contractName = "forwarder"
209+ method = "report"
210+ )
211+
174212// TransmitReport constructs the tx to transmit the report, and defines
175213// any specific handling for sending the report via ChainWriter.
176214func (t * evmTargetStrategy ) TransmitReport (ctx context.Context , _ []byte , _ []byte , _ [][]byte , request capabilities.CapabilityRequest ) (string , error ) {
@@ -183,16 +221,39 @@ func (t *evmTargetStrategy) TransmitReport(ctx context.Context, _ []byte, _ []by
183221 if err != nil {
184222 return txID .String (), fmt .Errorf ("failed to getEVMRequest: %w" , err )
185223 }
224+ req := getRawReport (r )
225+ t .lggr .Debugw ("Transaction raw report" , "report" , hex .EncodeToString (req .RawReport ))
226+
227+ meta := commontypes.TxMeta {WorkflowExecutionID : & request .Metadata .WorkflowExecutionID }
228+ if r .Config .GasLimit != nil {
229+ meta .GasLimit = new (big.Int ).SetUint64 (* r .Config .GasLimit )
230+ }
186231
232+ value := big .NewInt (0 )
233+ if err := t .cw .SubmitTransaction (ctx , contractName , method , req , txID .String (), t .forwarder , & meta , value ); err != nil {
234+ if ! commontypes .ErrSettingTransactionGasLimitNotSupported .Is (err ) {
235+ return txID .String (), fmt .Errorf ("failed to submit transaction: %w" , err )
236+ }
237+ meta .GasLimit = nil
238+ if err := t .cw .SubmitTransaction (ctx , contractName , method , req , txID .String (), t .forwarder , & meta , value ); err != nil {
239+ return txID .String (), fmt .Errorf ("failed to submit transaction: %w" , err )
240+ }
241+ }
242+ return txID .String (), nil
243+ }
244+
245+ type rawReport struct {
246+ Receiver string
247+ RawReport []byte
248+ ReportContext []byte
249+ Signatures [][]byte
250+ }
251+
252+ func getRawReport (r TargetRequest ) rawReport {
187253 // Note: The codec that ChainWriter uses to encode the parameters for the contract ABI cannot handle
188254 // `nil` values, including for slices. Until the bug is fixed we need to ensure that there are no
189255 // `nil` values passed in the request.
190- req := struct {
191- Receiver string
192- RawReport []byte
193- ReportContext []byte
194- Signatures [][]byte
195- }{r .Config .Address , r .Inputs .SignedReport .Report , r .Inputs .SignedReport .Context , r .Inputs .SignedReport .Signatures }
256+ req := rawReport {r .Config .Address , r .Inputs .SignedReport .Report , r .Inputs .SignedReport .Context , r .Inputs .SignedReport .Signatures }
196257
197258 if req .RawReport == nil {
198259 req .RawReport = make ([]byte , 0 )
@@ -205,24 +266,8 @@ func (t *evmTargetStrategy) TransmitReport(ctx context.Context, _ []byte, _ []by
205266 if req .Signatures == nil {
206267 req .Signatures = make ([][]byte , 0 )
207268 }
208- t .lggr .Debugw ("Transaction raw report" , "report" , hex .EncodeToString (req .RawReport ))
209269
210- meta := commontypes.TxMeta {WorkflowExecutionID : & request .Metadata .WorkflowExecutionID }
211- if r .Config .GasLimit != nil {
212- meta .GasLimit = new (big.Int ).SetUint64 (* r .Config .GasLimit )
213- }
214-
215- value := big .NewInt (0 )
216- if err := t .cw .SubmitTransaction (ctx , "forwarder" , "report" , req , txID .String (), t .forwarder , & meta , value ); err != nil {
217- if ! commontypes .ErrSettingTransactionGasLimitNotSupported .Is (err ) {
218- return txID .String (), fmt .Errorf ("failed to submit transaction: %w" , err )
219- }
220- meta .GasLimit = nil
221- if err := t .cw .SubmitTransaction (ctx , "forwarder" , "report" , req , txID .String (), t .forwarder , & meta , value ); err != nil {
222- return txID .String (), fmt .Errorf ("failed to submit transaction: %w" , err )
223- }
224- }
225- return txID .String (), nil
270+ return req
226271}
227272
228273func (t * evmTargetStrategy ) GetTransactionStatus (ctx context.Context , transactionID string ) (commontypes.TransactionStatus , error ) {
0 commit comments