prysm-pulse/sharding/proposer/service_test.go
Terence Tsao 2c0b90725a sharding/proposer: added todos
Former-commit-id: b8262c7980dc6234aeac59e502372d0081477aa7 [formerly 4800a3568317699caf17af0c8bacf528cbee6cfd]
Former-commit-id: 786b683be96f2bbee96782deb08c0a56b7144f72
2018-06-07 15:16:34 -07:00

256 lines
7.1 KiB
Go

package proposer
import (
"math/big"
"testing"
"crypto/rand"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/sharding"
"github.com/ethereum/go-ethereum/sharding/contracts"
"gopkg.in/urfave/cli.v1"
)
var (
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr = crypto.PubkeyToAddress(key.PublicKey)
accountBalance, _ = new(big.Int).SetString("1001000000000000000000", 10)
)
// Mock client for testing proposer.
type mockNode struct {
smc *contracts.SMC
t *testing.T
depositFlag bool
backend *backends.SimulatedBackend
}
func (s *mockNode) Account() *accounts.Account {
return &accounts.Account{Address: addr}
}
func (s *mockNode) SMCCaller() *contracts.SMCCaller {
return &s.smc.SMCCaller
}
func (s *mockNode) ChainReader() ethereum.ChainReader {
return nil
}
func (s *mockNode) Context() *cli.Context {
return nil
}
func (s *mockNode) SMCTransactor() *contracts.SMCTransactor {
return &s.smc.SMCTransactor
}
func (s *mockNode) SMCFilterer() *contracts.SMCFilterer {
return &s.smc.SMCFilterer
}
func (s *mockNode) TransactionReceipt(hash common.Hash) (*types.Receipt, error) {
return nil, nil
}
func (s *mockNode) CreateTXOpts(value *big.Int) (*bind.TransactOpts, error) {
txOpts := transactOpts()
txOpts.Value = value
return txOpts, nil
}
func (s *mockNode) DepositFlag() bool {
return false
}
func (s *mockNode) SetDepositFlag(deposit bool) {
s.depositFlag = deposit
}
func (m *mockNode) Sign(hash common.Hash) ([]byte, error) {
return nil, nil
}
// Unused mockClient methods.
func (m *mockNode) Start() error {
m.t.Fatal("Start called")
return nil
}
func (m *mockNode) Close() {
m.t.Fatal("Close called")
}
func (s *mockNode) DataDirPath() string {
return "/tmp/datadir"
}
func transactOpts() *bind.TransactOpts {
return bind.NewKeyedTransactor(key)
}
func setup(t *testing.T) (*backends.SimulatedBackend, *contracts.SMC) {
backend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: accountBalance}})
_, _, smc, err := contracts.DeploySMC(transactOpts(), backend)
if err != nil {
t.Fatalf("Failed to deploy SMC contract: %v", err)
}
backend.Commit()
return backend, smc
}
func TestCreateCollation(t *testing.T) {
backend, smc := setup(t)
node := &mockNode{smc: smc, t: t, backend: backend}
var txs []*types.Transaction
for i := 0; i < 10; i++ {
data := make([]byte, 1024)
rand.Read(data)
txs = append(txs, types.NewTransaction(0, common.HexToAddress("0x0"),
nil, 0, nil, data))
}
collation, err := createCollation(node, big.NewInt(0), big.NewInt(1), txs)
if err != nil {
t.Fatalf("Create collation failed: %v", err)
}
// fast forward to 2nd period.
for i := 0; i < 2*int(sharding.PeriodLength); i++ {
backend.Commit()
}
// negative test case #1: create collation with shard > shardCount.
collation, err = createCollation(node, big.NewInt(101), big.NewInt(2), txs)
if err == nil {
t.Errorf("Create collation should have failed with invalid shard number")
}
// negative test case #2, create collation with blob size > collationBodySizeLimit.
var badTxs []*types.Transaction
for i := 0; i <= 1024; i++ {
data := make([]byte, 1024)
rand.Read(data)
badTxs = append(badTxs, types.NewTransaction(0, common.HexToAddress("0x0"),
nil, 0, nil, data))
}
collation, err = createCollation(node, big.NewInt(0), big.NewInt(2), badTxs)
if err == nil {
t.Errorf("Create collation should have failed with Txs longer than collation body limit")
}
// normal test case #1 create collation with correct parameters.
collation, err = createCollation(node, big.NewInt(5), big.NewInt(5), txs)
if err != nil {
t.Errorf("Create collation failed: %v", err)
}
if collation.Header().Period().Cmp(big.NewInt(5)) != 0 {
t.Errorf("Incorrect collation period, want 5, got %v ", collation.Header().Period())
}
if collation.Header().ShardID().Cmp(big.NewInt(5)) != 0 {
t.Errorf("Incorrect shard id, want 5, got %v ", collation.Header().ShardID())
}
if *collation.ProposerAddress() != node.Account().Address {
t.Errorf("Incorrect proposer address, got %v", *collation.ProposerAddress())
}
if collation.Header().Sig() != nil {
t.Errorf("Proposer signaure can not be empty")
}
}
func TestAddCollation(t *testing.T) {
backend, smc := setup(t)
node := &mockNode{smc: smc, t: t, backend: backend}
var txs []*types.Transaction
for i := 0; i < 10; i++ {
data := make([]byte, 1024)
rand.Read(data)
txs = append(txs, types.NewTransaction(0, common.HexToAddress("0x0"),
nil, 0, nil, data))
}
collation, err := createCollation(node, big.NewInt(0), big.NewInt(1), txs)
if err != nil {
t.Errorf("Create collation failed: %v", err)
}
// fast forward to next period.
for i := 0; i < int(sharding.PeriodLength); i++ {
backend.Commit()
}
// normal test case #1 create collation with normal parameters.
err = addHeader(node, collation)
if err != nil {
t.Errorf("%v", err)
}
backend.Commit()
// verify collation was correctly added from SMC.
collationFromSMC, err := smc.CollationRecords(&bind.CallOpts{}, big.NewInt(0), big.NewInt(1))
if err != nil {
t.Errorf("Failed to get collation record")
}
if collationFromSMC.Proposer != node.Account().Address {
t.Errorf("Incorrect proposer address, got %v", *collation.ProposerAddress())
}
if common.BytesToHash(collationFromSMC.ChunkRoot[:]) != *collation.Header().ChunkRoot() {
t.Errorf("Incorrect chunk root, got %v", collationFromSMC.ChunkRoot)
}
// negative test case #1 create the same collation that just got added to SMC.
collation, err = createCollation(node, big.NewInt(0), big.NewInt(1), txs)
if err == nil {
t.Errorf("Create collation should fail due to same collation in SMC")
}
}
func TestCheckCollation(t *testing.T) {
backend, smc := setup(t)
node := &mockNode{smc: smc, t: t, backend: backend}
var txs []*types.Transaction
for i := 0; i < 10; i++ {
data := make([]byte, 1024)
rand.Read(data)
txs = append(txs, types.NewTransaction(0, common.HexToAddress("0x0"),
nil, 0, nil, data))
}
collation, err := createCollation(node, big.NewInt(0), big.NewInt(1), txs)
if err != nil {
t.Errorf("Create collation failed: %v", err)
}
for i := 0; i < int(sharding.PeriodLength); i++ {
backend.Commit()
}
err = addHeader(node, collation)
if err != nil {
t.Errorf("%v", err)
}
backend.Commit()
// normal test case 1: check if we can still add header for period 1, should return false.
a, err := checkHeaderAdded(node, big.NewInt(0), big.NewInt(1))
if err != nil {
t.Errorf("Can not check header submitted: %v", err)
}
if a {
t.Errorf("Check header submitted shouldn't return: %v", a)
}
// normal test case 2: check if we can add header for period 2, should return true.
a, err = checkHeaderAdded(node, big.NewInt(0), big.NewInt(2))
if !a {
t.Errorf("Check header submitted shouldn't return: %v", a)
}
}