Skip to content

Commit 12b7064

Browse files
dimrocse3000
authored andcommitted
intro TxReceiptStatus for statuses defined by EIP658
ethereum/EIPs#658
1 parent 0a8aeb3 commit 12b7064

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

core/adapters/eth_tx_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ func TestEthTxAdapter_Perform_FromPendingConfirmations_ConfirmCompletes(t *testi
297297
ethMock := app.MockEthClient()
298298
ethMock.Register("eth_getTransactionReceipt", strpkg.TxReceipt{})
299299
confirmedHash := cltest.NewHash()
300-
receipt := strpkg.TxReceipt{Hash: confirmedHash, BlockNumber: cltest.Int(sentAt)}
300+
receipt := strpkg.TxReceipt{Hash: confirmedHash, BlockNumber: cltest.Int(sentAt), Status: strpkg.TxReceiptSuccess}
301301
ethMock.Register("eth_getTransactionReceipt", receipt)
302302
confirmedAt := sentAt + config.MinOutgoingConfirmations() - 1 // confirmations are 0-based idx
303303
ethMock.Register("eth_blockNumber", utils.Uint64ToHex(confirmedAt))
@@ -352,7 +352,7 @@ func TestEthTxAdapter_Perform_AppendingTransactionReceipts(t *testing.T) {
352352
sentAt := uint64(23456)
353353

354354
ethMock := app.MockEthClient()
355-
receipt := strpkg.TxReceipt{Hash: cltest.NewHash(), BlockNumber: cltest.Int(sentAt)}
355+
receipt := strpkg.TxReceipt{Hash: cltest.NewHash(), BlockNumber: cltest.Int(sentAt), Status: strpkg.TxReceiptSuccess}
356356
ethMock.Register("eth_getTransactionReceipt", receipt)
357357
confirmedAt := sentAt + config.MinOutgoingConfirmations() - 1 // confirmations are 0-based idx
358358
ethMock.Register("eth_blockNumber", utils.Uint64ToHex(confirmedAt))
@@ -368,7 +368,7 @@ func TestEthTxAdapter_Perform_AppendingTransactionReceipts(t *testing.T) {
368368

369369
input := sentResult
370370
input.MarkPendingConfirmations()
371-
previousReceipt := strpkg.TxReceipt{Hash: cltest.NewHash(), BlockNumber: cltest.Int(sentAt - 10)}
371+
previousReceipt := strpkg.TxReceipt{Hash: cltest.NewHash(), BlockNumber: cltest.Int(sentAt - 10), Status: strpkg.TxReceiptSuccess}
372372
input.Add("ethereumReceipts", []strpkg.TxReceipt{previousReceipt})
373373

374374
output := adapter.Perform(input, store)

core/store/eth_client.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package store
22

33
import (
44
"context"
5+
"fmt"
56
"math/big"
67

78
ethereum "github.com/ethereum/go-ethereum"
@@ -157,8 +158,9 @@ func (eth *EthClient) SubscribeToNewHeads(
157158
// TxReceipt holds the block number and the transaction hash of a signed
158159
// transaction that has been written to the blockchain.
159160
type TxReceipt struct {
160-
BlockNumber *models.Big `json:"blockNumber" gorm:"type:numeric"`
161-
Hash common.Hash `json:"transactionHash"`
161+
BlockNumber *models.Big `json:"blockNumber" gorm:"type:numeric"`
162+
Hash common.Hash `json:"transactionHash"`
163+
Status TxReceiptStatus `json:"status"`
162164
}
163165

164166
var emptyHash = common.Hash{}
@@ -167,3 +169,33 @@ var emptyHash = common.Hash{}
167169
func (txr *TxReceipt) Unconfirmed() bool {
168170
return txr.Hash == emptyHash || txr.BlockNumber == nil
169171
}
172+
173+
// TxReceiptStatus encapsulates the different return values available
174+
// for an ethereum transaction receipt as defined by
175+
// http://eips.ethereum.org/EIPS/eip-658
176+
type TxReceiptStatus string
177+
178+
const (
179+
// TxReceiptRevert represents the status that results in any failure and
180+
// resulting revert.
181+
TxReceiptRevert TxReceiptStatus = "0x0"
182+
// TxReceiptSuccess represents a successful transaction, not resulting in a
183+
// revert.
184+
TxReceiptSuccess = "0x1"
185+
)
186+
187+
// UnmarshalText parses text input to a predefined transaction receipt
188+
// status as defined by Ethereum or an EIP. Returns an error if we encounter
189+
// unexpected input.
190+
func (trs *TxReceiptStatus) UnmarshalText(input []byte) error {
191+
switch TxReceiptStatus(input) {
192+
case TxReceiptRevert:
193+
*trs = TxReceiptRevert
194+
case TxReceiptSuccess:
195+
*trs = TxReceiptSuccess
196+
default:
197+
return fmt.Errorf("unable to convert %s to %T", string(input), trs)
198+
}
199+
200+
return nil
201+
}

core/store/eth_client_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/ethereum/go-ethereum/common"
1010
"github.com/smartcontractkit/chainlink/core/internal/cltest"
11+
"github.com/smartcontractkit/chainlink/core/store"
1112
strpkg "github.com/smartcontractkit/chainlink/core/store"
1213
"github.com/stretchr/testify/assert"
1314
"github.com/stretchr/testify/require"
@@ -124,3 +125,68 @@ func TestEthClient_GetERC20Balance(t *testing.T) {
124125
assert.NoError(t, err)
125126
assert.Equal(t, expected, result)
126127
}
128+
129+
func TestTxReceiptStatus_UnmarshalText_Success(t *testing.T) {
130+
t.Parallel()
131+
132+
tests := []struct {
133+
input string
134+
expected store.TxReceiptStatus
135+
}{
136+
{"0x0", store.TxReceiptRevert},
137+
{"0x1", store.TxReceiptSuccess},
138+
}
139+
140+
for _, test := range tests {
141+
t.Run(test.input, func(t *testing.T) {
142+
var ptrs store.TxReceiptStatus
143+
err := ptrs.UnmarshalText([]byte(test.input))
144+
assert.NoError(t, err)
145+
assert.Equal(t, test.expected, ptrs)
146+
})
147+
}
148+
}
149+
150+
func TestTxReceiptStatus_UnmarshalText_Error(t *testing.T) {
151+
t.Parallel()
152+
153+
tests := []struct {
154+
input string
155+
}{
156+
{""},
157+
{"0x"},
158+
}
159+
160+
for _, test := range tests {
161+
t.Run(test.input, func(t *testing.T) {
162+
var ptrs store.TxReceiptStatus
163+
err := ptrs.UnmarshalText([]byte(test.input))
164+
assert.Error(t, err)
165+
})
166+
}
167+
}
168+
169+
func TestTxReceiptStatus_UnmarshalJSON_Success(t *testing.T) {
170+
t.Parallel()
171+
172+
type subject struct {
173+
Status store.TxReceiptStatus `json:"status"`
174+
}
175+
176+
tests := []struct {
177+
input string
178+
expected store.TxReceiptStatus
179+
}{
180+
{`{"status": "0x0"}`, store.TxReceiptRevert},
181+
{`{"status": "0x1"}`, store.TxReceiptSuccess},
182+
}
183+
184+
for _, test := range tests {
185+
t.Run(test.input, func(t *testing.T) {
186+
var dst subject
187+
err := json.Unmarshal([]byte(test.input), &dst)
188+
require.NoError(t, err)
189+
assert.Equal(t, test.expected, dst.Status)
190+
})
191+
}
192+
}

0 commit comments

Comments
 (0)