Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
Signed-off-by: SamMayWork <[email protected]>
  • Loading branch information
SamMayWork committed May 10, 2024
2 parents 7717d19 + 67fdd49 commit 266e6bd
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 48 deletions.
1 change: 1 addition & 0 deletions config.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
|passthroughHeadersEnabled|Enable passing through the set of allowed HTTP request headers|`boolean`|`false`
|requestTimeout|The maximum amount of time that a request is allowed to remain open|[`time.Duration`](https://pkg.go.dev/time#Duration)|`30s`
|tlsHandshakeTimeout|The maximum amount of time to wait for a successful TLS handshake|[`time.Duration`](https://pkg.go.dev/time#Duration)|`10s`
|traceTXForRevertReason|Enable the use of transaction trace functions (e.g. debug_traceTransaction) to obtain transaction revert reasons. This can place a high load on the EVM client.|`boolean`|`false`
|txCacheSize|Maximum of transactions to hold in the transaction info cache|`int`|`250`
|url|URL of JSON/RPC endpoint for the Ethereum node/gateway|string|`<nil>`

Expand Down
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ require (
github.com/hashicorp/golang-lru v1.0.2
github.com/hyperledger/firefly-common v1.4.6
github.com/hyperledger/firefly-signer v1.1.13
github.com/hyperledger/firefly-transaction-manager v1.3.9
github.com/hyperledger/firefly-transaction-manager v1.3.11
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.20.0
golang.org/x/net v0.23.0
golang.org/x/text v0.14.0
gopkg.in/yaml.v2 v2.4.0
)
Expand Down Expand Up @@ -90,10 +90,10 @@ require (
gitlab.com/hfuss/mux-prometheus v0.0.5 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.16.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/hyperledger/firefly-common v1.4.6 h1:qqXoSaRml3WjUnWcWxrrXs5AIOWa+UcMXLCF8yEa4Pk=
github.com/hyperledger/firefly-common v1.4.6/go.mod h1:jkErZdQmC9fsAJZQO427tURdwB9iiW+NMUZSqS3eBIE=
github.com/hyperledger/firefly-transaction-manager v1.3.9 h1:lysp0ZIxd4zR53Eu+lRjEcJ1hbmHaAsIESBrmBWWito=
github.com/hyperledger/firefly-transaction-manager v1.3.9/go.mod h1:N3BoHh8+dWG710oQKuNiXmJNEOBBeLTsQ8GpZ41vhog=
github.com/hyperledger/firefly-transaction-manager v1.3.11 h1:sUYGUSZbuuxzHjQgvSsJtKLSgaQqRjMEy/bgM6dUJwM=
github.com/hyperledger/firefly-transaction-manager v1.3.11/go.mod h1:N3BoHh8+dWG710oQKuNiXmJNEOBBeLTsQ8GpZ41vhog=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
Expand Down Expand Up @@ -259,8 +259,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e h1:723BNChdd0c2Wk6WOE320qGBiPtYx0F0Bbm1kriShfE=
golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
Expand All @@ -278,8 +278,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -304,16 +304,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
5 changes: 5 additions & 0 deletions internal/ethereum/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
MaxConcurrentRequests = "maxConcurrentRequests"
TxCacheSize = "txCacheSize"
HederaCompatibilityMode = "hederaCompatibilityMode"
TraceTXForRevertReason = "traceTXForRevertReason"
)

const (
Expand Down Expand Up @@ -71,5 +72,9 @@ func InitConfig(conf config.Section) {
conf.AddKnownKey(RetryMaxDelay, DefaultRetryMaxDelay)
conf.AddKnownKey(MaxConcurrentRequests, 50)
conf.AddKnownKey(TxCacheSize, 250)
<<<<<<< HEAD

Check failure on line 75 in internal/ethereum/config.go

View workflow job for this annotation

GitHub Actions / build

syntax error: unexpected <<, expected }
conf.AddKnownKey(HederaCompatibilityMode, false)
=======
conf.AddKnownKey(TraceTXForRevertReason, false)
>>>>>>> 67fdd4913465665a4e21d47636a5674323bdfcf3
}
2 changes: 2 additions & 0 deletions internal/ethereum/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type ethConnector struct {
eventBlockTimestamps bool
blockListener *blockListener
eventFilterPollingInterval time.Duration
traceTXForRevertReason bool

mux sync.Mutex
eventStreams map[fftypes.UUID]*eventStream
Expand All @@ -64,6 +65,7 @@ func NewEthereumConnector(ctx context.Context, conf config.Section) (cc ffcapi.A
checkpointBlockGap: conf.GetInt64(EventsCheckpointBlockGap),
eventBlockTimestamps: conf.GetBool(EventsBlockTimestamps),
eventFilterPollingInterval: conf.GetDuration(EventsFilterPollingInterval),
traceTXForRevertReason: conf.GetBool(TraceTXForRevertReason),
retry: &retry.Retry{
InitialDelay: conf.GetDuration(RetryInitDelay),
MaximumDelay: conf.GetDuration(RetryMaxDelay),
Expand Down
1 change: 1 addition & 0 deletions internal/ethereum/ethereum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func newTestConnector(t *testing.T) (context.Context, *ethConnector, *rpcbackend
config.RootConfigReset()
conf := config.RootSection("unittest")
InitConfig(conf)
//conf.Set(TraceTXForRevertReason, true)
conf.Set(ffresty.HTTPConfigURL, "http://localhost:8545")
conf.Set(BlockPollingInterval, "1h") // Disable for tests that are not using it
logrus.SetLevel(logrus.DebugLevel)
Expand Down
82 changes: 52 additions & 30 deletions internal/ethereum/get_receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,26 @@ import (

"github.com/hyperledger/firefly-common/pkg/fftypes"
"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/hyperledger/firefly-common/pkg/log"
"github.com/hyperledger/firefly-evmconnect/internal/msgs"
"github.com/hyperledger/firefly-signer/pkg/ethtypes"
"github.com/hyperledger/firefly-transaction-manager/pkg/ffcapi"
)

// txReceiptJSONRPC is the receipt obtained over JSON/RPC from the ethereum client, with gas used, logs and contract address
type txReceiptJSONRPC struct {
BlockHash ethtypes.HexBytes0xPrefix `json:"blockHash"`
BlockNumber *ethtypes.HexInteger `json:"blockNumber"`
ContractAddress *ethtypes.Address0xHex `json:"contractAddress"`
CumulativeGasUsed *ethtypes.HexInteger `json:"cumulativeGasUsed"`
From *ethtypes.Address0xHex `json:"from"`
GasUsed *ethtypes.HexInteger `json:"gasUsed"`
Logs []*logJSONRPC `json:"logs"`
Status *ethtypes.HexInteger `json:"status"`
To *ethtypes.Address0xHex `json:"to"`
TransactionHash ethtypes.HexBytes0xPrefix `json:"transactionHash"`
TransactionIndex *ethtypes.HexInteger `json:"transactionIndex"`
BlockHash ethtypes.HexBytes0xPrefix `json:"blockHash"`
BlockNumber *ethtypes.HexInteger `json:"blockNumber"`
ContractAddress *ethtypes.Address0xHex `json:"contractAddress"`
CumulativeGasUsed *ethtypes.HexInteger `json:"cumulativeGasUsed"`
From *ethtypes.Address0xHex `json:"from"`
GasUsed *ethtypes.HexInteger `json:"gasUsed"`
Logs []*logJSONRPC `json:"logs"`
Status *ethtypes.HexInteger `json:"status"`
To *ethtypes.Address0xHex `json:"to"`
TransactionHash ethtypes.HexBytes0xPrefix `json:"transactionHash"`
TransactionIndex *ethtypes.HexInteger `json:"transactionIndex"`
RevertReason *ethtypes.HexBytes0xPrefix `json:"revertReason"`
}

// receiptExtraInfo is the version of the receipt we store under the TX.
Expand Down Expand Up @@ -119,30 +121,50 @@ func ProtocolIDForReceipt(blockNumber, transactionIndex *fftypes.FFBigInt) strin
return ""
}

func (c *ethConnector) getErrorInfo(ctx context.Context, transactionHash string) (pReturnValue *string, pErrorMessage *string) {

// Attempt to get the return value of the transaction - not possible on all RPC endpoints
var debugTrace *txDebugTrace
traceErr := c.backend.CallRPC(ctx, &debugTrace, "debug_traceTransaction", transactionHash)
if traceErr != nil {
msg := i18n.NewError(ctx, msgs.MsgUnableToCallDebug, traceErr).Error()
return nil, &msg
func padHexData(hexString string) string {
hexString = strings.TrimPrefix(hexString, "0x")
if len(hexString)%2 == 1 {
hexString = "0" + hexString
}

returnValue := debugTrace.ReturnValue
if returnValue == "" {
// some clients (e.g. Besu) include the error reason on the final struct log
if len(debugTrace.StructLogs) > 0 {
finalStructLog := debugTrace.StructLogs[len(debugTrace.StructLogs)-1]
if *finalStructLog.Op == "REVERT" && finalStructLog.Reason != nil {
returnValue = *finalStructLog.Reason
return hexString
}

func (c *ethConnector) getErrorInfo(ctx context.Context, transactionHash string, revertFromReceipt *ethtypes.HexBytes0xPrefix) (pReturnValue *string, pErrorMessage *string) {

var revertReason string
if revertFromReceipt == nil {
// Tracing a transaction to get revert information is expensive so it's not enabled by default
if c.traceTXForRevertReason {
log.L(ctx).Trace("No revert reason for the failed transaction found in the receipt. Calling debug_traceTransaction to retrieve it.")
// Attempt to get the return value of the transaction - not possible on all RPC endpoints
var debugTrace *txDebugTrace
traceErr := c.backend.CallRPC(ctx, &debugTrace, "debug_traceTransaction", transactionHash)
if traceErr != nil {
msg := i18n.NewError(ctx, msgs.MsgUnableToCallDebug, traceErr).Error()
return nil, &msg
}

revertReason = debugTrace.ReturnValue
log.L(ctx).Debugf("Revert reason from debug_traceTransaction: '%v'", revertReason)
if revertReason == "" {
// some clients (e.g. Besu) include the error reason on the final struct log
if len(debugTrace.StructLogs) > 0 {
finalStructLog := debugTrace.StructLogs[len(debugTrace.StructLogs)-1]
if *finalStructLog.Op == "REVERT" && finalStructLog.Reason != nil {
revertReason = *finalStructLog.Reason
}
}
}
}
} else {
log.L(ctx).Trace("Revert reason is set in the receipt. Skipping call to debug_traceTransaction.")
revertReason = revertFromReceipt.String()
}

// See if the return value is using the default error you get from "revert"
var errorMessage string
returnDataBytes, _ := hex.DecodeString(strings.TrimPrefix(returnValue, "0x"))
returnDataBytes, _ := hex.DecodeString(padHexData(revertReason))
if len(returnDataBytes) > 4 && bytes.Equal(returnDataBytes[0:4], defaultErrorID) {
value, err := defaultError.DecodeCallDataCtx(ctx, returnDataBytes)
if err == nil {
Expand All @@ -153,12 +175,12 @@ func (c *ethConnector) getErrorInfo(ctx context.Context, transactionHash string)
// Otherwise we can't decode it, so put it directly in the error
if errorMessage == "" {
if len(returnDataBytes) > 0 {
errorMessage = i18n.NewError(ctx, msgs.MsgReturnValueNotDecoded, returnValue).Error()
errorMessage = i18n.NewError(ctx, msgs.MsgReturnValueNotDecoded, revertReason).Error()
} else {
errorMessage = i18n.NewError(ctx, msgs.MsgReturnValueNotAvailable).Error()
}
}
return &returnValue, &errorMessage
return &revertReason, &errorMessage
}

func (c *ethConnector) TransactionReceipt(ctx context.Context, req *ffcapi.TransactionReceiptRequest) (*ffcapi.TransactionReceiptResponse, ffcapi.ErrorReason, error) {
Expand All @@ -178,7 +200,7 @@ func (c *ethConnector) TransactionReceipt(ctx context.Context, req *ffcapi.Trans
var transactionErrorMessage *string

if !isSuccess {
returnDataString, transactionErrorMessage = c.getErrorInfo(ctx, req.TransactionHash)
returnDataString, transactionErrorMessage = c.getErrorInfo(ctx, req.TransactionHash, ethReceipt.RevertReason)
}

ethReceipt.Logs = nil
Expand Down
Loading

0 comments on commit 266e6bd

Please sign in to comment.