Skip to content

Commit

Permalink
Merge pull request #3161 from smartcontractkit/release/0.8.9-rc0
Browse files Browse the repository at this point in the history
Release/0.8.9 rc0
  • Loading branch information
tyrion70 authored Jul 13, 2020
2 parents f3e9c1e + 9e4a293 commit 24b4066
Show file tree
Hide file tree
Showing 207 changed files with 2,761 additions and 786 deletions.
6 changes: 5 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ jobs:
- '/go/pkg/mod'
- run: yarn setup:contracts
- run: go run ./core local db preparetest
- run: go test -v -p 4 -parallel 4 ./...
- run: go test -v -p 4 -parallel 4 ./... | tee ./output.txt | grep "\-\-\- FAIL" || echo "All passed!" # only show failures
- store_artifacts:
path: ./output.txt

rust:
docker:
- image: smartcontract/builder:1.0.33
Expand Down Expand Up @@ -221,6 +224,7 @@ jobs:
- store_artifacts:
path: ./integration/logs
feeds:
resource_class: large
docker:
- image: smartcontract/builder:1.0.33
steps:
Expand Down
18 changes: 17 additions & 1 deletion .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,20 @@ jobs:
- uses: actions/setup-go@v2
- uses: actions/checkout@v2
- run: go get -v golang.org/x/lint/golint
- run: set +e ; d="$($HOME/go/bin/golint -min_confidence 1 ./... | grep -v comment)" ; if [ -z "$d" ]; then exit 0 ; else echo "golint check output:" ; echo "$d" ; exit 1 ; fi ; set -e
- run: set +e ; d="$($HOME/go/bin/golint -min_confidence 1 ./... | grep -v comment)" ; if [ -z "$d" ]; then exit 0 ; else echo "golint check output:" ; echo "$d" ; exit 1 ; fi ; set -e
exportloopref:
name: exportloopref
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v2
- uses: actions/checkout@v2
- run: go get -v github.com/kyoh86/exportloopref/cmd/exportloopref
- run: $HOME/go/bin/exportloopref ./...
exhaustive:
name: exhaustive
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v2
- uses: actions/checkout@v2
- run: go get -v github.com/nishanths/exhaustive/...
- run: $HOME/go/bin/exhaustive -default-signifies-exhaustive ./...
13 changes: 13 additions & 0 deletions CHANGELOG-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.8.9] - 2020-07-13

### Added

- Added a check on sensitive file ownership that gives a warning if certain files are not owned by the user running chainlink
- Added mechanism to asynchronously communicate when a job spec has an ethereum interaction error (or any async error) with a UI screen
- Gas Bumper now bumps based on the current gas price instead of the gas price of the original transaction

### Fixed
- Support for multiple node addresses

## [0.8.8] - 2020-06-29

### Added
Expand All @@ -16,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- HeadTracker now automatically backfills missing heads up to `ETH_FINALITY_DEPTH`
- The strategy for gas bumping has been changed to produce a potentially higher gas cost in exchange for the transaction getting through faster.

### Breaking changes

Expand All @@ -41,6 +53,7 @@ This release contains a number of features aimed at improving the node's reliabi
- `ETH_GAS_BUMP_THRESHOLD` default value has been decreased from 12 to 3
- `ETH_FINALITY_DEPTH` specifies how deep protection should be against re-orgs. The default is 50. It only applies if BulletproofTxManager is enabled. It is not recommended to change this setting.
- `EthHeadTrackerHistoryDepth` specifies how many heads the head tracker should keep in the database. The default is 100. It is not recommended to change this setting.
- Update README.md with links to mockery, jq, and gencodec as they are required to run `go generate ./...`

## [0.8.6] - 2020-06-08

Expand Down
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
core @j16r @se3000 @RyanRHall @spooktheducks @samsondav
core @topliceanu @se3000 @RyanRHall @spooktheducks @samsondav
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,35 +116,37 @@ go build -o chainlink ./core/

1. [Install Yarn](https://yarnpkg.com/lang/en/docs/install)

2. Build contracts:
2. Install [gencodec](https://github.com/fjl/gencodec), [mockery version 1.0.0](https://github.com/vektra/mockery/releases/tag/v1.0.0), and [jq](https://stedolan.github.io/jq/download/) to be able to run `go generate ./...` and `make abigen`

3. Build contracts:

```bash
yarn
yarn setup:contracts
```

3. Generate and compile static assets:
4. Generate and compile static assets:

```bash
go generate ./...
go run ./packr/main.go ./core/eth/
```

4. Prepare your development environment:
5. Prepare your development environment:

```bash
export DATABASE_URL=postgresql://127.0.0.1:5432/chainlink_test?sslmode=disable
export CHAINLINK_DEV=true # I prefer to use direnv and skip this
```

5. Drop/Create test database and run migrations:
6. Drop/Create test database and run migrations:
```
go run ./core/main.go local db preparetest
```

If you do end up modifying the migrations for the database, you will need to rerun

6. Run tests:
7. Run tests:

```bash
go test -parallel=1 ./...
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.8.8
0.8.9
4 changes: 2 additions & 2 deletions belt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
"@oclif/config": "^1",
"@oclif/plugin-help": "^2",
"@oclif/plugin-not-found": "^1.2.3",
"chalk": "^4.0.0",
"chalk": "^4.1.0",
"cli-ux": "^5.4.4",
"debug": "^4.1.1",
"inquirer": "^7.0.5",
"inquirer": "^7.2.0",
"shelljs": "^0.8.3",
"ts-generator": "^0.0.8",
"tslib": "^1",
Expand Down
14 changes: 9 additions & 5 deletions core/adapters/eth_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,19 @@ func getTxData(e *EthTx, input models.RunInput) ([]byte, error) {
return common.HexToHash(result.Str).Bytes(), nil
}

payloadOffset := utils.EVMWordUint64(utils.EVMWordByteLen)
if len(e.DataPrefix) > 0 {
payloadOffset = utils.EVMWordUint64(utils.EVMWordByteLen * 2)
}
output, err := utils.EVMTranscodeJSONWithFormat(result, e.DataFormat)
if err != nil {
return []byte{}, err
}
return utils.ConcatBytes(payloadOffset, output), nil
if e.DataFormat == DataFormatBytes || len(e.DataPrefix) > 0 {
payloadOffset := utils.EVMWordUint64(utils.EVMWordByteLen)
if len(e.DataPrefix) > 0 {
payloadOffset = utils.EVMWordUint64(utils.EVMWordByteLen * 2)
return utils.ConcatBytes(payloadOffset, output), nil
}
return utils.ConcatBytes(payloadOffset, output), nil
}
return utils.ConcatBytes(output), nil
}

func createTxRunResult(
Expand Down
29 changes: 29 additions & 0 deletions core/adapters/eth_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,35 @@ func TestEthTxAdapter_Perform_BytesFormatWithDataPrefix(t *testing.T) {
txManager.AssertExpectations(t)
}

func TestEthTxAdapter_Perform_Preformatted(t *testing.T) {
t.Parallel()

store, cleanup := cltest.NewStore(t)
defer cleanup()

hexPayload := "b72f443a17edf4a55f766cf3c83469e6f96494b16823a41a4acb25800f30310300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001b76616c69646174696f6e2e747769747465722e757365726e616d650000000000000000000000000000000000000000000000000000000000000000000000001c76616c69646174696f6e2e747769747465722e7369676e617475726500000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a64657261696e6265726b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008430783965353831646633383765376138343433653636336435386663313736303034356433666362376165643234393633376163633737376262653837643561333934326431363130643265386538626437353066643533633230643466633661383536303737623235656439653538356439616161336439646535626365376238316200000000000000000000000000000000000000000000000000000000"
fs := "0xdeadcafe"

txManager := new(mocks.TxManager)
tx := &models.Tx{Attempts: []*models.TxAttempt{&models.TxAttempt{}}}
txManager.On("Connected").Maybe().Return(true)
txManager.On("CreateTxWithGas", mock.Anything, mock.Anything, hexutil.MustDecode(fs+hexPayload), mock.Anything, mock.Anything).Return(tx, nil)
txManager.On("CheckAttempt", mock.Anything, mock.Anything).Return(&models.TxReceipt{}, strpkg.Unconfirmed, nil)
store.TxManager = txManager

adapter := adapters.EthTx{
FunctionSelector: models.HexToFunctionSelector(fs),
DataFormat: "preformatted",
}
input := cltest.NewRunInputWithResult("0x" + hexPayload)
result := adapter.Perform(input, store)

assert.NoError(t, result.Error())
assert.Equal(t, models.RunStatusPendingOutgoingConfirmations, result.Status())

txManager.AssertExpectations(t)
}

func TestEthTxAdapter_Perform_FromPendingOutgoingConfirmations_StillPending(t *testing.T) {
t.Parallel()

Expand Down
13 changes: 11 additions & 2 deletions core/adapters/random.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,17 @@ func (ra *Random) Perform(input models.RunInput, store *store.Store) models.RunO
if err != nil {
return models.NewRunOutputError(err)
}
ethereumByteArray := fmt.Sprintf("0x%x", utils.EVMEncodeBytes(solidityProof[:]))
return models.NewRunOutputCompleteWithResult(ethereumByteArray)
vrfCoordinatorArgs, err := models.VRFFulfillMethod().Inputs.PackValues(
[]interface{}{
solidityProof[:], // geth expects slice, even if arg is constant-length
})
if err != nil {
return models.NewRunOutputError(errors.Wrapf(err,
"while packing VRF proof %s as argument to "+
"VRFCoordinator.fulfillRandomnessRequest", solidityProof))
}
return models.NewRunOutputCompleteWithResult(fmt.Sprintf("0x%x",
vrfCoordinatorArgs))
}

// getSeed returns the numeric seed for the vrf task, or an error
Expand Down
18 changes: 8 additions & 10 deletions core/adapters/random_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import (

"github.com/smartcontractkit/chainlink/core/adapters"
"github.com/smartcontractkit/chainlink/core/internal/cltest"
"github.com/smartcontractkit/chainlink/core/internal/gethwrappers/generated/solidity_verifier_wrapper"
"github.com/smartcontractkit/chainlink/core/internal/gethwrappers/generated/solidity_vrf_verifier_wrapper"
"github.com/smartcontractkit/chainlink/core/store/models"
"github.com/smartcontractkit/chainlink/core/utils"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
Expand All @@ -23,14 +22,14 @@ import (

// NB: For changes to the VRF solidity code to be reflected here, "go generate"
// must be run in core/services/vrf.
func vrfVerifier(t *testing.T) *solidity_verifier_wrapper.VRFTestHelper {
func vrfVerifier(t *testing.T) *solidity_vrf_verifier_wrapper.VRFTestHelper {
ethereumKey, err := crypto.GenerateKey()
require.NoError(t, err)
auth := bind.NewKeyedTransactor(ethereumKey)
genesisData := core.GenesisAlloc{auth.From: {Balance: big.NewInt(1000000000)}}
gasLimit := eth.DefaultConfig.Miner.GasCeil
backend := backends.NewSimulatedBackend(genesisData, gasLimit)
_, _, verifier, err := solidity_verifier_wrapper.DeployVRFTestHelper(auth, backend)
_, _, verifier, err := solidity_vrf_verifier_wrapper.DeployVRFTestHelper(auth, backend)
require.NoError(t, err)
backend.Commit()
return verifier
Expand All @@ -48,12 +47,11 @@ func TestRandom_Perform(t *testing.T) {
input := models.NewRunInput(&models.ID{}, models.ID{}, jsonInput, models.RunStatusUnstarted)
result := adapter.Perform(*input, store)
require.NoError(t, result.Error(), "while running random adapter")
proof := hexutil.MustDecode(result.Result().String())
// Check that proof is a solidity bytes array containing the actual proof
length := big.NewInt(0).SetBytes(proof[:utils.EVMWordByteLen]).Uint64()
require.Equal(t, length, uint64(len(proof)-utils.EVMWordByteLen))
actualProof := proof[utils.EVMWordByteLen:]
randomOutput, err := vrfVerifier(t).RandomValueFromVRFProof(nil, actualProof)
proofArg := hexutil.MustDecode(result.Result().String())
var proof []byte
err = models.VRFFulfillMethod().Inputs.Unpack(&proof, proofArg)
require.NoError(t, err, "failed to unpack VRF proof from random adapter")
randomOutput, err := vrfVerifier(t).RandomValueFromVRFProof(nil, proof)
require.NoError(t, err, "proof was invalid")
expected := common.HexToHash(
"c0a5642a409290ac65d9d44a4c52e53f31921ff1b7d235c585193a18190c82f1")
Expand Down
10 changes: 9 additions & 1 deletion core/cmd/local_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,19 @@ func checkFilePermissions(rootDir string) error {
if utils.TooPermissive(fileInfo.Mode().Perm(), ownerPermsMask) {
newPerms := fileInfo.Mode().Perm() & ownerPermsMask
logger.Warnf("%s has overly permissive file permissions, reducing them from %s to %s", path, fileInfo.Mode().Perm(), newPerms)
err := utils.EnsureFilepathMaxPerms(path, newPerms)
err = utils.EnsureFilepathMaxPerms(path, newPerms)
if err != nil {
return err
}
}
owned, err := utils.IsFileOwnedByChainlink(fileInfo)
if err != nil {
logger.Warn(err)
continue
}
if !owned {
logger.Warnf("The file %v is not owned by the user running chainlink. This will be made mandatory in the future.", path)
}
}
return nil
}
Expand Down
10 changes: 9 additions & 1 deletion core/cmd/local_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,18 @@ func TestClient_ImportKey(t *testing.T) {
set := flag.NewFlagSet("import", 0)
set.Parse([]string{"../internal/fixtures/keys/7fc66c61f88A61DFB670627cA715Fe808057123e.json"})
c := cli.NewContext(nil, set, nil)
assert.NoError(t, client.ImportKey(c))
require.NoError(t, client.ImportKey(c))

// importing again simply upserts
require.NoError(t, client.ImportKey(c))

keys, err := app.GetStore().Keys()
require.NoError(t, err)

require.Len(t, keys, 2)
require.Equal(t, int32(1), keys[0].ID)
require.Greater(t, keys[1].ID, int32(1))

addresses := []string{}
for _, k := range keys {
addresses = append(addresses, k.Address.String())
Expand Down
2 changes: 2 additions & 0 deletions core/cmd/local_client_vrf.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/smartcontractkit/chainlink/core/logger"
"github.com/smartcontractkit/chainlink/core/store"
"github.com/smartcontractkit/chainlink/core/store/models/vrfkey"
"github.com/smartcontractkit/chainlink/core/store/orm"
"github.com/smartcontractkit/chainlink/core/utils"
)

Expand All @@ -22,6 +23,7 @@ func vRFKeyStore(cli *Client) *store.VRFKeyStore {
// CreateVRFKey creates a key in the VRF keystore, protected by the password in
// the password file
func (cli *Client) CreateVRFKey(c *clipkg.Context) error {
cli.Config.Dialect = orm.DialectPostgresWithoutLock
password, err := getPassword(c)
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions core/internal/cltest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ func (c *SimulatedBackendClient) GethClient(f func(c eth.GethClient) error) erro
return nil
}

// RPCClient is a noop, solely needed to conform to GethClientWrapper interface
func (c *SimulatedBackendClient) RPCClient(f func(c eth.RPCClient) error) error {
return nil
}

// Close terminates the underlying blockchain's update loop.
func (c *SimulatedBackendClient) Close() {
c.b.Close()
Expand Down
8 changes: 8 additions & 0 deletions core/internal/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -1346,3 +1346,11 @@ func FindJobRun(t *testing.T, store *strpkg.Store, id *models.ID) models.JobRun
require.NoError(t, err)
return jr
}

func MustHexToUint64(t *testing.T, hex string) uint64 {
res, err := utils.HexToUint64(hex)
if err != nil {
t.Fatal(err)
}
return res
}
32 changes: 26 additions & 6 deletions core/internal/cltest/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,31 @@ func MockEthOnStore(t testing.TB, s *store.Store, flags ...string) *EthMock {

// SimpleGethWrapper offers an easy way to mock the eth client
type SimpleGethWrapper struct {
c eth.GethClient
}

func NewSimpleGethWrapper(c eth.GethClient) *SimpleGethWrapper {
wrapper := SimpleGethWrapper{c: c}
g eth.GethClient
r eth.RPCClient
}

func NewSimpleGethWrapper(clients ...interface{}) *SimpleGethWrapper {
wrapper := SimpleGethWrapper{}
for _, client := range clients {
switch c := client.(type) {
case eth.GethClient:
wrapper.g = c
case eth.RPCClient:
wrapper.r = c
default:
panic("unrecognised client type")
}
}
return &wrapper
}

func (wrapper *SimpleGethWrapper) GethClient(f func(c eth.GethClient) error) error {
return f(wrapper.c)
return f(wrapper.g)
}

func (wrapper *SimpleGethWrapper) RPCClient(f func(r eth.RPCClient) error) error {
return f(wrapper.r)
}

// EthMock is a mock ethereum client
Expand All @@ -100,6 +115,11 @@ func (mock *EthMock) GethClient(f func(c eth.GethClient) error) error {
return nil
}

// RPCClient is a noop, solely needed to conform to GethClientWrapper interface
func (mock *EthMock) RPCClient(f func(c eth.RPCClient) error) error {
return nil
}

// Dial mock dial
func (mock *EthMock) Dial(url string) (eth.CallerSubscriber, error) {
return mock, nil
Expand Down
Loading

0 comments on commit 24b4066

Please sign in to comment.