Skip to content

Commit

Permalink
Merge pull request #3112 from smartcontractkit/release/0.8.8-rc3
Browse files Browse the repository at this point in the history
Release/0.8.8 rc3
  • Loading branch information
tyrion70 authored Jun 29, 2020
2 parents fad433b + 279bcd5 commit f3e9c1e
Show file tree
Hide file tree
Showing 194 changed files with 7,061 additions and 4,469 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.8.8] - 2020-06-29

### Added

- `ethtx` tasks now support a new parameter, `minRequiredOutgoingConfirmations` which allows you to tune how many confirmations are required before moving on from an `ethtx` task on a per task basis (only works with BulletproofTxManager). If it is not supplied, the default of `MIN_OUTGOING_CONFIRMATIONS` is used (same as the old behaviour).

### Changed

- HeadTracker now automatically backfills missing heads up to `ETH_FINALITY_DEPTH`

### Breaking changes

- `admin withdraw` command has been removed. This was only ever useful to withdraw LINK if the Oracle contract was owned by the Chainlink node address. It is no longer recommended to have the Oracle owner be the chainlink node address.
- Fixed `txs create` to send the amount in Eth not in Wei (as per the documentation)

## [0.8.7] - 2020-06-15

### Added
Expand Down Expand Up @@ -59,6 +74,8 @@ This release contains a number of features aimed at improving the node's reliabi
on `FluxAggregator`, `WhitelistedAggregator`, `AggregatorProxy`,
`WhitelistedAggregatorProxy`.
- Updated the solidity compiler version for v0.6 from 0.6.2 to 0.6.6.
- AccessControlledAggregatorProxy checks an external contract for users to be able to
read functions.

### Fixed

Expand Down
16 changes: 14 additions & 2 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,27 @@ install-chainlink: chainlink ## Install the chainlink binary.
cp $< $(GOBIN)/chainlink

chainlink: $(SGX_BUILD_ENCLAVE) operator-ui ## Build the chainlink binary.
CGO_ENABLED=0 go run packr/main.go "${CURDIR}/core/eth" ## embed contracts in .go file
CGO_ENABLED=0 go run packr/main.go "${CURDIR}/core/services/eth" ## embed contracts in .go file
go build $(GOFLAGS) -o $@ ./core/

.PHONY: chainlink-build
chainlink-build:
CGO_ENABLED=0 go run packr/main.go "${CURDIR}/core/services/eth" ## embed contracts in .go file
CGO_ENABLED=0 go run packr/main.go "${CURDIR}/core/services"
go build $(GOFLAGS) -o chainlink ./core/
cp chainlink $(GOBIN)/chainlink

.PHONY: operator-ui
operator-ui: ## Build the static frontend UI.
yarn setup:chainlink
CHAINLINK_VERSION="$(VERSION)@$(COMMIT_SHA)" yarn workspace @chainlink/operator-ui build
CGO_ENABLED=0 go run packr/main.go "${CURDIR}/core/services"

.PHONY: contracts-operator-ui-build
contracts-operator-ui-build: # only compiles tsc and builds contracts and operator-ui
yarn setup:chainlink
CHAINLINK_VERSION="$(VERSION)@$(COMMIT_SHA)" yarn workspace @chainlink/operator-ui build

.PHONY: abigen
abigen:
./tools/bin/build_abigen
Expand All @@ -79,7 +91,7 @@ abigen:
go-solidity-wrappers: abigen ## Recompiles solidity contracts and their go wrappers
yarn workspace @chainlink/contracts compile
go generate ./core/internal/gethwrappers
go run ./packr/main.go ./core/eth/
go run ./packr/main.go ./core/services/eth/

.PHONY: testdb
testdb: ## Prepares the test database
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.7
0.8.8
31 changes: 18 additions & 13 deletions core/adapters/eth_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"

"github.com/smartcontractkit/chainlink/core/eth"
"github.com/smartcontractkit/chainlink/core/logger"
"github.com/smartcontractkit/chainlink/core/store"
strpkg "github.com/smartcontractkit/chainlink/core/store"
Expand All @@ -27,12 +26,12 @@ const (
// EthTx holds the Address to send the result to and the FunctionSelector
// to execute.
type EthTx struct {
ToAddress common.Address `json:"address"`
FromAddress common.Address `json:"fromAddress,omitempty"`
FunctionSelector eth.FunctionSelector `json:"functionSelector"`
DataPrefix hexutil.Bytes `json:"dataPrefix"`
DataFormat string `json:"format"`
GasLimit uint64 `json:"gasLimit,omitempty"`
ToAddress common.Address `json:"address"`
FromAddress common.Address `json:"fromAddress,omitempty"`
FunctionSelector models.FunctionSelector `json:"functionSelector"`
DataPrefix hexutil.Bytes `json:"dataPrefix"`
DataFormat string `json:"format"`
GasLimit uint64 `json:"gasLimit,omitempty"`

// GasPrice only needed for legacy tx manager
GasPrice *utils.Big `json:"gasPrice" gorm:"type:numeric"`
Expand Down Expand Up @@ -124,7 +123,7 @@ func (e *EthTx) insertEthTx(input models.RunInput, store *store.Store) models.Ru
func (e *EthTx) checkEthTxForReceipt(ethTxID int64, input models.RunInput, s *store.Store) models.RunOutput {
var minRequiredOutgoingConfirmations uint64
if e.MinRequiredOutgoingConfirmations == 0 {
minRequiredOutgoingConfirmations = s.Config.MinOutgoingConfirmations()
minRequiredOutgoingConfirmations = s.Config.MinRequiredOutgoingConfirmations()
} else {
minRequiredOutgoingConfirmations = e.MinRequiredOutgoingConfirmations
}
Expand All @@ -140,8 +139,14 @@ func (e *EthTx) checkEthTxForReceipt(ethTxID int64, input models.RunInput, s *st
return models.NewRunOutputPendingOutgoingConfirmationsWithData(input.Data())
}

output := models.JSON{}
output, err = output.Add("result", (*hash).Hex())
hexHash := (*hash).Hex()

output := input.Data()
output, err = output.MultiAdd(models.KV{
"result": hexHash,
// HACK: latestOutgoingTxHash is used for backwards compatibility with the stats pusher
"latestOutgoingTxHash": hexHash,
})
if err != nil {
err = errors.Wrap(err, "checkEthTxForReceipt failed")
logger.Error(err)
Expand All @@ -154,7 +159,7 @@ func getConfirmedTxHash(ethTxID int64, db *gorm.DB, minRequiredOutgoingConfirmat
receipt := models.EthReceipt{}
err := db.
Joins("INNER JOIN eth_tx_attempts ON eth_tx_attempts.hash = eth_receipts.tx_hash AND eth_tx_attempts.eth_tx_id = ?", ethTxID).
Joins("INNER JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state = ?", models.EthTxConfirmed).
Joins("INNER JOIN eth_txes ON eth_txes.id = eth_tx_attempts.eth_tx_id AND eth_txes.state = 'confirmed'").
Where("eth_receipts.block_number <= (SELECT max(number) - ? FROM heads)", minRequiredOutgoingConfirmations).
First(&receipt).
Error
Expand Down Expand Up @@ -312,11 +317,11 @@ func ensureTxRunResult(input models.RunInput, str *strpkg.Store) models.RunOutpu
}

func addReceiptToResult(
receipt eth.TxReceipt,
receipt models.TxReceipt,
input models.RunInput,
data models.JSON,
) models.RunOutput {
receipts := []eth.TxReceipt{}
receipts := []models.TxReceipt{}

ethereumReceipts := input.Data().Get("ethereumReceipts").String()
if ethereumReceipts != "" {
Expand Down
4 changes: 2 additions & 2 deletions core/adapters/eth_tx_abi_encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"

"github.com/smartcontractkit/chainlink/core/adapters"
ethpkg "github.com/smartcontractkit/chainlink/core/eth"
"github.com/smartcontractkit/chainlink/core/internal/cltest"
"github.com/smartcontractkit/chainlink/core/store/models"
"github.com/smartcontractkit/chainlink/core/utils"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -136,7 +136,7 @@ func TestEthTxABIEncodeAdapter_Perform_ConfirmedWithJSON(t *testing.T) {
assert.Equal(t, expectedAsHex, hexutil.Encode(tx.Data()))
return nil
})
receipt := ethpkg.TxReceipt{Hash: hash, BlockNumber: cltest.Int(confirmed)}
receipt := models.TxReceipt{Hash: hash, BlockNumber: cltest.Int(confirmed)}
app.EthMock.Register("eth_getTransactionReceipt", receipt)
input := cltest.NewRunInputWithString(t, rawInput)
responseData := adapterUnderTest.Perform(input, store)
Expand Down
28 changes: 16 additions & 12 deletions core/adapters/eth_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"testing"

"github.com/smartcontractkit/chainlink/core/adapters"
"github.com/smartcontractkit/chainlink/core/eth"
"github.com/smartcontractkit/chainlink/core/internal/cltest"
"github.com/smartcontractkit/chainlink/core/internal/mocks"
strpkg "github.com/smartcontractkit/chainlink/core/store"
Expand Down Expand Up @@ -91,7 +90,7 @@ func TestEthTxAdapter_Perform(t *testing.T) {
tx := &models.Tx{Attempts: []*models.TxAttempt{&models.TxAttempt{}}}
txData := hexutil.MustDecode(test.output)
txManager.On("CreateTxWithGas", mock.Anything, mock.Anything, txData, gasPrice.ToInt(), gasLimit).Once().Return(tx, nil)
txManager.On("CheckAttempt", mock.Anything, mock.Anything).Once().Return(&eth.TxReceipt{}, test.receiptState, nil)
txManager.On("CheckAttempt", mock.Anything, mock.Anything).Once().Return(&models.TxReceipt{}, test.receiptState, nil)

store.TxManager = txManager

Expand Down Expand Up @@ -124,7 +123,7 @@ func TestEthTxAdapter_Perform_BytesFormatWithDataPrefix(t *testing.T) {
"000000000000000000000000000000000000000000000000000000000000000a"+ // length in bytes
"63c3b66e6669726d656400000000000000000000000000000000000000000000"), // encoded string left padded
mock.Anything, mock.Anything).Return(tx, nil)
txManager.On("CheckAttempt", mock.Anything, mock.Anything).Return(&eth.TxReceipt{}, strpkg.Unconfirmed, nil)
txManager.On("CheckAttempt", mock.Anything, mock.Anything).Return(&models.TxReceipt{}, strpkg.Unconfirmed, nil)
store.TxManager = txManager

adapter := adapters.EthTx{DataFormat: "bytes", DataPrefix: hexutil.MustDecode("0x88888888")}
Expand All @@ -145,7 +144,7 @@ func TestEthTxAdapter_Perform_FromPendingOutgoingConfirmations_StillPending(t *t

txManager := new(mocks.TxManager)
txManager.On("Connected").Return(true)
txManager.On("BumpGasUntilSafe", mock.Anything).Return(&eth.TxReceipt{}, strpkg.Confirmed, nil)
txManager.On("BumpGasUntilSafe", mock.Anything).Return(&models.TxReceipt{}, strpkg.Confirmed, nil)
store.TxManager = txManager

adapter := adapters.EthTx{}
Expand All @@ -170,7 +169,7 @@ func TestEthTxAdapter_Perform_FromPendingOutgoingConfirmations_Safe(t *testing.T
txManager := new(mocks.TxManager)
txManager.On("Connected").Return(true)
receiptHash := cltest.NewHash()
receipt := &eth.TxReceipt{Hash: receiptHash, BlockNumber: cltest.Int(129831)}
receipt := &models.TxReceipt{Hash: receiptHash, BlockNumber: cltest.Int(129831)}
txManager.On("BumpGasUntilSafe", mock.Anything).Return(receipt, strpkg.Safe, nil)
store.TxManager = txManager

Expand All @@ -185,7 +184,7 @@ func TestEthTxAdapter_Perform_FromPendingOutgoingConfirmations_Safe(t *testing.T
assert.Equal(t, receiptHash.String(), output.Result().String())

receiptsJSON := output.Get("ethereumReceipts").String()
var receipts []eth.TxReceipt
var receipts []models.TxReceipt
require.NoError(t, json.Unmarshal([]byte(receiptsJSON), &receipts))
require.Len(t, receipts, 1)
assert.Equal(t, receipt, &receipts[0])
Expand All @@ -205,7 +204,7 @@ func TestEthTxAdapter_Perform_AppendingTransactionReceipts(t *testing.T) {
txManager := new(mocks.TxManager)
txManager.On("Connected").Return(true)
receiptHash := cltest.NewHash()
receipt := &eth.TxReceipt{Hash: receiptHash, BlockNumber: cltest.Int(129831)}
receipt := &models.TxReceipt{Hash: receiptHash, BlockNumber: cltest.Int(129831)}
txManager.On("BumpGasUntilSafe", mock.Anything).Return(receipt, strpkg.Safe, nil)
store.TxManager = txManager

Expand All @@ -224,7 +223,7 @@ func TestEthTxAdapter_Perform_AppendingTransactionReceipts(t *testing.T) {
assert.Equal(t, receiptHash.String(), output.Result().String())

receiptsJSON := output.Get("ethereumReceipts").String()
var receipts []eth.TxReceipt
var receipts []models.TxReceipt
require.NoError(t, json.Unmarshal([]byte(receiptsJSON), &receipts))
require.Len(t, receipts, 2)

Expand Down Expand Up @@ -471,7 +470,7 @@ func TestEthTxAdapter_Perform_NoDoubleSpendOnSendTransactionFail(t *testing.T) {
}),
mock.Anything,
mock.Anything).Once().Return(tx, nil)
txManager.On("CheckAttempt", txAttempt, uint64(0)).Return(&eth.TxReceipt{}, strpkg.Confirmed, nil)
txManager.On("CheckAttempt", txAttempt, uint64(0)).Return(&models.TxReceipt{}, strpkg.Confirmed, nil)

result = adapter.Perform(input, store)
require.NoError(t, result.Error())
Expand All @@ -493,7 +492,7 @@ func TestEthTxAdapter_Perform_BPTXM(t *testing.T) {

toAddress := cltest.NewAddress()
gasLimit := uint64(42)
functionSelector := eth.HexToFunctionSelector("0x70a08231") // balanceOf(address)
functionSelector := models.HexToFunctionSelector("0x70a08231") // balanceOf(address)
dataPrefix := hexutil.MustDecode("0x88888888")

t.Run("with valid data and empty DataFormat writes to database and returns run output pending outgoing confirmations", func(t *testing.T) {
Expand Down Expand Up @@ -661,14 +660,19 @@ func TestEthTxAdapter_Perform_BPTXM(t *testing.T) {
Number: 13,
}))
store.GetRawDB().Exec(`INSERT INTO eth_task_run_txes (task_run_id, eth_tx_id) VALUES ($1, $2)`, taskRunID.UUID(), etx.ID)
input := models.NewRunInputWithResult(jobRunID, taskRunID, "0x9786856756", models.RunStatusUnstarted)
data := cltest.JSONFromString(t, `{"foo": "bar", "result": "some old bollocks"}`)
input := models.NewRunInput(jobRunID, taskRunID, data, models.RunStatusUnstarted)

// Do the thing
runOutput := adapter.Perform(*input, store)

require.NoError(t, runOutput.Error())
assert.Equal(t, models.RunStatusCompleted, runOutput.Status())
assert.Equal(t, confirmedAttemptHash.Hex(), runOutput.Result().String())
// Does not clobber previously assigned data
assert.Equal(t, "bar", runOutput.Get("foo").String())
// Assigns latestOutgoingTxHash for legacy compatibility
assert.Equal(t, confirmedAttemptHash.Hex(), runOutput.Get("latestOutgoingTxHash").String())
})

t.Run("with confirmed transaction with exactly one attempt with exactly one receipt that is older than minRequiredOutgoingConfirmations, returns output complete with transaction hash pulled from receipt", func(t *testing.T) {
Expand Down Expand Up @@ -718,7 +722,7 @@ func TestEthTxAdapter_Perform_BPTXM(t *testing.T) {
cltest.MustInsertEthReceipt(t, store, 1, cltest.NewHash(), confirmedAttemptHash)
require.NoError(t, store.IdempotentInsertHead(models.Head{
Hash: cltest.NewHash(),
Number: int64(store.Config.MinOutgoingConfirmations()) + 2,
Number: int64(store.Config.MinRequiredOutgoingConfirmations()) + 2,
}))
store.GetRawDB().Exec(`INSERT INTO eth_task_run_txes (task_run_id, eth_tx_id) VALUES ($1, $2)`, taskRunID.UUID(), etx.ID)
input := models.NewRunInputWithResult(jobRunID, taskRunID, "0x9786856756", models.RunStatusUnstarted)
Expand Down
Loading

0 comments on commit f3e9c1e

Please sign in to comment.