diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 5973a8cebcd833bce50bfeb5b7c33e655d8c391c..6b3d8479b77e2f5d0b626a82668edbf455c09e08 100644
--- a/cmd/puppeth/wizard_genesis.go
+++ b/cmd/puppeth/wizard_genesis.go
@@ -112,6 +112,7 @@ func (w *wizard) makeGenesis() {
 			ProducerDelay:     5,
 			Sprint:            60,
 			ValidatorContract: "0x0000000000000000000000000000000000001000",
+			Heimdall:          "http://localhost:1317",
 		}
 
 		// We also need the initial list of signers
diff --git a/consensus/bor/api.go b/consensus/bor/api.go
index da6ef1bdc0a722cd3e6c852569d5ec04a2ef0340..3e9cf87fa2385a4d2e2f90ebdc7fe555f3a1d1b5 100644
--- a/consensus/bor/api.go
+++ b/consensus/bor/api.go
@@ -87,33 +87,3 @@ func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
 	}
 	return snap.signers(), nil
 }
-
-// Proposals returns the current proposals the node tries to uphold and vote on.
-func (api *API) Proposals() map[common.Address]bool {
-	api.bor.lock.RLock()
-	defer api.bor.lock.RUnlock()
-
-	proposals := make(map[common.Address]bool)
-	for address, auth := range api.bor.proposals {
-		proposals[address] = auth
-	}
-	return proposals
-}
-
-// Propose injects a new authorization proposal that the signer will attempt to
-// push through.
-func (api *API) Propose(address common.Address, auth bool) {
-	api.bor.lock.Lock()
-	defer api.bor.lock.Unlock()
-
-	api.bor.proposals[address] = auth
-}
-
-// Discard drops a currently running proposal, stopping the signer from casting
-// further votes (either for or against).
-func (api *API) Discard(address common.Address) {
-	api.bor.lock.Lock()
-	defer api.bor.lock.Unlock()
-
-	delete(api.bor.proposals, address)
-}
diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index 6daaebf8e84a2d1dd84754758df144e7053811db..a5469f7ffd04c06412738c1de825a9f86a30b5f2 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -3,12 +3,15 @@ package bor
 import (
 	"bytes"
 	"context"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"io"
 	"math"
 	"math/big"
+	"net/http"
 	"sort"
+	"strconv"
 	"strings"
 	"sync"
 	"time"
@@ -36,7 +39,7 @@ 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":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"proposer","type":"address"},{"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":"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":"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 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":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":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 (
 	checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database
@@ -238,14 +241,14 @@ type Bor struct {
 	recents    *lru.ARCCache // Snapshots for recent block to speed up reorgs
 	signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
 
-	proposals map[common.Address]bool // Current list of proposals we are pushing
-
 	signer common.Address // Ethereum address of the signing key
 	signFn SignerFn       // Signer function to authorize hashes with
 	lock   sync.RWMutex   // Protects the signer fields
 
 	ethAPI          *ethapi.PublicBlockChainAPI
 	validatorSetABI abi.ABI
+	span            *Span
+	httpClient      http.Client
 
 	// The fields below are for testing only
 	fakeDiff bool // Skip difficulty verifications
@@ -276,8 +279,11 @@ func New(
 		ethAPI:          ethAPI,
 		recents:         recents,
 		signatures:      signatures,
-		proposals:       make(map[common.Address]bool),
+		span:            nil,
 		validatorSetABI: vABI,
+		httpClient: http.Client{
+			Timeout: time.Duration(5 * time.Second),
+		},
 	}
 
 	return c
@@ -463,11 +469,8 @@ func (c *Bor) snapshot(chain consensus.ChainReader, number uint64, hash common.H
 				// get checkpoint data
 				hash := checkpoint.Hash()
 
-				// current validators
-				validators, err := c.GetCurrentValidators(number, number+1)
-				if err != nil {
-					return nil, err
-				}
+				// get validators and current span
+				validators, _ := c.GetCurrentValidators(number, number+1)
 
 				// new snap shot
 				snap = newSnapshot(c.config, c.signatures, number, hash, validators, c.ethAPI)
@@ -659,8 +662,12 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error {
 // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
 // rewards given.
 func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) {
-	// commit span
-	// c.commitSpan(state, header, chainContext{Chain: chain, Bor: c})
+	// // commit span
+	// err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c})
+	// if err != nil {
+	// 	fmt.Println("Error while committing span", err)
+	// 	// return nil, err
+	// }
 
 	// No block rewards in PoA, so the state remains as is and uncles are dropped
 	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
@@ -671,7 +678,11 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state
 // nor block rewards given, and returns the final block.
 func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
 	// commit span
-	// c.commitSpan(state, header, chainContext{Chain: chain, Bor: c})
+	err := c.checkAndCommitSpan(state, header, chainContext{Chain: chain, Bor: c})
+	if err != nil {
+		fmt.Println("Error while committing span", err)
+		// return nil, err
+	}
 
 	// No block rewards in PoA, so the state remains as is and uncles are dropped
 	header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
@@ -809,6 +820,92 @@ func (c *Bor) Close() error {
 	return nil
 }
 
+// Checks if new span is pending
+func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) {
+	blockNr := rpc.BlockNumber(snapshotNumber)
+	method := "spanProposalPending"
+
+	// get packed data
+	data, err := c.validatorSetABI.Pack(method)
+	if err != nil {
+		fmt.Println("Unable to pack tx for spanProposalPending", "error", err)
+		return false, err
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel() // cancel when we are finished consuming integers
+
+	// call
+	msgData := (hexutil.Bytes)(data)
+	toAddress := common.HexToAddress(c.config.ValidatorContract)
+	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
+	result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
+		Gas:  &gas,
+		To:   &toAddress,
+		Data: &msgData,
+	}, blockNr)
+	if err != nil {
+		return false, err
+	}
+
+	var ret0 = new(bool)
+	if err := c.validatorSetABI.Unpack(ret0, method, result); err != nil {
+		return false, err
+	}
+
+	return *ret0, nil
+}
+
+// GetCurrentSpan get current span from contract
+func (c *Bor) GetCurrentSpan(snapshotNumber uint64) (*Span, error) {
+	// block
+	blockNr := rpc.BlockNumber(snapshotNumber)
+
+	// method
+	method := "getCurrentSpan"
+
+	data, err := c.validatorSetABI.Pack(method)
+	if err != nil {
+		fmt.Println("Unable to pack tx for getCurrentSpan", "error", err)
+		return nil, err
+	}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel() // cancel when we are finished consuming integers
+
+	// call
+	msgData := (hexutil.Bytes)(data)
+	toAddress := common.HexToAddress(c.config.ValidatorContract)
+	gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
+	result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{
+		Gas:  &gas,
+		To:   &toAddress,
+		Data: &msgData,
+	}, blockNr)
+	if err != nil {
+		return nil, err
+	}
+
+	// span result
+	ret := new(struct {
+		Number     *big.Int
+		StartBlock *big.Int
+		EndBlock   *big.Int
+	})
+	if err := c.validatorSetABI.Unpack(ret, method, result); err != nil {
+		return nil, err
+	}
+
+	// create new span
+	span := Span{
+		ID:         ret.Number.Uint64(),
+		StartBlock: ret.StartBlock.Uint64(),
+		EndBlock:   ret.EndBlock.Uint64(),
+	}
+
+	return &span, nil
+}
+
 // GetCurrentValidators get current validators
 func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([]*Validator, error) {
 	// block
@@ -864,16 +961,90 @@ func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([
 	return valz, nil
 }
 
+func (c *Bor) checkAndCommitSpan(
+	state *state.StateDB,
+	header *types.Header,
+	chain core.ChainContext,
+) error {
+	var pending bool = false
+	var span *Span = c.span
+
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		pending, _ = c.isSpanPending(header.Number.Uint64())
+		wg.Done()
+	}()
+
+	// fetch if span is nil
+	if span == nil {
+		wg.Add(1)
+		go func() {
+			fmt.Println("Fetching current span")
+			span, _ = c.GetCurrentSpan(header.Number.Uint64() - 1)
+			c.span = span // store in cache
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+
+	// commit span if there is new span pending or span is ending or end block is not set
+	if pending || (span != nil && (span.EndBlock == 0 || span.EndBlock == header.Number.Uint64())) {
+		err := c.commitSpan(span, state, header, chain)
+		c.span = nil // reset cache
+		return err
+	}
+
+	return nil
+}
+
 func (c *Bor) commitSpan(
+	span *Span,
 	state *state.StateDB,
 	header *types.Header,
 	chain core.ChainContext,
 ) error {
+	response, err := FetchFromHeimdall(c.httpClient, c.chainConfig.Bor.Heimdall, "bor", "span", strconv.FormatUint(span.ID+1, 10))
+	if err != nil {
+		return err
+	}
+
+	var heimdallSpan HeimdallSpan
+	if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil {
+		return err
+	}
+
+	// get validators bytes
+	var validators []MinimalVal
+	for _, val := range heimdallSpan.ValidatorSet.Validators {
+		validators = append(validators, val.MinimalVal())
+	}
+	validatorsBytes, err := rlp.EncodeToBytes(validators)
+	if err != nil {
+		return err
+	}
+
+	// get producers bytes
+	var producers []MinimalVal
+	for _, val := range heimdallSpan.SelectedProducers {
+		producers = append(validators, val.MinimalVal())
+	}
+	producersBytes, err := rlp.EncodeToBytes(producers)
+	if err != nil {
+		return err
+	}
+
 	// method
 	method := "commitSpan"
 
 	// get packed data
-	data, err := c.validatorSetABI.Pack(method)
+	data, err := c.validatorSetABI.Pack(method,
+		heimdallSpan.ID,
+		heimdallSpan.StartBlock,
+		heimdallSpan.EndBlock,
+		validatorsBytes,
+		producersBytes,
+	)
 	if err != nil {
 		fmt.Println("Unable to pack tx for commitSpan", "error", err)
 		return err
diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go
new file mode 100644
index 0000000000000000000000000000000000000000..d805f2c4193d2e834c9d75cbecf43751df10321c
--- /dev/null
+++ b/consensus/bor/rest.go
@@ -0,0 +1,58 @@
+package bor
+
+import (
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"path"
+)
+
+// ResponseWithHeight defines a response object type that wraps an original
+// response with a height.
+type ResponseWithHeight struct {
+	Height string          `json:"height"`
+	Result json.RawMessage `json:"result"`
+}
+
+// FetchFromHeimdall returns data from heimdall
+func FetchFromHeimdall(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) {
+	u, err := url.Parse(urlString)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, e := range paths {
+		if e != "" {
+			u.Path = path.Join(u.Path, e)
+		}
+	}
+
+	res, err := client.Get(u.String())
+	if err != nil {
+		return nil, err
+	}
+	defer res.Body.Close()
+
+	// check status code
+	if res.StatusCode != 200 {
+		return nil, fmt.Errorf("Error while fetching data from Heimdall")
+	}
+
+	// get response
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	// unmarshall data from buffer
+	var response ResponseWithHeight
+	fmt.Println("body", string(body))
+	if err := json.Unmarshal(body, &response); err != nil {
+		return nil, err
+	}
+
+	fmt.Println("response", response.Result)
+	return &response, nil
+}
diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go
index b55fa8c9ea8c0b6d6c6454d5b2af76e51a498dda..2583bd97b89da461295fd54dc75bdbcc6e49b958 100644
--- a/consensus/bor/snapshot.go
+++ b/consensus/bor/snapshot.go
@@ -29,22 +29,6 @@ import (
 	lru "github.com/hashicorp/golang-lru"
 )
 
-// Vote represents a single vote that an authorized signer made to modify the
-// list of authorizations.
-type Vote struct {
-	Signer    common.Address `json:"signer"`    // Authorized signer that cast this vote
-	Block     uint64         `json:"block"`     // Block number the vote was cast in (expire old votes)
-	Address   common.Address `json:"address"`   // Account being voted on to change its authorization
-	Authorize bool           `json:"authorize"` // Whether to authorize or deauthorize the voted account
-}
-
-// Tally is a simple vote tally to keep the current score of votes. Votes that
-// go against the proposal aren't counted since it's equivalent to not voting.
-type Tally struct {
-	Authorize bool `json:"authorize"` // Whether the vote is about authorizing or kicking someone
-	Votes     int  `json:"votes"`     // Number of votes until now wanting to pass the proposal
-}
-
 // Snapshot is the state of the authorization voting at a given point in time.
 type Snapshot struct {
 	config   *params.BorConfig // Consensus engine parameters to fine tune behavior
@@ -55,8 +39,6 @@ type Snapshot struct {
 	Hash         common.Hash               `json:"hash"`         // Block hash where the snapshot was created
 	ValidatorSet *ValidatorSet             `json:"validatorSet"` // Validator set at this moment
 	Recents      map[uint64]common.Address `json:"recents"`      // Set of recent signers for spam protections
-	// Votes        []*Vote                   `json:"votes"`        // List of votes cast in chronological order
-	// Tally map[common.Address]Tally `json:"tally"` // Current vote tally to avoid recalculating
 }
 
 // signersAscending implements the sort interface to allow sorting a list of addresses
@@ -69,7 +51,14 @@ func (s signersAscending) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 // newSnapshot creates a new snapshot with the specified startup parameters. This
 // method does not initialize the set of recent signers, so only ever use if for
 // the genesis block.
-func newSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, validators []*Validator, ethAPI *ethapi.PublicBlockChainAPI) *Snapshot {
+func newSnapshot(
+	config *params.BorConfig,
+	sigcache *lru.ARCCache,
+	number uint64,
+	hash common.Hash,
+	validators []*Validator,
+	ethAPI *ethapi.PublicBlockChainAPI,
+) *Snapshot {
 	snap := &Snapshot{
 		config:       config,
 		ethAPI:       ethAPI,
@@ -78,7 +67,6 @@ func newSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, number uint64
 		Hash:         hash,
 		ValidatorSet: NewValidatorSet(validators),
 		Recents:      make(map[uint64]common.Address),
-		// Tally:        make(map[common.Address]Tally),
 	}
 	return snap
 }
@@ -122,8 +110,6 @@ func (s *Snapshot) copy() *Snapshot {
 		Hash:         s.Hash,
 		ValidatorSet: s.ValidatorSet.Copy(),
 		Recents:      make(map[uint64]common.Address),
-		// Votes:        make([]*Vote, len(s.Votes)),
-		// Tally:        make(map[common.Address]Tally),
 	}
 	for block, signer := range s.Recents {
 		cpy.Recents[block] = signer
@@ -208,15 +194,20 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
 			return nil, err
 		}
 
+		fmt.Println(" validator set change ", number)
+
 		// change validator set and change proposer
 		if number > 0 && (number+1)%s.config.Sprint == 0 {
 			validatorBytes := header.Extra[extraVanity : len(header.Extra)-extraSeal]
 
-			// newVals, _ := GetValidators(number, number+1, s.config.Sprint, s.config.ValidatorContract, snap.ethAPI)
+			// get validators from headers and use that for new validator set
 			newVals, _ := ParseValidators(validatorBytes)
 			v := getUpdatedValidatorSet(snap.ValidatorSet.Copy(), newVals)
 			v.IncrementProposerPriority(1)
 			snap.ValidatorSet = v
+
+			// log new validator set
+			fmt.Println("Current validator set", "number", snap.Number, "validatorSet", snap.ValidatorSet)
 		}
 
 		// check if signer is in validator set
@@ -258,8 +249,6 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
 	snap.Number += uint64(len(headers))
 	snap.Hash = headers[len(headers)-1].Hash()
 
-	fmt.Println("Current validator set", "number", snap.Number, "validatorSet", snap.ValidatorSet)
-
 	return snap, nil
 }
 
diff --git a/consensus/bor/span.go b/consensus/bor/span.go
new file mode 100644
index 0000000000000000000000000000000000000000..6da0df7ea7353fe9446258735488f9e43191cd6d
--- /dev/null
+++ b/consensus/bor/span.go
@@ -0,0 +1,16 @@
+package bor
+
+// Span represents a current bor span
+type Span struct {
+	ID         uint64 `json:"span_id" yaml:"span_id"`
+	StartBlock uint64 `json:"start_block" yaml:"start_block"`
+	EndBlock   uint64 `json:"end_block" yaml:"end_block"`
+}
+
+// HeimdallSpan represents
+type HeimdallSpan struct {
+	Span
+	ValidatorSet      ValidatorSet `json:"validator_set" yaml:"validator_set"`
+	SelectedProducers []Validator  `json:"selected_producers" yaml:"selected_producers"`
+	ChainID           string       `json:"bor_chain_id" yaml:"bor_chain_id"`
+}
diff --git a/consensus/bor/validator.go b/consensus/bor/validator.go
index 32934ea2d4ab96cd128f7bc3c7edf0b4e0360d01..50b4a58ae4655e131ac7df280327555ce8b27bfe 100644
--- a/consensus/bor/validator.go
+++ b/consensus/bor/validator.go
@@ -6,20 +6,23 @@ import (
 	"errors"
 	"fmt"
 	"math/big"
+	"sort"
 	"strings"
 
 	"github.com/ethereum/go-ethereum/common"
 )
 
-// Volatile state for each Validator
+// Validator represets Volatile state for each Validator
 // NOTE: The ProposerPriority is not included in Validator.Hash();
 // make sure to update that method if changes are made here
 type Validator struct {
-	Address          common.Address `json:"address"`
-	VotingPower      int64          `json:"voting_power"`
-	ProposerPriority int64          `json:"proposer_priority"`
+	ID               uint64         `json:"ID"`
+	Address          common.Address `json:"signer"`
+	VotingPower      int64          `json:"power"`
+	ProposerPriority int64          `json:"accum"`
 }
 
+// NewValidator creates new validator
 func NewValidator(address common.Address, votingPower int64) *Validator {
 	return &Validator{
 		Address:          address,
@@ -105,6 +108,15 @@ func (v *Validator) PowerBytes() []byte {
 	return result
 }
 
+// MinimalVal returns block number of last validator update
+func (v *Validator) MinimalVal() MinimalVal {
+	return MinimalVal{
+		ID:          v.ID,
+		VotingPower: uint64(v.VotingPower),
+		Signer:      v.Address,
+	}
+}
+
 // ParseValidators returns validator set bytes
 func ParseValidators(validatorsBytes []byte) ([]*Validator, error) {
 	if len(validatorsBytes)%40 != 0 {
@@ -124,3 +136,29 @@ func ParseValidators(validatorsBytes []byte) ([]*Validator, error) {
 
 	return result, nil
 }
+
+// ---
+
+// MinimalVal is the minimal validator representation
+// Used to send validator information to bor validator contract
+type MinimalVal struct {
+	ID          uint64         `json:"ID"`
+	VotingPower uint64         `json:"power"` // TODO add 10^-18 here so that we dont overflow easily
+	Signer      common.Address `json:"signer"`
+}
+
+// SortMinimalValByAddress sorts validators
+func SortMinimalValByAddress(a []MinimalVal) []MinimalVal {
+	sort.Slice(a, func(i, j int) bool {
+		return bytes.Compare(a[i].Signer.Bytes(), a[j].Signer.Bytes()) < 0
+	})
+	return a
+}
+
+// ValidatorsToMinimalValidators converts array of validators to minimal validators
+func ValidatorsToMinimalValidators(vals []Validator) (minVals []MinimalVal) {
+	for _, val := range vals {
+		minVals = append(minVals, val.MinimalVal())
+	}
+	return
+}
diff --git a/contracts/validatorset/contract/ValidatorSet.abi b/contracts/validatorset/contract/ValidatorSet.abi
deleted file mode 100644
index 367a36292d34c8ffd3db0d830b5d930c99593afc..0000000000000000000000000000000000000000
--- a/contracts/validatorset/contract/ValidatorSet.abi
+++ /dev/null
@@ -1 +0,0 @@
-[{"constant":false,"inputs":[],"name":"finalizeChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"},{"name":"proof","type":"bytes"}],"name":"reportMalicious","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"validator","type":"address"},{"name":"blockNumber","type":"uint256"}],"name":"reportBenign","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_parentHash","type":"bytes32"},{"indexed":false,"name":"_newSet","type":"address[]"}],"name":"InitiateChange","type":"event"}]
\ No newline at end of file
diff --git a/contracts/validatorset/contract/ValidatorSet.bin b/contracts/validatorset/contract/ValidatorSet.bin
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/contracts/validatorset/contract/ValidatorSet.sol b/contracts/validatorset/contract/ValidatorSet.sol
deleted file mode 100644
index df23c1d369998aed8299d4bf2469cba30c85851d..0000000000000000000000000000000000000000
--- a/contracts/validatorset/contract/ValidatorSet.sol
+++ /dev/null
@@ -1,15 +0,0 @@
-pragma solidity 0.5.9;
-
-interface ValidatorSet {
-	/// Get initial validator set
-	function getInitialValidators()
-		external
-		view
-		returns (address[] memory, uint256[] memory);
-
-	/// Get current validator set (last enacted or initial if no changes ever made) with current stake.
-	function getValidators()
-		external
-		view
-		returns (address[] memory, uint256[] memory);
-}
\ No newline at end of file
diff --git a/contracts/validatorset/validatorset.go b/contracts/validatorset/validatorset.go
deleted file mode 100644
index c64bf8614c34bf9d783e58ac27177ed09d684046..0000000000000000000000000000000000000000
--- a/contracts/validatorset/validatorset.go
+++ /dev/null
@@ -1,399 +0,0 @@
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package validatorset
-
-import (
-	"math/big"
-	"strings"
-
-	ethereum "github.com/ethereum/go-ethereum"
-	"github.com/ethereum/go-ethereum/accounts/abi"
-	"github.com/ethereum/go-ethereum/accounts/abi/bind"
-	"github.com/ethereum/go-ethereum/common"
-	"github.com/ethereum/go-ethereum/core/types"
-	"github.com/ethereum/go-ethereum/event"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var (
-	_ = big.NewInt
-	_ = strings.NewReader
-	_ = ethereum.NotFound
-	_ = abi.U256
-	_ = bind.Bind
-	_ = common.Big1
-	_ = types.BloomLookup
-	_ = event.NewSubscription
-)
-
-// ValidatorsetABI is the input ABI used to generate the binding from.
-const ValidatorsetABI = "[{\"constant\":false,\"inputs\":[],\"name\":\"finalizeChange\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getValidators\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"},{\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"name\":\"proof\",\"type\":\"bytes\"}],\"name\":\"reportMalicious\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"validator\",\"type\":\"address\"},{\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"reportBenign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_parentHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"_newSet\",\"type\":\"address[]\"}],\"name\":\"InitiateChange\",\"type\":\"event\"}]"
-
-// Validatorset is an auto generated Go binding around an Ethereum contract.
-type Validatorset struct {
-	ValidatorsetCaller     // Read-only binding to the contract
-	ValidatorsetTransactor // Write-only binding to the contract
-	ValidatorsetFilterer   // Log filterer for contract events
-}
-
-// ValidatorsetCaller is an auto generated read-only Go binding around an Ethereum contract.
-type ValidatorsetCaller struct {
-	contract *bind.BoundContract // Generic contract wrapper for the low level calls
-}
-
-// ValidatorsetTransactor is an auto generated write-only Go binding around an Ethereum contract.
-type ValidatorsetTransactor struct {
-	contract *bind.BoundContract // Generic contract wrapper for the low level calls
-}
-
-// ValidatorsetFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
-type ValidatorsetFilterer struct {
-	contract *bind.BoundContract // Generic contract wrapper for the low level calls
-}
-
-// ValidatorsetSession is an auto generated Go binding around an Ethereum contract,
-// with pre-set call and transact options.
-type ValidatorsetSession struct {
-	Contract     *Validatorset     // Generic contract binding to set the session for
-	CallOpts     bind.CallOpts     // Call options to use throughout this session
-	TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
-}
-
-// ValidatorsetCallerSession is an auto generated read-only Go binding around an Ethereum contract,
-// with pre-set call options.
-type ValidatorsetCallerSession struct {
-	Contract *ValidatorsetCaller // Generic contract caller binding to set the session for
-	CallOpts bind.CallOpts       // Call options to use throughout this session
-}
-
-// ValidatorsetTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
-// with pre-set transact options.
-type ValidatorsetTransactorSession struct {
-	Contract     *ValidatorsetTransactor // Generic contract transactor binding to set the session for
-	TransactOpts bind.TransactOpts       // Transaction auth options to use throughout this session
-}
-
-// ValidatorsetRaw is an auto generated low-level Go binding around an Ethereum contract.
-type ValidatorsetRaw struct {
-	Contract *Validatorset // Generic contract binding to access the raw methods on
-}
-
-// ValidatorsetCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
-type ValidatorsetCallerRaw struct {
-	Contract *ValidatorsetCaller // Generic read-only contract binding to access the raw methods on
-}
-
-// ValidatorsetTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
-type ValidatorsetTransactorRaw struct {
-	Contract *ValidatorsetTransactor // Generic write-only contract binding to access the raw methods on
-}
-
-// NewValidatorset creates a new instance of Validatorset, bound to a specific deployed contract.
-func NewValidatorset(address common.Address, backend bind.ContractBackend) (*Validatorset, error) {
-	contract, err := bindValidatorset(address, backend, backend, backend)
-	if err != nil {
-		return nil, err
-	}
-	return &Validatorset{ValidatorsetCaller: ValidatorsetCaller{contract: contract}, ValidatorsetTransactor: ValidatorsetTransactor{contract: contract}, ValidatorsetFilterer: ValidatorsetFilterer{contract: contract}}, nil
-}
-
-// NewValidatorsetCaller creates a new read-only instance of Validatorset, bound to a specific deployed contract.
-func NewValidatorsetCaller(address common.Address, caller bind.ContractCaller) (*ValidatorsetCaller, error) {
-	contract, err := bindValidatorset(address, caller, nil, nil)
-	if err != nil {
-		return nil, err
-	}
-	return &ValidatorsetCaller{contract: contract}, nil
-}
-
-// NewValidatorsetTransactor creates a new write-only instance of Validatorset, bound to a specific deployed contract.
-func NewValidatorsetTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorsetTransactor, error) {
-	contract, err := bindValidatorset(address, nil, transactor, nil)
-	if err != nil {
-		return nil, err
-	}
-	return &ValidatorsetTransactor{contract: contract}, nil
-}
-
-// NewValidatorsetFilterer creates a new log filterer instance of Validatorset, bound to a specific deployed contract.
-func NewValidatorsetFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorsetFilterer, error) {
-	contract, err := bindValidatorset(address, nil, nil, filterer)
-	if err != nil {
-		return nil, err
-	}
-	return &ValidatorsetFilterer{contract: contract}, nil
-}
-
-// bindValidatorset binds a generic wrapper to an already deployed contract.
-func bindValidatorset(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
-	parsed, err := abi.JSON(strings.NewReader(ValidatorsetABI))
-	if err != nil {
-		return nil, err
-	}
-	return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
-}
-
-// Call invokes the (constant) contract method with params as input values and
-// sets the output to result. The result type might be a single field for simple
-// returns, a slice of interfaces for anonymous returns and a struct for named
-// returns.
-func (_Validatorset *ValidatorsetRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
-	return _Validatorset.Contract.ValidatorsetCaller.contract.Call(opts, result, method, params...)
-}
-
-// Transfer initiates a plain transaction to move funds to the contract, calling
-// its default method if one is available.
-func (_Validatorset *ValidatorsetRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
-	return _Validatorset.Contract.ValidatorsetTransactor.contract.Transfer(opts)
-}
-
-// Transact invokes the (paid) contract method with params as input values.
-func (_Validatorset *ValidatorsetRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
-	return _Validatorset.Contract.ValidatorsetTransactor.contract.Transact(opts, method, params...)
-}
-
-// Call invokes the (constant) contract method with params as input values and
-// sets the output to result. The result type might be a single field for simple
-// returns, a slice of interfaces for anonymous returns and a struct for named
-// returns.
-func (_Validatorset *ValidatorsetCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
-	return _Validatorset.Contract.contract.Call(opts, result, method, params...)
-}
-
-// Transfer initiates a plain transaction to move funds to the contract, calling
-// its default method if one is available.
-func (_Validatorset *ValidatorsetTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
-	return _Validatorset.Contract.contract.Transfer(opts)
-}
-
-// Transact invokes the (paid) contract method with params as input values.
-func (_Validatorset *ValidatorsetTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
-	return _Validatorset.Contract.contract.Transact(opts, method, params...)
-}
-
-// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
-//
-// Solidity: function getValidators() constant returns(address[], uint256[])
-func (_Validatorset *ValidatorsetCaller) GetValidators(opts *bind.CallOpts) ([]common.Address, []*big.Int, error) {
-	var (
-		ret0 = new([]common.Address)
-		ret1 = new([]*big.Int)
-	)
-	out := &[]interface{}{
-		ret0,
-		ret1,
-	}
-	err := _Validatorset.contract.Call(opts, out, "getValidators")
-	return *ret0, *ret1, err
-}
-
-// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
-//
-// Solidity: function getValidators() constant returns(address[], uint256[])
-func (_Validatorset *ValidatorsetSession) GetValidators() ([]common.Address, []*big.Int, error) {
-	return _Validatorset.Contract.GetValidators(&_Validatorset.CallOpts)
-}
-
-// GetValidators is a free data retrieval call binding the contract method 0xb7ab4db5.
-//
-// Solidity: function getValidators() constant returns(address[], uint256[])
-func (_Validatorset *ValidatorsetCallerSession) GetValidators() ([]common.Address, []*big.Int, error) {
-	return _Validatorset.Contract.GetValidators(&_Validatorset.CallOpts)
-}
-
-// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
-//
-// Solidity: function finalizeChange() returns()
-func (_Validatorset *ValidatorsetTransactor) FinalizeChange(opts *bind.TransactOpts) (*types.Transaction, error) {
-	return _Validatorset.contract.Transact(opts, "finalizeChange")
-}
-
-// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
-//
-// Solidity: function finalizeChange() returns()
-func (_Validatorset *ValidatorsetSession) FinalizeChange() (*types.Transaction, error) {
-	return _Validatorset.Contract.FinalizeChange(&_Validatorset.TransactOpts)
-}
-
-// FinalizeChange is a paid mutator transaction binding the contract method 0x75286211.
-//
-// Solidity: function finalizeChange() returns()
-func (_Validatorset *ValidatorsetTransactorSession) FinalizeChange() (*types.Transaction, error) {
-	return _Validatorset.Contract.FinalizeChange(&_Validatorset.TransactOpts)
-}
-
-// ReportBenign is a paid mutator transaction binding the contract method 0xd69f13bb.
-//
-// Solidity: function reportBenign(address validator, uint256 blockNumber) returns()
-func (_Validatorset *ValidatorsetTransactor) ReportBenign(opts *bind.TransactOpts, validator common.Address, blockNumber *big.Int) (*types.Transaction, error) {
-	return _Validatorset.contract.Transact(opts, "reportBenign", validator, blockNumber)
-}
-
-// ReportBenign is a paid mutator transaction binding the contract method 0xd69f13bb.
-//
-// Solidity: function reportBenign(address validator, uint256 blockNumber) returns()
-func (_Validatorset *ValidatorsetSession) ReportBenign(validator common.Address, blockNumber *big.Int) (*types.Transaction, error) {
-	return _Validatorset.Contract.ReportBenign(&_Validatorset.TransactOpts, validator, blockNumber)
-}
-
-// ReportBenign is a paid mutator transaction binding the contract method 0xd69f13bb.
-//
-// Solidity: function reportBenign(address validator, uint256 blockNumber) returns()
-func (_Validatorset *ValidatorsetTransactorSession) ReportBenign(validator common.Address, blockNumber *big.Int) (*types.Transaction, error) {
-	return _Validatorset.Contract.ReportBenign(&_Validatorset.TransactOpts, validator, blockNumber)
-}
-
-// ReportMalicious is a paid mutator transaction binding the contract method 0xc476dd40.
-//
-// Solidity: function reportMalicious(address validator, uint256 blockNumber, bytes proof) returns()
-func (_Validatorset *ValidatorsetTransactor) ReportMalicious(opts *bind.TransactOpts, validator common.Address, blockNumber *big.Int, proof []byte) (*types.Transaction, error) {
-	return _Validatorset.contract.Transact(opts, "reportMalicious", validator, blockNumber, proof)
-}
-
-// ReportMalicious is a paid mutator transaction binding the contract method 0xc476dd40.
-//
-// Solidity: function reportMalicious(address validator, uint256 blockNumber, bytes proof) returns()
-func (_Validatorset *ValidatorsetSession) ReportMalicious(validator common.Address, blockNumber *big.Int, proof []byte) (*types.Transaction, error) {
-	return _Validatorset.Contract.ReportMalicious(&_Validatorset.TransactOpts, validator, blockNumber, proof)
-}
-
-// ReportMalicious is a paid mutator transaction binding the contract method 0xc476dd40.
-//
-// Solidity: function reportMalicious(address validator, uint256 blockNumber, bytes proof) returns()
-func (_Validatorset *ValidatorsetTransactorSession) ReportMalicious(validator common.Address, blockNumber *big.Int, proof []byte) (*types.Transaction, error) {
-	return _Validatorset.Contract.ReportMalicious(&_Validatorset.TransactOpts, validator, blockNumber, proof)
-}
-
-// ValidatorsetInitiateChangeIterator is returned from FilterInitiateChange and is used to iterate over the raw logs and unpacked data for InitiateChange events raised by the Validatorset contract.
-type ValidatorsetInitiateChangeIterator struct {
-	Event *ValidatorsetInitiateChange // Event containing the contract specifics and raw log
-
-	contract *bind.BoundContract // Generic contract to use for unpacking event data
-	event    string              // Event name to use for unpacking event data
-
-	logs chan types.Log        // Log channel receiving the found contract events
-	sub  ethereum.Subscription // Subscription for errors, completion and termination
-	done bool                  // Whether the subscription completed delivering logs
-	fail error                 // Occurred error to stop iteration
-}
-
-// Next advances the iterator to the subsequent event, returning whether there
-// are any more events found. In case of a retrieval or parsing error, false is
-// returned and Error() can be queried for the exact failure.
-func (it *ValidatorsetInitiateChangeIterator) Next() bool {
-	// If the iterator failed, stop iterating
-	if it.fail != nil {
-		return false
-	}
-	// If the iterator completed, deliver directly whatever's available
-	if it.done {
-		select {
-		case log := <-it.logs:
-			it.Event = new(ValidatorsetInitiateChange)
-			if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
-				it.fail = err
-				return false
-			}
-			it.Event.Raw = log
-			return true
-
-		default:
-			return false
-		}
-	}
-	// Iterator still in progress, wait for either a data or an error event
-	select {
-	case log := <-it.logs:
-		it.Event = new(ValidatorsetInitiateChange)
-		if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
-			it.fail = err
-			return false
-		}
-		it.Event.Raw = log
-		return true
-
-	case err := <-it.sub.Err():
-		it.done = true
-		it.fail = err
-		return it.Next()
-	}
-}
-
-// Error returns any retrieval or parsing error occurred during filtering.
-func (it *ValidatorsetInitiateChangeIterator) Error() error {
-	return it.fail
-}
-
-// Close terminates the iteration process, releasing any pending underlying
-// resources.
-func (it *ValidatorsetInitiateChangeIterator) Close() error {
-	it.sub.Unsubscribe()
-	return nil
-}
-
-// ValidatorsetInitiateChange represents a InitiateChange event raised by the Validatorset contract.
-type ValidatorsetInitiateChange struct {
-	ParentHash [32]byte
-	NewSet     []common.Address
-	Raw        types.Log // Blockchain specific contextual infos
-}
-
-// FilterInitiateChange is a free log retrieval operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
-//
-// Solidity: event InitiateChange(bytes32 indexed _parentHash, address[] _newSet)
-func (_Validatorset *ValidatorsetFilterer) FilterInitiateChange(opts *bind.FilterOpts, _parentHash [][32]byte) (*ValidatorsetInitiateChangeIterator, error) {
-
-	var _parentHashRule []interface{}
-	for _, _parentHashItem := range _parentHash {
-		_parentHashRule = append(_parentHashRule, _parentHashItem)
-	}
-
-	logs, sub, err := _Validatorset.contract.FilterLogs(opts, "InitiateChange", _parentHashRule)
-	if err != nil {
-		return nil, err
-	}
-	return &ValidatorsetInitiateChangeIterator{contract: _Validatorset.contract, event: "InitiateChange", logs: logs, sub: sub}, nil
-}
-
-// WatchInitiateChange is a free log subscription operation binding the contract event 0x55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89.
-//
-// Solidity: event InitiateChange(bytes32 indexed _parentHash, address[] _newSet)
-func (_Validatorset *ValidatorsetFilterer) WatchInitiateChange(opts *bind.WatchOpts, sink chan<- *ValidatorsetInitiateChange, _parentHash [][32]byte) (event.Subscription, error) {
-
-	var _parentHashRule []interface{}
-	for _, _parentHashItem := range _parentHash {
-		_parentHashRule = append(_parentHashRule, _parentHashItem)
-	}
-
-	logs, sub, err := _Validatorset.contract.WatchLogs(opts, "InitiateChange", _parentHashRule)
-	if err != nil {
-		return nil, err
-	}
-	return event.NewSubscription(func(quit <-chan struct{}) error {
-		defer sub.Unsubscribe()
-		for {
-			select {
-			case log := <-logs:
-				// New log arrived, parse the event and forward to the user
-				event := new(ValidatorsetInitiateChange)
-				if err := _Validatorset.contract.UnpackLog(event, "InitiateChange", log); err != nil {
-					return err
-				}
-				event.Raw = log
-
-				select {
-				case sink <- event:
-				case err := <-sub.Err():
-					return err
-				case <-quit:
-					return nil
-				}
-			case err := <-sub.Err():
-				return err
-			case <-quit:
-				return nil
-			}
-		}
-	}), nil
-}