mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2024-12-31 23:41:22 +00:00
50c69a6571
sharding: simplified all interfaces, into smaller, more useful ones Former-commit-id: c49a98c4c57bcce710d91034804fe270b2567645 [formerly fe0fb3f69dff87c40a98da4a5e7f52d0ac1106aa] Former-commit-id: 73f6b5c33b5c3197bf76096cf18cc490acb16462
225 lines
6.8 KiB
Go
225 lines
6.8 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/contracts"
|
|
"github.com/ethereum/go-ethereum/sharding/params"
|
|
)
|
|
|
|
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 (m *mockNode) Account() *accounts.Account {
|
|
return &accounts.Account{Address: addr}
|
|
}
|
|
|
|
func (m *mockNode) SMCCaller() *contracts.SMCCaller {
|
|
return &m.smc.SMCCaller
|
|
}
|
|
|
|
func (m *mockNode) ChainReader() ethereum.ChainReader {
|
|
return nil
|
|
}
|
|
|
|
func (m *mockNode) SMCTransactor() *contracts.SMCTransactor {
|
|
return &m.smc.SMCTransactor
|
|
}
|
|
|
|
func (m *mockNode) CreateTXOpts(value *big.Int) (*bind.TransactOpts, error) {
|
|
txOpts := transactOpts()
|
|
txOpts.Value = value
|
|
return txOpts, nil
|
|
}
|
|
|
|
func (m *mockNode) Sign(hash common.Hash) ([]byte, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (m *mockNode) GetShardCount() (int64, error) {
|
|
return 100, nil
|
|
}
|
|
|
|
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, node.Account(), 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(params.DefaultConfig.PeriodLength); i++ {
|
|
backend.Commit()
|
|
}
|
|
|
|
// negative test case #1: create collation with shard > shardCount.
|
|
collation, err = createCollation(node, node.Account(), 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, node.Account(), 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, node.Account(), 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, node.Account(), 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(params.DefaultConfig.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, node.Account(), 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, node.Account(), node, big.NewInt(0), big.NewInt(1), txs)
|
|
if err != nil {
|
|
t.Errorf("Create collation failed: %v", err)
|
|
}
|
|
|
|
for i := 0; i < int(params.DefaultConfig.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)
|
|
}
|
|
}
|