Test for IsValidatorAction

This commit is contained in:
atvanguard 2020-03-05 11:35:43 +05:30
parent 1d5b263362
commit f7e58d6030
4 changed files with 107 additions and 66 deletions

View file

@ -163,6 +163,11 @@ Ethereum nodes with exposed APIs! Further, all browser tabs can access locally
running web servers, so malicious web pages could try to subvert locally available
APIs!**
### Tests
```
go test github.com/maticnetwork/bor/consensus/bor_test
```
## License
The bor library (i.e. all code outside of the `cmd` directory) is licensed under the

View file

@ -40,8 +40,10 @@ import (
"golang.org/x/crypto/sha3"
)
const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
const stateReceiverABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"states","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPendingStates","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"validatorSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isValidatorSetContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"stateId","type":"uint256"}],"name":"proposeState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]`
const (
validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]`
stateReceiverABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"states","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPendingStates","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"validatorSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isValidatorSetContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"stateId","type":"uint256"}],"name":"proposeState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]`
)
const (
checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
@ -1225,16 +1227,30 @@ func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address
log.Error("Failed fetching snapshot", err)
}
_IsValidatorAction := false
isValidator := false
for _, validator := range snap.ValidatorSet.Validators {
if bytes.Compare(validator.Address.Bytes(), from.Bytes()) == 0 {
_IsValidatorAction = true
isValidator = true
break
}
}
// @todo only either of proposeState and proposeSpan should pass this check
fmt.Println("tx.Data", tx.Data())
return _IsValidatorAction
return isValidator && (isProposeSpanAction(tx, chain.Config().Bor.ValidatorContract) ||
isProposeStateAction(tx, chain.Config().Bor.StateReceiverContract))
}
func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool {
// keccak256('proposeSpan()').slice(0, 4)
proposeSpanSig, _ := hex.DecodeString("4b0e4d17")
return bytes.Compare(proposeSpanSig, tx.Data()[:4]) == 0 &&
tx.To().String() == validatorContract
}
func isProposeStateAction(tx *types.Transaction, stateReceiverContract string) bool {
// keccak256('proposeState(uint256)').slice(0, 4)
proposeStateSig, _ := hex.DecodeString("ede01f17")
fmt.Println(bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0, tx.To().String(), stateReceiverContract)
return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 &&
tx.To().String() == stateReceiverContract
}
//

View file

@ -1,22 +1,24 @@
package bor_test
import (
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"testing"
"github.com/stretchr/testify/assert"
"github.com/maticnetwork/bor/common"
"github.com/maticnetwork/bor/consensus/bor"
"github.com/maticnetwork/bor/core"
"github.com/maticnetwork/bor/core/rawdb"
"github.com/maticnetwork/bor/core/types"
"github.com/maticnetwork/bor/core/vm"
"github.com/maticnetwork/bor/crypto"
"github.com/maticnetwork/bor/eth"
"github.com/maticnetwork/bor/internal/ethapi"
// "github.com/maticnetwork/bor/node"
// "github.com/maticnetwork/bor/params"
"github.com/maticnetwork/bor/ethdb"
"github.com/maticnetwork/bor/node"
)
func TestIsValidatorAction(t *testing.T) {
@ -24,59 +26,77 @@ func TestIsValidatorAction(t *testing.T) {
db = rawdb.NewMemoryDatabase()
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key.PublicKey)
// signer = new(types.HomesteadSigner)
)
data, err := ioutil.ReadFile("genesis.json")
if err != nil {
t.Fatalf("%s", err)
}
config := eth.Config
Genesis: &core.Genesis{},
}
// var genesis core.Genesis
if err := json.Unmarshal(data, config.Genesis); err != nil {
t.Fatalf("%s", err)
}
// fmt.Println(genesis)
chainConfig, _, err := core.SetupGenesisBlock(db, config.Genesis)
fmt.Printf("Chain config: %v\n", chainConfig)
// copy(genspec.ExtraData[extraVanity:], addr[:])
config.Genesis.MustCommit(db)
_eth := &eth.Ethereum{
// config: config,
// chainDb: chainDb,
// eventMux: ctx.EventMux,
// accountManager: ctx.AccountManager,
// engine: nil,
// shutdownChan: make(chan bool),
// networkID: config.NetworkId,
// gasPrice: config.Miner.GasPrice,
// etherbase: config.Miner.Etherbase,
// bloomRequests: make(chan chan *bloombits.Retrieval),
// bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
}
_eth.APIBackend = &eth.EthAPIBackend{false, _eth, nil}
ethAPI := ethapi.NewPublicBlockChainAPI(_eth.APIBackend)
// ctx := &node.ServiceContext{
// config: &node.Config{},
// // services: make(map[reflect.Type]Service),
// // EventMux: n.eventmux,
// // AccountManager: n.accman,
// }
engine := bor.New(chainConfig, db, &ethapi.PublicBlockChainAPI{})
chain, err := core.NewBlockChain(db, nil, chainConfig, engine, vm.Config{}, nil)
if err != nil {
t.Fatalf("%s", err)
}
ethereum := buildEthereumInstance(t, db)
chain := ethereum.BlockChain()
engine := ethereum.Engine()
bor := engine.(*bor.Bor)
// proposeState
data, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000")
tx := types.NewTransaction(
0,
addr, // to - Just a place holder
big.NewInt(0), 0 /* fix gas limit */, big.NewInt(0),
nil, // data
common.HexToAddress(chain.Config().Bor.StateReceiverContract),
big.NewInt(0), 0, big.NewInt(0),
data,
)
engine.IsValidatorAction(chain, addr, tx)
assert.True(t, bor.IsValidatorAction(chain, addr, tx))
// proposeSpan
data, _ = hex.DecodeString("4b0e4d17")
tx = types.NewTransaction(
0,
common.HexToAddress(chain.Config().Bor.ValidatorContract),
big.NewInt(0), 0, big.NewInt(0),
data,
)
assert.True(t, bor.IsValidatorAction(chain, addr, tx))
}
func buildEthereumInstance(t *testing.T, db ethdb.Database) *eth.Ethereum {
genesisData, err := ioutil.ReadFile("genesis.json")
if err != nil {
t.Fatalf("%s", err)
}
gen := &core.Genesis{}
if err := json.Unmarshal(genesisData, gen); err != nil {
t.Fatalf("%s", err)
}
// chainConfig, _, err := core.SetupGenesisBlock(db, gen)
ethConf := &eth.Config{
Genesis: gen,
}
ethConf.Genesis.MustCommit(db)
// Create a temporary storage for the node keys and initialize it
workspace, err := ioutil.TempDir("", "console-tester-")
if err != nil {
t.Fatalf("failed to create temporary keystore: %v", err)
}
// Create a networkless protocol stack and start an Ethereum service within
stack, err := node.New(&node.Config{DataDir: workspace, UseLightweightKDF: true, Name: "console-tester"})
if err != nil {
t.Fatalf("failed to create node: %v", err)
}
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
s, err := eth.New(ctx, ethConf)
return s, err
})
if err != nil {
t.Fatalf("failed to register Ethereum protocol: %v", err)
}
// Start the node and assemble the JavaScript console around it
if err = stack.Start(); err != nil {
t.Fatalf("failed to start test stack: %v", err)
}
_, err = stack.Attach()
if err != nil {
t.Fatalf("failed to attach to node: %v", err)
}
var ethereum *eth.Ethereum
stack.Service(&ethereum)
return ethereum
}

File diff suppressed because one or more lines are too long