Skip to content

Commit

Permalink
Merge branch 'master' into refactor-allow-unfinalized
Browse files Browse the repository at this point in the history
  • Loading branch information
darioush authored Jan 4, 2024
2 parents 49b05b6 + 7832d53 commit b184ca5
Show file tree
Hide file tree
Showing 68 changed files with 837 additions and 1,225 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
token: ${{ secrets.AVALANCHE_PAT }}
- uses: actions/setup-go@v3
with:
go-version: '~1.20.10'
go-version: '~1.20.12'
check-latest: true
- name: change avalanchego dep
if: ${{ github.event_name == 'workflow_dispatch' }}
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
token: ${{ secrets.AVALANCHE_PAT }}
- uses: actions/setup-go@v3
with:
go-version: '~1.20.10'
go-version: '~1.20.12'
check-latest: true
- name: change avalanchego dep
if: ${{ github.event_name == 'workflow_dispatch' }}
Expand Down Expand Up @@ -98,7 +98,7 @@ jobs:
token: ${{ secrets.AVALANCHE_PAT }}
- uses: actions/setup-go@v3
with:
go-version: '~1.20.10'
go-version: '~1.20.12'
check-latest: true
- name: change avalanchego dep
if: ${{ github.event_name == 'workflow_dispatch' }}
Expand Down Expand Up @@ -129,7 +129,7 @@ jobs:
token: ${{ secrets.AVALANCHE_PAT }}
- uses: actions/setup-go@v3
with:
go-version: '~1.20.10'
go-version: '~1.20.12'
check-latest: true
- name: Run e2e tests
run: E2E_SERIAL=1 ./scripts/tests.e2e.sh
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# ============= Compilation Stage ================
FROM golang:1.20.10-bullseye AS builder
FROM golang:1.20.12-bullseye AS builder

ARG AVALANCHE_VERSION

Expand Down
4 changes: 1 addition & 3 deletions accounts/abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,7 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
return Type{}, errors.New("abi: purely anonymous or underscored field is not supported")
}
fieldName := ResolveNameConflict(name, func(s string) bool { return used[s] })
if err != nil {
return Type{}, err
}

used[fieldName] = true
if !isValidFieldName(fieldName) {
return Type{}, fmt.Errorf("field %d has invalid name", idx)
Expand Down
11 changes: 5 additions & 6 deletions consensus/dummy/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,13 @@ func (self *DummyEngine) verifyHeaderGasFields(config *params.ChainConfig, heade

// modified from consensus.go
func (self *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header *types.Header, parent *types.Header, uncle bool) error {
var (
config = chain.Config()
)
config := chain.Config()
// Ensure that we do not verify an uncle
if uncle {
return errUnclesUnsupported
}
switch {
case config.IsDUpgrade(header.Time):
case config.IsDurango(header.Time):
if len(header.Extra) < params.DynamicFeeExtraDataSize {
return fmt.Errorf("expected extra-data field length >= %d, found %d", params.DynamicFeeExtraDataSize, len(header.Extra))
}
Expand All @@ -217,7 +215,7 @@ func (self *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header
if header.Time > uint64(time.Now().Add(allowedFutureBlockTime).Unix()) {
return consensus.ErrFutureBlock
}
//if header.Time <= parent.Time {
// if header.Time <= parent.Time {
if header.Time < parent.Time {
return errInvalidBlockTime
}
Expand Down Expand Up @@ -395,7 +393,8 @@ func (self *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *type
}

func (self *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, parent *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
uncles []*types.Header, receipts []*types.Receipt,
) (*types.Block, error) {
var (
contribution, extDataGasUsed *big.Int
extraData []byte
Expand Down
12 changes: 4 additions & 8 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,10 @@ type BlockChain struct {

stopping atomic.Bool // false if chain is running, true when stopped

engine consensus.Engine
validator Validator // Block and state validator interface
prefetcher Prefetcher // Block state prefetcher interface
processor Processor // Block transaction processor interface
vmConfig vm.Config
engine consensus.Engine
validator Validator // Block and state validator interface
processor Processor // Block transaction processor interface
vmConfig vm.Config

lastAccepted *types.Block // Prevents reorgs past this height

Expand Down Expand Up @@ -335,7 +334,6 @@ func NewBlockChain(
}
bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
bc.validator = NewBlockValidator(chainConfig, bc, engine)
bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
bc.processor = NewStateProcessor(chainConfig, bc, engine)

bc.hc, err = NewHeaderChain(db, chainConfig, cacheConfig, engine)
Expand Down Expand Up @@ -1321,8 +1319,6 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error {
statedb.StartPrefetcher("chain", bc.cacheConfig.TriePrefetcherParallelism)
activeState = statedb

// If we have a followup block, run that against the current state to pre-cache
// transactions and probabilistically some of the account/storage trie nodes.
// Process block using the parent state as reference point
pstart := time.Now()
receipts, logs, usedGas, err := bc.processor.Process(block, parent, statedb, bc.vmConfig)
Expand Down
4 changes: 2 additions & 2 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
if !ok {
return newEVMBlockContext(header, chain, author, nil)
}
// Prior to the DUpgrade, the VM enforces the extra data is smaller than or
// equal to this size. After the DUpgrade, the VM pre-verifies the extra
// Prior to the Durango, the VM enforces the extra data is smaller than or
// equal to this size. After the Durango, the VM pre-verifies the extra
// data past the dynamic fee rollup window is valid.
predicateResults, err := predicate.ParseResults(predicateBytes)
if err != nil {
Expand Down
12 changes: 9 additions & 3 deletions core/predicate_check.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"

"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/precompile/precompileconfig"
Expand All @@ -31,7 +32,7 @@ func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.Pred

predicateResults := make(map[common.Address][]byte)
// Short circuit early if there are no precompile predicates to verify
if len(rules.Predicaters) == 0 {
if !rules.PredicatersExist() {
return predicateResults, nil
}

Expand All @@ -52,10 +53,15 @@ func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.Pred
// Since [address] is only added to [predicateArguments] when there's a valid predicate in the ruleset
// there's no need to check if the predicate exists here.
predicaterContract := rules.Predicaters[address]
res := predicaterContract.VerifyPredicate(predicateContext, predicates)
bitset := set.NewBits()
for i, predicate := range predicates {
if err := predicaterContract.VerifyPredicate(predicateContext, predicate); err != nil {
bitset.Add(i)
}
}
res := bitset.Bytes()
log.Debug("predicate verify", "tx", tx.Hash(), "address", address, "res", res)
predicateResults[address] = res
}

return predicateResults, nil
}
157 changes: 147 additions & 10 deletions core/predicate_check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/coreth/precompile/precompileconfig"
Expand All @@ -31,8 +32,6 @@ func TestCheckPredicate(t *testing.T) {
addr2 := common.HexToAddress("0xbb")
addr3 := common.HexToAddress("0xcc")
addr4 := common.HexToAddress("0xdd")
predicateResultBytes1 := []byte{1, 2, 3}
predicateResultBytes2 := []byte{3, 2, 1}
predicateContext := &precompileconfig.PredicateContext{
ProposerVMBlockCtx: &block.Context{
PChainHeight: 10,
Expand Down Expand Up @@ -142,7 +141,7 @@ func TestCheckPredicate(t *testing.T) {
predicater := precompileconfig.NewMockPredicater(gomock.NewController(t))
arg := common.Hash{1}
predicater.EXPECT().PredicateGas(arg[:]).Return(uint64(0), nil).Times(2)
predicater.EXPECT().VerifyPredicate(gomock.Any(), [][]byte{arg[:]}).Return(predicateResultBytes1)
predicater.EXPECT().VerifyPredicate(gomock.Any(), arg[:]).Return(nil)
return map[common.Address]precompileconfig.Predicater{
addr1: predicater,
}
Expand All @@ -156,7 +155,7 @@ func TestCheckPredicate(t *testing.T) {
},
}),
expectedRes: map[common.Address][]byte{
addr1: predicateResultBytes1,
addr1: {}, // valid bytes
},
expectedErr: nil,
},
Expand Down Expand Up @@ -188,7 +187,7 @@ func TestCheckPredicate(t *testing.T) {
predicater := precompileconfig.NewMockPredicater(gomock.NewController(t))
arg := common.Hash{1}
predicater.EXPECT().PredicateGas(arg[:]).Return(uint64(0), nil).Times(2)
predicater.EXPECT().VerifyPredicate(gomock.Any(), [][]byte{arg[:]}).Return(predicateResultBytes1)
predicater.EXPECT().VerifyPredicate(gomock.Any(), arg[:]).Return(nil)
return map[common.Address]precompileconfig.Predicater{
addr1: predicater,
addr2: predicater,
Expand All @@ -203,7 +202,7 @@ func TestCheckPredicate(t *testing.T) {
},
}),
expectedRes: map[common.Address][]byte{
addr1: predicateResultBytes1,
addr1: {}, // valid bytes
},
expectedErr: nil,
},
Expand All @@ -215,11 +214,11 @@ func TestCheckPredicate(t *testing.T) {
predicate1 := precompileconfig.NewMockPredicater(ctrl)
arg1 := common.Hash{1}
predicate1.EXPECT().PredicateGas(arg1[:]).Return(uint64(0), nil).Times(2)
predicate1.EXPECT().VerifyPredicate(gomock.Any(), [][]byte{arg1[:]}).Return(predicateResultBytes1)
predicate1.EXPECT().VerifyPredicate(gomock.Any(), arg1[:]).Return(nil)
predicate2 := precompileconfig.NewMockPredicater(ctrl)
arg2 := common.Hash{2}
predicate2.EXPECT().PredicateGas(arg2[:]).Return(uint64(0), nil).Times(2)
predicate2.EXPECT().VerifyPredicate(gomock.Any(), [][]byte{arg2[:]}).Return(predicateResultBytes2)
predicate2.EXPECT().VerifyPredicate(gomock.Any(), arg2[:]).Return(testErr)
return map[common.Address]precompileconfig.Predicater{
addr1: predicate1,
addr2: predicate2,
Expand All @@ -240,8 +239,8 @@ func TestCheckPredicate(t *testing.T) {
},
}),
expectedRes: map[common.Address][]byte{
addr1: predicateResultBytes1,
addr2: predicateResultBytes2,
addr1: {}, // valid bytes
addr2: {1}, // invalid bytes
},
expectedErr: nil,
},
Expand Down Expand Up @@ -322,3 +321,141 @@ func TestCheckPredicate(t *testing.T) {
})
}
}

func TestCheckPredicatesOutput(t *testing.T) {
testErr := errors.New("test error")
addr1 := common.HexToAddress("0xaa")
addr2 := common.HexToAddress("0xbb")
validHash := common.Hash{1}
invalidHash := common.Hash{2}
predicateContext := &precompileconfig.PredicateContext{
ProposerVMBlockCtx: &block.Context{
PChainHeight: 10,
},
}
type testTuple struct {
address common.Address
isValidPredicate bool
}
type resultTest struct {
name string
expectedRes map[common.Address][]byte
testTuple []testTuple
}
tests := []resultTest{
{name: "no predicates", expectedRes: map[common.Address][]byte{}},
{
name: "one address one predicate",
testTuple: []testTuple{
{address: addr1, isValidPredicate: true},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits().Bytes()},
},
{
name: "one address one invalid predicate",
testTuple: []testTuple{
{address: addr1, isValidPredicate: false},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(0).Bytes()},
},
{
name: "one address two invalid predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(0, 1).Bytes()},
},
{
name: "one address two mixed predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: true},
{address: addr1, isValidPredicate: false},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(1).Bytes()},
},
{
name: "one address mixed predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: true},
{address: addr1, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
{address: addr1, isValidPredicate: true},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(1, 2).Bytes()},
},
{
name: "two addresses mixed predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: true},
{address: addr2, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
{address: addr2, isValidPredicate: true},
{address: addr2, isValidPredicate: true},
{address: addr2, isValidPredicate: false},
{address: addr2, isValidPredicate: true},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(1, 2).Bytes(), addr2: set.NewBits(0, 3).Bytes()},
},
{
name: "two addresses all valid predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: true},
{address: addr2, isValidPredicate: true},
{address: addr1, isValidPredicate: true},
{address: addr1, isValidPredicate: true},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits().Bytes(), addr2: set.NewBits().Bytes()},
},
{
name: "two addresses all invalid predicates",
testTuple: []testTuple{
{address: addr1, isValidPredicate: false},
{address: addr2, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
{address: addr1, isValidPredicate: false},
},
expectedRes: map[common.Address][]byte{addr1: set.NewBits(0, 1, 2).Bytes(), addr2: set.NewBits(0).Bytes()},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
// Create the rules from TestChainConfig and update the predicates based on the test params
rules := params.TestChainConfig.AvalancheRules(common.Big0, 0)
predicater := precompileconfig.NewMockPredicater(gomock.NewController(t))
predicater.EXPECT().PredicateGas(gomock.Any()).Return(uint64(0), nil).Times(len(test.testTuple))

var txAccessList types.AccessList
for _, tuple := range test.testTuple {
var predicateHash common.Hash
if tuple.isValidPredicate {
predicateHash = validHash
predicater.EXPECT().VerifyPredicate(gomock.Any(), validHash[:]).Return(nil)
} else {
predicateHash = invalidHash
predicater.EXPECT().VerifyPredicate(gomock.Any(), invalidHash[:]).Return(testErr)
}
txAccessList = append(txAccessList, types.AccessTuple{
Address: tuple.address,
StorageKeys: []common.Hash{
predicateHash,
},
})
}

rules.Predicaters[addr1] = predicater
rules.Predicaters[addr2] = predicater

// Specify only the access list, since this test should not depend on any other values
tx := types.NewTx(&types.DynamicFeeTx{
AccessList: txAccessList,
Gas: 53000,
})
predicateRes, err := CheckPredicates(rules, predicateContext, tx)
require.NoError(err)
require.Equal(test.expectedRes, predicateRes)
})
}
}
Loading

0 comments on commit b184ca5

Please sign in to comment.