contracts: register hash only and fix interface puzzle

This commit is contained in:
rjl493456442 2018-06-12 10:24:33 +08:00
parent 536eb1632d
commit a387151976
8 changed files with 71 additions and 75 deletions

File diff suppressed because one or more lines are too long

View file

@ -86,16 +86,12 @@ contract Registrar {
* Note we trust the given information here provided by foundation, * Note we trust the given information here provided by foundation,
* need a trust less version for future. * need a trust less version for future.
* @param _sectionIndex section index * @param _sectionIndex section index
* @param _sectionHead section header * @param _hash checkpoint hash calculated in the client side
* @param _chtRoot cht root hash
* @param _bloomTrieRoot bloom trie root hash
* @return indicator whether set checkpoint successfully * @return indicator whether set checkpoint successfully
*/ */
function SetCheckpoint( function SetCheckpoint(
uint _sectionIndex, uint _sectionIndex,
bytes32 _sectionHead, bytes32 _hash
bytes32 _chtRoot,
bytes32 _bloomTrieRoot
) )
OnlyAuthorized OnlyAuthorized
public public
@ -111,10 +107,10 @@ contract Registrar {
return false; return false;
} }
checkpoints[_sectionIndex] = keccak256(abi.encodePacked(_sectionHead, _chtRoot, _bloomTrieRoot)); checkpoints[_sectionIndex] = _hash;
latest = _sectionIndex; latest = _sectionIndex;
emit NewCheckpointEvent(_sectionIndex, msg.sender, checkpoints[_sectionIndex]); emit NewCheckpointEvent(_sectionIndex, msg.sender, _hash);
} }
/** /**

View file

@ -23,9 +23,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts/registrar/contract" "github.com/ethereum/go-ethereum/contracts/registrar/contract"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
) )
@ -34,7 +32,7 @@ var (
RegistrarAddr = map[common.Hash]common.Address{ RegistrarAddr = map[common.Hash]common.Address{
// params.MainnetGenesisHash: common.HexToAddress(""), // params.MainnetGenesisHash: common.HexToAddress(""),
// params.TestnetGenesisHash: common.HexToAddress(""), // params.TestnetGenesisHash: common.HexToAddress(""),
params.RinkebyGenesisHash: common.HexToAddress("0xe3f2686a5d0c56a2d853c19c46b173a755263be8"), params.RinkebyGenesisHash: common.HexToAddress("0xaefc742121f79ce9d0953fea7c9cd10f6586179b"),
} }
) )
@ -45,8 +43,8 @@ type Registrar struct {
} }
// NewRegistrar binds checkpoint contract and returns a registrar instance. // NewRegistrar binds checkpoint contract and returns a registrar instance.
func NewRegistrar(contractAddr common.Address, backend ethapi.Backend, lightMode bool) (*Registrar, error) { func NewRegistrar(contractAddr common.Address, backend bind.ContractBackend) (*Registrar, error) {
contract, err := contract.NewContract(contractAddr, eth.NewContractBackend(backend, lightMode)) contract, err := contract.NewContract(contractAddr, backend)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -43,6 +43,7 @@ var (
ChtRoot: common.HexToHash("cf92fd2a79464354e8dae4d589ae92acdf90a3a4f8f7d8a3ec5fb9c114ae81cd"), ChtRoot: common.HexToHash("cf92fd2a79464354e8dae4d589ae92acdf90a3a4f8f7d8a3ec5fb9c114ae81cd"),
BloomTrieRoot: common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), BloomTrieRoot: common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
} }
checkpointHash = crypto.Keccak256Hash(trustedCheckpoint.SectionHead.Bytes(), trustedCheckpoint.ChtRoot.Bytes(), trustedCheckpoint.BloomTrieRoot.Bytes())
) )
// validateOperation executes the operation, watches and delivers all events fired by the backend and ensures the // validateOperation executes the operation, watches and delivers all events fired by the backend and ensures the
@ -200,8 +201,7 @@ func TestCheckpointRegister(t *testing.T) {
// Register unstable checkpoint // Register unstable checkpoint
validateOperation(t, c, contractBackend, func() { validateOperation(t, c, contractBackend, func() {
c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), trustedCheckpoint.SectionHead, c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), checkpointHash)
trustedCheckpoint.ChtRoot, trustedCheckpoint.BloomTrieRoot)
}, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error { }, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error {
hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx))) hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx)))
if err != nil { if err != nil {
@ -219,29 +219,27 @@ func TestCheckpointRegister(t *testing.T) {
validateOperation(t, c, contractBackend, func() { validateOperation(t, c, contractBackend, func() {
user2, _ := crypto.GenerateKey() user2, _ := crypto.GenerateKey()
unauthorized := bind.NewKeyedTransactor(user2) unauthorized := bind.NewKeyedTransactor(user2)
c.SetCheckpoint(unauthorized, big.NewInt(int64(trustedCheckpoint.SectionIdx)), trustedCheckpoint.SectionHead, c.SetCheckpoint(unauthorized, big.NewInt(int64(trustedCheckpoint.SectionIdx)), checkpointHash)
trustedCheckpoint.ChtRoot, trustedCheckpoint.BloomTrieRoot)
}, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error { }, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error {
hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx))) hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx)))
if err != nil { if err != nil {
return errors.New("get checkpoint failed") return errors.New("get checkpoint failed")
} }
if hash != emptyHash { if hash != emptyHash {
return errors.New("unstable checkpoint should be banned") return errors.New("checkpoint from unauthorized user should be banned")
} }
return nil return nil
}, "register by unauthorized user") }, "register by unauthorized user")
// Register a stable checkpoint // Register a stable checkpoint
validateOperation(t, c, contractBackend, func() { validateOperation(t, c, contractBackend, func() {
c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), trustedCheckpoint.SectionHead, c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), checkpointHash)
trustedCheckpoint.ChtRoot, trustedCheckpoint.BloomTrieRoot)
}, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error { }, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error {
hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx))) hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx)))
if err != nil { if err != nil {
return errors.New("get checkpoint failed") return errors.New("get checkpoint failed")
} }
if !trustedCheckpoint.HashEqual(common.Hash(hash)) { if hash != checkpointHash {
return errors.New("register stable checkpoint failed") return errors.New("register stable checkpoint failed")
} }
if !validateEvents(1, events) { if !validateEvents(1, events) {
@ -250,17 +248,16 @@ func TestCheckpointRegister(t *testing.T) {
return nil return nil
}, "register stable checkpoint") }, "register stable checkpoint")
fakeHash := crypto.Keccak256Hash([]byte("dead"), []byte("beef"), []byte("deadbeef"))
// Modify the latest checkpoint // Modify the latest checkpoint
validateOperation(t, c, contractBackend, func() { validateOperation(t, c, contractBackend, func() {
trustedCheckpoint.SectionHead = common.HexToHash("dead") c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), fakeHash)
c.SetCheckpoint(transactOpts, big.NewInt(int64(trustedCheckpoint.SectionIdx)), trustedCheckpoint.SectionHead,
trustedCheckpoint.ChtRoot, trustedCheckpoint.BloomTrieRoot)
}, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error { }, func(events <-chan *contract.ContractNewCheckpointEvent, events2 <-chan *contract.ContractAddAdminEvent, events3 <-chan *contract.ContractRemoveAdminEvent) error {
hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx))) hash, err := c.GetCheckpoint(nil, big.NewInt(int64(trustedCheckpoint.SectionIdx)))
if err != nil { if err != nil {
return errors.New("get checkpoint failed") return errors.New("get checkpoint failed")
} }
if !trustedCheckpoint.HashEqual(common.Hash(hash)) { if hash != fakeHash {
return errors.New("register stable checkpoint failed") return errors.New("register stable checkpoint failed")
} }
if !validateEvents(1, events) { if !validateEvents(1, events) {

View file

@ -39,20 +39,22 @@ import (
// object. These should be rewritten to internal Go method calls when the Go API // object. These should be rewritten to internal Go method calls when the Go API
// is refactored to support a clean library use. // is refactored to support a clean library use.
type ContractBackend struct { type ContractBackend struct {
eapi *ethapi.PublicEthereumAPI // Wrapper around the Ethereum object to access metadata filterBackend filters.Backend // Backend used for filter vm logs.
bcapi *ethapi.PublicBlockChainAPI // Wrapper around the blockchain to access chain data events *filters.EventSystem // Event system used to watch new fired vm logs.
txapi *ethapi.PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data eapi *ethapi.PublicEthereumAPI // Wrapper around the Ethereum object to access metadata
filterapi *filters.PublicFilterAPI // Wrapper around the filter to watch and retrieve contract logs bcapi *ethapi.PublicBlockChainAPI // Wrapper around the blockchain to access chain data
txapi *ethapi.PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data
} }
// NewContractBackend creates a new native contract backend using an existing // NewContractBackend creates a new native contract backend using an existing
// Ethereum object. // Ethereum object.
func NewContractBackend(apiBackend ethapi.Backend, lightMode bool) *ContractBackend { func NewContractBackend(apiBackend ethapi.Backend, filterBackend filters.Backend, lightMode bool) *ContractBackend {
return &ContractBackend{ return &ContractBackend{
eapi: ethapi.NewPublicEthereumAPI(apiBackend), filterBackend: filterBackend,
bcapi: ethapi.NewPublicBlockChainAPI(apiBackend), events: filters.NewEventSystem(apiBackend.EventMux(), filterBackend, lightMode),
txapi: ethapi.NewPublicTransactionPoolAPI(apiBackend, new(ethapi.AddrLocker)), eapi: ethapi.NewPublicEthereumAPI(apiBackend),
filterapi: filters.NewPublicFilterAPI(apiBackend.(filters.Backend), lightMode), bcapi: ethapi.NewPublicBlockChainAPI(apiBackend),
txapi: ethapi.NewPublicTransactionPoolAPI(apiBackend, new(ethapi.AddrLocker)),
} }
} }
@ -93,7 +95,7 @@ func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return (*big.Int)(price), nil return price.ToInt(), nil
} }
// EstimateGasLimit implements bind.ContractTransactor trying to estimate the gas // EstimateGasLimit implements bind.ContractTransactor trying to estimate the gas
@ -117,23 +119,34 @@ func (b *ContractBackend) SendTransaction(ctx context.Context, tx *types.Transac
// FilterLogs implements bind.ContractFilterer returning logs matching the given argument // FilterLogs implements bind.ContractFilterer returning logs matching the given argument
// that are stored within the state. // that are stored within the state.
func (b *ContractBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) { func (b *ContractBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) {
ret, err := b.filterapi.GetLogs(ctx, filters.FilterCriteria(query)) // Initialize unset filter boundaried to run from genesis to chain head
from := int64(0)
if query.FromBlock != nil {
from = query.FromBlock.Int64()
}
to := int64(-1)
if query.ToBlock != nil {
to = query.ToBlock.Int64()
}
// Construct and execute the filter
filter := filters.New(b.filterBackend, from, to, query.Addresses, query.Topics)
logs, err := filter.Logs(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
logs := make([]types.Log, len(ret)) res := make([]types.Log, len(logs))
for idx, log := range ret { for i, log := range logs {
logs[idx] = *log res[i] = *log
} }
return logs, nil return res, nil
} }
// SubscribeFilterLogs implements bind.ContractFilterer watching new fired logs matching the given argument. // SubscribeFilterLogs implements bind.ContractFilterer watching new fired logs matching the given argument.
func (b *ContractBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { func (b *ContractBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
// Subscribe to contract events // Subscribe to contract events
sink := make(chan []*types.Log) sink := make(chan []*types.Log)
sub, err := b.events.SubscribeLogs(query, sink)
sub, err := b.filterapi.EventSystem().SubscribeLogs(query, sink)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -75,11 +75,6 @@ func NewPublicFilterAPI(backend Backend, lightMode bool) *PublicFilterAPI {
return api return api
} }
// EventSystem returns
func (filter *PublicFilterAPI) EventSystem() *EventSystem {
return filter.events
}
// timeoutLoop runs every 5 minutes and deletes filters that have not been recently used. // timeoutLoop runs every 5 minutes and deletes filters that have not been recently used.
// Tt is started when the api is created. // Tt is started when the api is created.
func (api *PublicFilterAPI) timeoutLoop() { func (api *PublicFilterAPI) timeoutLoop() {

View file

@ -24,7 +24,6 @@ import (
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
@ -45,8 +44,6 @@ type Backend interface {
ChainDb() ethdb.Database ChainDb() ethdb.Database
EventMux() *event.TypeMux EventMux() *event.TypeMux
AccountManager() *accounts.Manager AccountManager() *accounts.Manager
BloomStatus() (uint64, uint64)
ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
// BlockChain API // BlockChain API
SetHead(number uint64) SetHead(number uint64)

View file

@ -62,27 +62,27 @@ type LesServer struct {
bloomTrieIndexer *core.ChainIndexer // Indexers for creating bloom trie root for each block section bloomTrieIndexer *core.ChainIndexer // Indexers for creating bloom trie root for each block section
} }
func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) { func NewLesServer(e *eth.Ethereum, config *eth.Config) (*LesServer, error) {
quitSync := make(chan struct{}) quitSync := make(chan struct{})
pm, err := NewProtocolManager(eth.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, eth.EventMux(), eth.Engine(), newPeerSet(), eth.BlockChain(), eth.TxPool(), eth.ChainDb(), nil, nil, nil, quitSync, new(sync.WaitGroup)) pm, err := NewProtocolManager(e.BlockChain().Config(), false, ServerProtocolVersions, config.NetworkId, e.EventMux(), e.Engine(), newPeerSet(), e.BlockChain(), e.TxPool(), e.ChainDb(), nil, nil, nil, quitSync, new(sync.WaitGroup))
if err != nil { if err != nil {
return nil, err return nil, err
} }
lesTopics := make([]discv5.Topic, len(AdvertiseProtocolVersions)) lesTopics := make([]discv5.Topic, len(AdvertiseProtocolVersions))
for i, pv := range AdvertiseProtocolVersions { for i, pv := range AdvertiseProtocolVersions {
lesTopics[i] = lesTopic(eth.BlockChain().Genesis().Hash(), pv) lesTopics[i] = lesTopic(e.BlockChain().Genesis().Hash(), pv)
} }
srv := &LesServer{ srv := &LesServer{
config: config, config: config,
backend: eth.APIBackend, backend: e.APIBackend,
chaindb: eth.ChainDb(), chaindb: e.ChainDb(),
protocolManager: pm, protocolManager: pm,
quitSync: quitSync, quitSync: quitSync,
lesTopics: lesTopics, lesTopics: lesTopics,
chtIndexer: light.NewChtIndexer(eth.ChainDb(), false), chtIndexer: light.NewChtIndexer(e.ChainDb(), false),
bloomTrieIndexer: light.NewBloomTrieIndexer(eth.ChainDb(), false), bloomTrieIndexer: light.NewBloomTrieIndexer(e.ChainDb(), false),
} }
logger := log.New() logger := log.New()
@ -105,7 +105,7 @@ func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
logger.Info("Loaded bloom trie", "section", bloomTrieLastSection, "head", bloomTrieSectionHead, "root", bloomTrieRoot) logger.Info("Loaded bloom trie", "section", bloomTrieLastSection, "head", bloomTrieSectionHead, "root", bloomTrieRoot)
} }
srv.chtIndexer.Start(eth.BlockChain()) srv.chtIndexer.Start(e.BlockChain())
pm.server = srv pm.server = srv
srv.defParams = &flowcontrol.ServerParams{ srv.defParams = &flowcontrol.ServerParams{
@ -113,9 +113,9 @@ func NewLesServer(eth *eth.Ethereum, config *eth.Config) (*LesServer, error) {
MinRecharge: 50000, MinRecharge: 50000,
} }
srv.fcManager = flowcontrol.NewClientManager(uint64(config.LightServ), 10, 1000000000) srv.fcManager = flowcontrol.NewClientManager(uint64(config.LightServ), 10, 1000000000)
srv.fcCostStats = newCostStats(eth.ChainDb()) srv.fcCostStats = newCostStats(e.ChainDb())
if addr, ok := registrar.RegistrarAddr[eth.BlockChain().Genesis().Hash()]; ok { if addr, ok := registrar.RegistrarAddr[e.BlockChain().Genesis().Hash()]; ok {
registrar, err := registrar.NewRegistrar(addr, eth.APIBackend, false) registrar, err := registrar.NewRegistrar(addr, eth.NewContractBackend(e.APIBackend, e.APIBackend, false))
if err != nil { if err != nil {
return nil, err return nil, err
} }