diff --git a/config/config.go b/config/config.go index c1c7255b..585d7514 100644 --- a/config/config.go +++ b/config/config.go @@ -55,6 +55,7 @@ type Config struct { Miner bool `long:"miner" description:"Enable miner module"` Generate bool `long:"generate" description:"Generate (mine) coins using the CPU"` GenerateOnTx bool `long:"generateontx" description:"Generate (mine) coins using the CPU when there is a new transaction"` + GenerateNoDevGap bool `long:"generatenodevgap" description:"Generate (mine) coins using the CPU on develop mode whithout gap"` MiningAddrs []string `long:"miningaddr" description:"Add the specified payment address to the list of addresses to use for generated blocks -- At least one address is required if the generate option is set"` MiningTimeOffset int `long:"miningtimeoffset" description:"Offset the mining timestamp of a block by this many seconds (positive values are in the past)"` BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"` @@ -140,6 +141,9 @@ type Config struct { // wallet WalletPass string AutoCollectEvm bool `long:"autocollectevm" description:"auto collect utxo to evm"` + + // TODO: It will soon be discarded in the near future + DevSnapSync bool `long:"devsnapsync" description:"Enable snap sync for P2P that only exist in development mode"` } func (c *Config) GetMinningAddrs() []types.Address { diff --git a/core/blockchain/snap.go b/core/blockchain/snap.go index b14b8027..158dd15f 100644 --- a/core/blockchain/snap.go +++ b/core/blockchain/snap.go @@ -213,9 +213,11 @@ func (b *BlockChain) ProcessBlockBySnap(sds []*SnapData) (meerdag.IBlock, error) if err != nil { return returnFun(err) } - err = b.addTokenState(dblock.GetID(), sd.tokenState, sd.prevTSHash) - if err != nil { - return returnFun(err) + if sd.prevTSHash != nil { + err = b.addTokenState(dblock.GetID(), sd.tokenState, sd.prevTSHash) + if err != nil { + return returnFun(err) + } } } else { err := b.indexManager.ConnectBlock(sd.block, dblock, nil) diff --git a/core/blockchain/token.go b/core/blockchain/token.go index 85174c93..ebb3abfb 100644 --- a/core/blockchain/token.go +++ b/core/blockchain/token.go @@ -190,7 +190,6 @@ func (b *BlockChain) addTokenState(id uint, state *token.TokenState, PrevStateHa func (b *BlockChain) GetTokenState(bid uint32) *token.TokenState { state, err := token.DBFetchTokenState(b.DB(), uint(bid)) if err != nil { - log.Error(err.Error()) return nil } return state diff --git a/core/blockchain/token/tokenstate.go b/core/blockchain/token/tokenstate.go index 3ca83507..504e5e78 100644 --- a/core/blockchain/token/tokenstate.go +++ b/core/blockchain/token/tokenstate.go @@ -247,6 +247,9 @@ func DBRemoveTokenState(db model.DataBase, id uint) error { } func NewTokenStateFromBytes(data []byte) (*TokenState, error) { + if len(data) <= 0 { + return nil, fmt.Errorf("No token state") + } ts := &TokenState{} _, err := ts.Deserialize(data) if err != nil { diff --git a/meerdag/blocktransf.go b/meerdag/blocktransf.go index 962ac677..989c0207 100644 --- a/meerdag/blocktransf.go +++ b/meerdag/blocktransf.go @@ -176,6 +176,22 @@ func (bd *MeerDAG) getBlockByOrder(order uint) IBlock { return bd.getBlockById(id) } +func (bd *MeerDAG) getBlockIDByOrder(order uint) uint { + if order >= MaxBlockOrder { + return MaxId + } + id, ok := bd.commitOrder[order] + if ok { + return id + } + id, err := DBGetBlockIdByOrder(bd.db, order) + if err != nil { + log.Error(err.Error()) + return MaxId + } + return id +} + // Return the last added block func (bd *MeerDAG) GetLastBlock() IBlock { bd.stateLock.Lock() diff --git a/meerdag/dagsync.go b/meerdag/dagsync.go index 16c862fb..0fa02a26 100644 --- a/meerdag/dagsync.go +++ b/meerdag/dagsync.go @@ -238,44 +238,82 @@ func (ds *DAGSync) getBlockChainFromMain(point IBlock, maxHashes uint) []*hash.H return result } -func (ds *DAGSync) CalcSnapSyncBlocks(locator []*SnapLocator, maxHashes uint, target *SnapLocator) ([]IBlock, error) { +func (ds *DAGSync) CalcSnapSyncBlocks(locator []*SnapLocator, maxHashes uint, target *SnapLocator) ([]IBlock, IBlock, error) { ds.bd.stateLock.Lock() defer ds.bd.stateLock.Unlock() if target != nil { - result := []IBlock{} if len(locator) != 1 { - return nil, fmt.Errorf("Locator len error") + return nil, nil, fmt.Errorf("Locator len error") } point := ds.bd.getBlock(locator[0].block) if point == nil { - return nil, fmt.Errorf("No block:%s", locator[0].block.String()) + return nil, nil, fmt.Errorf("No block:%s", locator[0].block.String()) } if !point.GetState().Root().IsEqual(locator[0].root) { - return nil, fmt.Errorf("Target root inconsistent:%s != %s", point.GetState().Root().String(), locator[0].root.String()) + return nil, nil, fmt.Errorf("Target root inconsistent:%s != %s", point.GetState().Root().String(), locator[0].root.String()) } targetBlock := ds.bd.getBlock(target.block) - if point == nil { - return nil, fmt.Errorf("No target:%s", target.block.String()) + if targetBlock == nil { + return nil, nil, fmt.Errorf("No target:%s", target.block.String()) } - for i := point.GetOrder() + 1; i <= targetBlock.GetOrder(); i++ { - block := ds.bd.getBlockByOrder(i) - if block == nil { - return result, fmt.Errorf("No block in order:%d", i) - } - result = append(result, block) - if uint(len(result)) >= maxHashes { - break - } + if point.GetOrder() >= targetBlock.GetOrder() { + return nil, nil, fmt.Errorf("Start point is invalid:%d >= %d(target)", point.GetOrder(), targetBlock.GetOrder()) } - return result, nil + return ds.getBlockChainForSnapSync(point, targetBlock, maxHashes), nil, nil } // get target mp := ds.bd.getMainChainTip() if mp.GetOrder() <= MaxSnapSyncTargetDepth { - return nil, fmt.Errorf("No blocks for snap-sync:%d", mp.GetOrder()) + return nil, nil, fmt.Errorf("No blocks for snap-sync:%d", mp.GetOrder()) + } + var targetBlock IBlock + for targetOrder := mp.GetOrder() - MaxSnapSyncTargetDepth; targetOrder > 0; targetOrder-- { + targetID := ds.bd.getBlockIDByOrder(targetOrder) + if ds.bd.isOnMainChain(targetID) { + targetBlock = ds.bd.getBlockById(targetID) + if targetBlock != nil { + break + } + } + } + + var point IBlock + for i := len(locator) - 1; i >= 0; i-- { + mainBlock := ds.bd.getBlock(locator[i].block) + if mainBlock == nil { + continue + } + if !mainBlock.GetState().Root().IsEqual(locator[i].root) { + continue + } + point = mainBlock + break } - return nil, nil + + if point == nil { + point = ds.bd.getGenesis() + } + if point.GetOrder() >= targetBlock.GetOrder() { + return nil, nil, fmt.Errorf("Start point is invalid:%d >= %d(target)", point.GetOrder(), targetBlock.GetOrder()) + } + return ds.getBlockChainForSnapSync(point, targetBlock, maxHashes), targetBlock, nil +} + +func (ds *DAGSync) getBlockChainForSnapSync(point IBlock, target IBlock, maxHashes uint) []IBlock { + result := []IBlock{} + for i := point.GetOrder() + 1; i <= target.GetOrder(); i++ { + block := ds.bd.getBlockByOrder(i) + if block == nil { + log.Warn("No block", "order", i) + return result + } + result = append(result, block) + if uint(len(result)) >= maxHashes { + break + } + } + return result } // NewDAGSync @@ -287,3 +325,10 @@ type SnapLocator struct { block *hash.Hash root *hash.Hash } + +func NewSnapLocator(block *hash.Hash, root *hash.Hash) *SnapLocator { + return &SnapLocator{ + block: block, + root: root, + } +} diff --git a/p2p/proto/v1/messages.ssz.go b/p2p/proto/v1/messages.ssz.go index 1af0a002..02a0e1ac 100644 --- a/p2p/proto/v1/messages.ssz.go +++ b/p2p/proto/v1/messages.ssz.go @@ -1,5 +1,5 @@ // Code generated by fastssz. DO NOT EDIT. -// Hash: 6dbc1ec8493f98bd301767824fbdbdeaa7197012ba18f6b60a7c2a1a9541634e +// Hash: 5fca8d5cd0b3d05c8b23538a44273c7937073ea5912004e4e75a0df6ee13e477 // Version: 0.1.2 package qitmeer_p2p_v1 @@ -2387,11 +2387,11 @@ func (l *Locator) MarshalSSZTo(buf []byte) (dst []byte, err error) { return } - // Field (1) 'StateRoot' - if l.StateRoot == nil { - l.StateRoot = new(Hash) + // Field (1) 'Root' + if l.Root == nil { + l.Root = new(Hash) } - if dst, err = l.StateRoot.MarshalSSZTo(dst); err != nil { + if dst, err = l.Root.MarshalSSZTo(dst); err != nil { return } @@ -2414,11 +2414,11 @@ func (l *Locator) UnmarshalSSZ(buf []byte) error { return err } - // Field (1) 'StateRoot' - if l.StateRoot == nil { - l.StateRoot = new(Hash) + // Field (1) 'Root' + if l.Root == nil { + l.Root = new(Hash) } - if err = l.StateRoot.UnmarshalSSZ(buf[32:64]); err != nil { + if err = l.Root.UnmarshalSSZ(buf[32:64]); err != nil { return err } @@ -2448,11 +2448,11 @@ func (l *Locator) HashTreeRootWith(hh ssz.HashWalker) (err error) { return } - // Field (1) 'StateRoot' - if l.StateRoot == nil { - l.StateRoot = new(Hash) + // Field (1) 'Root' + if l.Root == nil { + l.Root = new(Hash) } - if err = l.StateRoot.HashTreeRootWith(hh); err != nil { + if err = l.Root.HashTreeRootWith(hh); err != nil { return } @@ -2735,27 +2735,19 @@ func (s *SnapSyncReq) MarshalSSZTo(buf []byte) (dst []byte, err error) { dst = buf offset := int(68) - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if dst, err = s.TargetBlock.MarshalSSZTo(dst); err != nil { + if dst, err = s.Target.MarshalSSZTo(dst); err != nil { return } - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) - } - if dst, err = s.StateRoot.MarshalSSZTo(dst); err != nil { - return - } - - // Offset (2) 'Locator' + // Offset (1) 'Locator' dst = ssz.WriteOffset(dst, offset) offset += len(s.Locator) * 64 - // Field (2) 'Locator' + // Field (1) 'Locator' if size := len(s.Locator); size > 32 { err = ssz.ErrListTooBigFn("SnapSyncReq.Locator", size, 32) return @@ -2778,36 +2770,28 @@ func (s *SnapSyncReq) UnmarshalSSZ(buf []byte) error { } tail := buf - var o2 uint64 - - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) - } - if err = s.TargetBlock.UnmarshalSSZ(buf[0:32]); err != nil { - return err - } + var o1 uint64 - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if err = s.StateRoot.UnmarshalSSZ(buf[32:64]); err != nil { + if err = s.Target.UnmarshalSSZ(buf[0:64]); err != nil { return err } - // Offset (2) 'Locator' - if o2 = ssz.ReadOffset(buf[64:68]); o2 > size { + // Offset (1) 'Locator' + if o1 = ssz.ReadOffset(buf[64:68]); o1 > size { return ssz.ErrOffset } - if o2 < 68 { + if o1 < 68 { return ssz.ErrInvalidVariableOffset } - // Field (2) 'Locator' + // Field (1) 'Locator' { - buf = tail[o2:] + buf = tail[o1:] num, err := ssz.DivideInt2(len(buf), 64, 32) if err != nil { return err @@ -2829,7 +2813,7 @@ func (s *SnapSyncReq) UnmarshalSSZ(buf []byte) error { func (s *SnapSyncReq) SizeSSZ() (size int) { size = 68 - // Field (2) 'Locator' + // Field (1) 'Locator' size += len(s.Locator) * 64 return @@ -2844,23 +2828,15 @@ func (s *SnapSyncReq) HashTreeRoot() ([32]byte, error) { func (s *SnapSyncReq) HashTreeRootWith(hh ssz.HashWalker) (err error) { indx := hh.Index() - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) - } - if err = s.TargetBlock.HashTreeRootWith(hh); err != nil { - return - } - - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if err = s.StateRoot.HashTreeRootWith(hh); err != nil { + if err = s.Target.HashTreeRootWith(hh); err != nil { return } - // Field (2) 'Locator' + // Field (1) 'Locator' { subIndx := hh.Index() num := uint64(len(s.Locator)) @@ -2895,30 +2871,22 @@ func (s *SnapSyncRsp) MarshalSSZTo(buf []byte) (dst []byte, err error) { dst = buf offset := int(68) - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if dst, err = s.TargetBlock.MarshalSSZTo(dst); err != nil { + if dst, err = s.Target.MarshalSSZTo(dst); err != nil { return } - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) - } - if dst, err = s.StateRoot.MarshalSSZTo(dst); err != nil { - return - } - - // Offset (2) 'Datas' + // Offset (1) 'Datas' dst = ssz.WriteOffset(dst, offset) for ii := 0; ii < len(s.Datas); ii++ { offset += 4 offset += s.Datas[ii].SizeSSZ() } - // Field (2) 'Datas' + // Field (1) 'Datas' if size := len(s.Datas); size > 2000 { err = ssz.ErrListTooBigFn("SnapSyncRsp.Datas", size, 2000) return @@ -2948,36 +2916,28 @@ func (s *SnapSyncRsp) UnmarshalSSZ(buf []byte) error { } tail := buf - var o2 uint64 - - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) - } - if err = s.TargetBlock.UnmarshalSSZ(buf[0:32]); err != nil { - return err - } + var o1 uint64 - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if err = s.StateRoot.UnmarshalSSZ(buf[32:64]); err != nil { + if err = s.Target.UnmarshalSSZ(buf[0:64]); err != nil { return err } - // Offset (2) 'Datas' - if o2 = ssz.ReadOffset(buf[64:68]); o2 > size { + // Offset (1) 'Datas' + if o1 = ssz.ReadOffset(buf[64:68]); o1 > size { return ssz.ErrOffset } - if o2 < 68 { + if o1 < 68 { return ssz.ErrInvalidVariableOffset } - // Field (2) 'Datas' + // Field (1) 'Datas' { - buf = tail[o2:] + buf = tail[o1:] num, err := ssz.DecodeDynamicLength(buf, 2000) if err != nil { return err @@ -3003,7 +2963,7 @@ func (s *SnapSyncRsp) UnmarshalSSZ(buf []byte) error { func (s *SnapSyncRsp) SizeSSZ() (size int) { size = 68 - // Field (2) 'Datas' + // Field (1) 'Datas' for ii := 0; ii < len(s.Datas); ii++ { size += 4 size += s.Datas[ii].SizeSSZ() @@ -3021,23 +2981,15 @@ func (s *SnapSyncRsp) HashTreeRoot() ([32]byte, error) { func (s *SnapSyncRsp) HashTreeRootWith(hh ssz.HashWalker) (err error) { indx := hh.Index() - // Field (0) 'TargetBlock' - if s.TargetBlock == nil { - s.TargetBlock = new(Hash) - } - if err = s.TargetBlock.HashTreeRootWith(hh); err != nil { - return - } - - // Field (1) 'StateRoot' - if s.StateRoot == nil { - s.StateRoot = new(Hash) + // Field (0) 'Target' + if s.Target == nil { + s.Target = new(Locator) } - if err = s.StateRoot.HashTreeRootWith(hh); err != nil { + if err = s.Target.HashTreeRootWith(hh); err != nil { return } - // Field (2) 'Datas' + // Field (1) 'Datas' { subIndx := hh.Index() num := uint64(len(s.Datas)) diff --git a/p2p/proto/v1/snapsync.pb.go b/p2p/proto/v1/snapsync.pb.go index 44ad768e..f468c889 100644 --- a/p2p/proto/v1/snapsync.pb.go +++ b/p2p/proto/v1/snapsync.pb.go @@ -25,7 +25,7 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type Locator struct { Block *Hash `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"` - StateRoot *Hash `protobuf:"bytes,2,opt,name=stateRoot,proto3" json:"stateRoot,omitempty"` + Root *Hash `protobuf:"bytes,2,opt,name=root,proto3" json:"root,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -71,9 +71,9 @@ func (m *Locator) GetBlock() *Hash { return nil } -func (m *Locator) GetStateRoot() *Hash { +func (m *Locator) GetRoot() *Hash { if m != nil { - return m.StateRoot + return m.Root } return nil } @@ -166,9 +166,8 @@ func (m *TransferData) GetPrevTSHash() *Hash { } type SnapSyncReq struct { - TargetBlock *Hash `protobuf:"bytes,1,opt,name=targetBlock,proto3" json:"targetBlock,omitempty"` - StateRoot *Hash `protobuf:"bytes,2,opt,name=stateRoot,proto3" json:"stateRoot,omitempty"` - Locator []*Locator `protobuf:"bytes,3,rep,name=locator,proto3" json:"locator,omitempty" ssz-max:"32"` + Target *Locator `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + Locator []*Locator `protobuf:"bytes,2,rep,name=locator,proto3" json:"locator,omitempty" ssz-max:"32"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -207,16 +206,9 @@ func (m *SnapSyncReq) XXX_DiscardUnknown() { var xxx_messageInfo_SnapSyncReq proto.InternalMessageInfo -func (m *SnapSyncReq) GetTargetBlock() *Hash { +func (m *SnapSyncReq) GetTarget() *Locator { if m != nil { - return m.TargetBlock - } - return nil -} - -func (m *SnapSyncReq) GetStateRoot() *Hash { - if m != nil { - return m.StateRoot + return m.Target } return nil } @@ -229,9 +221,8 @@ func (m *SnapSyncReq) GetLocator() []*Locator { } type SnapSyncRsp struct { - TargetBlock *Hash `protobuf:"bytes,1,opt,name=targetBlock,proto3" json:"targetBlock,omitempty"` - StateRoot *Hash `protobuf:"bytes,2,opt,name=stateRoot,proto3" json:"stateRoot,omitempty"` - Datas []*TransferData `protobuf:"bytes,3,rep,name=datas,proto3" json:"datas,omitempty" ssz-max:"2000"` + Target *Locator `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + Datas []*TransferData `protobuf:"bytes,2,rep,name=datas,proto3" json:"datas,omitempty" ssz-max:"2000"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -270,16 +261,9 @@ func (m *SnapSyncRsp) XXX_DiscardUnknown() { var xxx_messageInfo_SnapSyncRsp proto.InternalMessageInfo -func (m *SnapSyncRsp) GetTargetBlock() *Hash { +func (m *SnapSyncRsp) GetTarget() *Locator { if m != nil { - return m.TargetBlock - } - return nil -} - -func (m *SnapSyncRsp) GetStateRoot() *Hash { - if m != nil { - return m.StateRoot + return m.Target } return nil } @@ -301,34 +285,33 @@ func init() { func init() { proto.RegisterFile("snapsync.proto", fileDescriptor_22c7ae889115bb49) } var fileDescriptor_22c7ae889115bb49 = []byte{ - // 417 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0xcf, 0x8e, 0xd2, 0x50, - 0x14, 0xc6, 0xed, 0x30, 0x9d, 0x19, 0x4f, 0x91, 0x8c, 0x37, 0x1a, 0x9b, 0x89, 0x29, 0xe4, 0xae, - 0x88, 0x93, 0x29, 0xa5, 0xfc, 0xd1, 0xb8, 0xac, 0xc6, 0xb8, 0x70, 0xd5, 0xf2, 0x02, 0xb7, 0xe5, - 0x52, 0x1a, 0x68, 0x6f, 0xe9, 0xbd, 0x10, 0xf0, 0x49, 0x5c, 0xf8, 0x2c, 0x26, 0xee, 0x5c, 0xfa, - 0x04, 0xc4, 0xe0, 0x1b, 0xf0, 0x04, 0x86, 0x5b, 0xc0, 0x4a, 0x62, 0x4d, 0x5c, 0xcc, 0xee, 0x9e, - 0xe4, 0xf7, 0x9d, 0xaf, 0xdf, 0x39, 0xa7, 0x50, 0xe3, 0x09, 0x49, 0xf9, 0x2a, 0x09, 0xcc, 0x34, - 0x63, 0x82, 0xa1, 0xda, 0x2c, 0x12, 0x31, 0xa5, 0x99, 0x99, 0xda, 0xa9, 0xb9, 0x68, 0xdf, 0xdc, - 0x85, 0x91, 0x18, 0xcf, 0x7d, 0x33, 0x60, 0x71, 0x2b, 0x64, 0x21, 0x6b, 0x49, 0xcc, 0x9f, 0x8f, - 0x64, 0x25, 0x0b, 0xf9, 0xca, 0xe5, 0x37, 0x8f, 0x62, 0xca, 0x39, 0x09, 0x69, 0x5e, 0xe2, 0x08, - 0x2e, 0x3f, 0xb0, 0x80, 0x08, 0x96, 0xa1, 0x17, 0xa0, 0xfa, 0x53, 0x16, 0x4c, 0x74, 0xa5, 0xa1, - 0x34, 0x35, 0xfb, 0x89, 0xf9, 0xa7, 0x91, 0xf9, 0x9e, 0xf0, 0xb1, 0x9b, 0x23, 0xc8, 0x86, 0x87, - 0x5c, 0x10, 0x41, 0x5d, 0xc6, 0x84, 0x7e, 0x56, 0xc2, 0xff, 0xc6, 0xf0, 0xe7, 0x33, 0xa8, 0x0e, - 0x32, 0x92, 0xf0, 0x11, 0xcd, 0xde, 0x12, 0x41, 0xd0, 0x6d, 0xd1, 0xb0, 0xea, 0x3c, 0xdd, 0xae, - 0xeb, 0x8f, 0x39, 0xff, 0x78, 0x17, 0x93, 0xe5, 0x6b, 0xdc, 0xb6, 0xba, 0xaf, 0x7a, 0x2f, 0xfb, - 0xf8, 0xe0, 0x78, 0x0b, 0x2a, 0x17, 0x4b, 0xc6, 0xa5, 0xdb, 0xdf, 0x61, 0xc9, 0xa0, 0x36, 0x5c, - 0x0d, 0x49, 0xe8, 0xc8, 0xe6, 0x95, 0x32, 0xfe, 0x88, 0x21, 0x04, 0xe7, 0x31, 0x89, 0x12, 0xfd, - 0xbc, 0xa1, 0x34, 0xaf, 0x5c, 0xf9, 0x46, 0x3d, 0x00, 0xc1, 0x26, 0x34, 0xf1, 0x76, 0x19, 0x74, - 0xb5, 0xac, 0x51, 0x01, 0x44, 0x5d, 0x80, 0x34, 0xa3, 0x8b, 0x81, 0xb7, 0x9b, 0x80, 0x7e, 0x51, - 0x32, 0x9d, 0x02, 0x87, 0xbf, 0x28, 0xa0, 0x79, 0x09, 0x49, 0xbd, 0x55, 0x12, 0xb8, 0x74, 0x86, - 0xfa, 0xa0, 0x09, 0x92, 0x85, 0x54, 0x38, 0xff, 0x5c, 0x4a, 0x11, 0xfc, 0x9f, 0xd5, 0xa0, 0x37, - 0x70, 0x39, 0xcd, 0xaf, 0x40, 0xaf, 0x34, 0x2a, 0x4d, 0xcd, 0x7e, 0x76, 0xaa, 0xd8, 0x1f, 0x89, - 0x73, 0xbd, 0x5d, 0xd7, 0xab, 0xc7, 0xf8, 0x1d, 0x1b, 0xbb, 0x07, 0x25, 0xfe, 0x5a, 0x0c, 0xc0, - 0xd3, 0x7b, 0x0d, 0xf0, 0x0e, 0xd4, 0x21, 0x11, 0x84, 0xef, 0x3f, 0xff, 0xf9, 0x29, 0x5f, 0xbc, - 0x3b, 0x07, 0x6d, 0xd7, 0xf5, 0xda, 0x31, 0x83, 0x6d, 0x59, 0x16, 0x76, 0x73, 0xb9, 0x73, 0xfd, - 0x6d, 0x63, 0x28, 0xdf, 0x37, 0x86, 0xf2, 0x63, 0x63, 0x28, 0x9f, 0x7e, 0x1a, 0x0f, 0xfc, 0x0b, - 0xf9, 0x9f, 0x74, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x26, 0x2a, 0xcb, 0x87, 0x03, 0x00, - 0x00, + // 405 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0xae, 0xd2, 0x40, + 0x14, 0x86, 0x2d, 0x97, 0x72, 0x6f, 0xce, 0x45, 0x72, 0x9d, 0x68, 0x6c, 0x6e, 0x4c, 0x21, 0xb3, + 0x22, 0x12, 0x4a, 0x29, 0xa0, 0xc6, 0x65, 0x35, 0xc6, 0x85, 0xab, 0x96, 0xbd, 0x99, 0x96, 0xa1, + 0x10, 0x68, 0xa7, 0xcc, 0x0c, 0x04, 0xdc, 0x9a, 0xf8, 0x0c, 0x2e, 0x7c, 0x20, 0x97, 0x3e, 0x01, + 0x31, 0xf8, 0x06, 0x3c, 0x81, 0x71, 0x5a, 0x48, 0x25, 0xb1, 0x89, 0xbb, 0x39, 0xcd, 0xf7, 0x9f, + 0xff, 0x3f, 0x3d, 0x07, 0x1a, 0x22, 0x21, 0xa9, 0xd8, 0x25, 0xa1, 0x95, 0x72, 0x26, 0x19, 0x6a, + 0xac, 0xe6, 0x32, 0xa6, 0x94, 0x5b, 0xa9, 0x93, 0x5a, 0x9b, 0xfe, 0x7d, 0x37, 0x9a, 0xcb, 0xd9, + 0x3a, 0xb0, 0x42, 0x16, 0xf7, 0x22, 0x16, 0xb1, 0x9e, 0xc2, 0x82, 0xf5, 0x54, 0x55, 0xaa, 0x50, + 0xaf, 0x4c, 0x7e, 0xff, 0x30, 0xa6, 0x42, 0x90, 0x88, 0x66, 0x25, 0xfe, 0x08, 0xd7, 0x1f, 0x58, + 0x48, 0x24, 0xe3, 0xe8, 0x39, 0xe8, 0xc1, 0x92, 0x85, 0x0b, 0x43, 0x6b, 0x69, 0xed, 0x5b, 0xe7, + 0xb1, 0xf5, 0xb7, 0x91, 0xf5, 0x9e, 0x88, 0x99, 0x97, 0x21, 0xa8, 0x0d, 0x55, 0xce, 0x98, 0x34, + 0x2a, 0x25, 0xa8, 0x22, 0xf0, 0xb7, 0x0a, 0xd4, 0xc7, 0x9c, 0x24, 0x62, 0x4a, 0xf9, 0x5b, 0x22, + 0x09, 0xea, 0x14, 0x6d, 0xea, 0xee, 0x93, 0xe3, 0xbe, 0xf9, 0x48, 0x88, 0x4f, 0xdd, 0x98, 0x6c, + 0x5f, 0xe3, 0xbe, 0x3d, 0x7c, 0x35, 0x7a, 0xf9, 0x02, 0x9f, 0x7c, 0x3a, 0xa0, 0x0b, 0xb9, 0x65, + 0x42, 0x19, 0xfd, 0x1b, 0x56, 0x0c, 0xea, 0xc3, 0xcd, 0x84, 0x44, 0xae, 0x6a, 0x7e, 0x55, 0xc6, + 0x9f, 0x31, 0x84, 0xa0, 0x1a, 0x93, 0x79, 0x62, 0x54, 0x5b, 0x5a, 0xfb, 0xc6, 0x53, 0x6f, 0x34, + 0x02, 0x90, 0x6c, 0x41, 0x13, 0x5f, 0x12, 0x49, 0x0d, 0xbd, 0xac, 0x51, 0x01, 0x44, 0x43, 0x80, + 0x94, 0xd3, 0xcd, 0xd8, 0xff, 0x33, 0xbc, 0x51, 0x2b, 0xf9, 0x31, 0x05, 0x0e, 0x7f, 0xd6, 0xe0, + 0xd6, 0x4f, 0x48, 0xea, 0xef, 0x92, 0xd0, 0xa3, 0x2b, 0xd4, 0x83, 0x9a, 0x24, 0x3c, 0xa2, 0x32, + 0xdf, 0xc2, 0xd3, 0xcb, 0x0e, 0xf9, 0xb6, 0xbc, 0x1c, 0x43, 0x6f, 0xe0, 0x7a, 0x99, 0x7d, 0x32, + 0x2a, 0xad, 0xab, 0x12, 0x85, 0x7b, 0x77, 0xdc, 0x37, 0xeb, 0xe7, 0x19, 0x06, 0x0e, 0xf6, 0x4e, + 0x4a, 0xfc, 0xa5, 0x98, 0x42, 0xa4, 0xff, 0x9f, 0xe2, 0x1d, 0xe8, 0x13, 0x22, 0x89, 0xc8, 0x33, + 0x3c, 0xbb, 0xe4, 0x8b, 0x17, 0xe0, 0xa2, 0xe3, 0xbe, 0xd9, 0x38, 0x07, 0x71, 0x6c, 0xdb, 0xc6, + 0x5e, 0x26, 0x77, 0xef, 0xbe, 0x1f, 0x4c, 0xed, 0xc7, 0xc1, 0xd4, 0x7e, 0x1e, 0x4c, 0xed, 0xeb, + 0x2f, 0xf3, 0x41, 0x50, 0x53, 0x77, 0x3a, 0xf8, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xa5, 0x06, 0xda, + 0x7c, 0x07, 0x03, 0x00, 0x00, } func (m *Locator) Marshal() (dAtA []byte, err error) { @@ -355,9 +338,9 @@ func (m *Locator) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } - if m.StateRoot != nil { + if m.Root != nil { { - size, err := m.StateRoot.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Root.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -494,24 +477,12 @@ func (m *SnapSyncReq) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSnapsync(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 } } - if m.StateRoot != nil { + if m.Target != nil { { - size, err := m.StateRoot.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSnapsync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.TargetBlock != nil { - { - size, err := m.TargetBlock.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -559,24 +530,12 @@ func (m *SnapSyncRsp) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSnapsync(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 } } - if m.StateRoot != nil { + if m.Target != nil { { - size, err := m.StateRoot.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintSnapsync(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.TargetBlock != nil { - { - size, err := m.TargetBlock.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Target.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -610,8 +569,8 @@ func (m *Locator) Size() (n int) { l = m.Block.Size() n += 1 + l + sovSnapsync(uint64(l)) } - if m.StateRoot != nil { - l = m.StateRoot.Size() + if m.Root != nil { + l = m.Root.Size() n += 1 + l + sovSnapsync(uint64(l)) } if m.XXX_unrecognized != nil { @@ -661,12 +620,8 @@ func (m *SnapSyncReq) Size() (n int) { } var l int _ = l - if m.TargetBlock != nil { - l = m.TargetBlock.Size() - n += 1 + l + sovSnapsync(uint64(l)) - } - if m.StateRoot != nil { - l = m.StateRoot.Size() + if m.Target != nil { + l = m.Target.Size() n += 1 + l + sovSnapsync(uint64(l)) } if len(m.Locator) > 0 { @@ -687,12 +642,8 @@ func (m *SnapSyncRsp) Size() (n int) { } var l int _ = l - if m.TargetBlock != nil { - l = m.TargetBlock.Size() - n += 1 + l + sovSnapsync(uint64(l)) - } - if m.StateRoot != nil { - l = m.StateRoot.Size() + if m.Target != nil { + l = m.Target.Size() n += 1 + l + sovSnapsync(uint64(l)) } if len(m.Datas) > 0 { @@ -780,7 +731,7 @@ func (m *Locator) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StateRoot", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Root", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -807,10 +758,10 @@ func (m *Locator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.StateRoot == nil { - m.StateRoot = &Hash{} + if m.Root == nil { + m.Root = &Hash{} } - if err := m.StateRoot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Root.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1116,7 +1067,7 @@ func (m *SnapSyncReq) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetBlock", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1143,50 +1094,14 @@ func (m *SnapSyncReq) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.TargetBlock == nil { - m.TargetBlock = &Hash{} + if m.Target == nil { + m.Target = &Locator{} } - if err := m.TargetBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StateRoot", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSnapsync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSnapsync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSnapsync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.StateRoot == nil { - m.StateRoot = &Hash{} - } - if err := m.StateRoot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Locator", wireType) } @@ -1276,7 +1191,7 @@ func (m *SnapSyncRsp) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TargetBlock", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1303,50 +1218,14 @@ func (m *SnapSyncRsp) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.TargetBlock == nil { - m.TargetBlock = &Hash{} + if m.Target == nil { + m.Target = &Locator{} } - if err := m.TargetBlock.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Target.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StateRoot", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSnapsync - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSnapsync - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSnapsync - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.StateRoot == nil { - m.StateRoot = &Hash{} - } - if err := m.StateRoot.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Datas", wireType) } diff --git a/p2p/proto/v1/snapsync.proto b/p2p/proto/v1/snapsync.proto index 393cb6c3..af615302 100644 --- a/p2p/proto/v1/snapsync.proto +++ b/p2p/proto/v1/snapsync.proto @@ -8,7 +8,7 @@ import "message.proto"; message Locator { Hash block =1; - Hash stateRoot=2; + Hash root=2; } message TransferData { @@ -21,13 +21,11 @@ message TransferData { } message SnapSyncReq { - Hash targetBlock =1; - Hash stateRoot=2; - repeated Locator locator =3 [(gogoproto.moretags) = "ssz-max:\"32\""]; + Locator target =1; + repeated Locator locator =2 [(gogoproto.moretags) = "ssz-max:\"32\""]; } message SnapSyncRsp { - Hash targetBlock =1; - Hash stateRoot=2; - repeated TransferData datas =3 [(gogoproto.moretags) = "ssz-max:\"2000\""]; + Locator target =1; + repeated TransferData datas =2 [(gogoproto.moretags) = "ssz-max:\"2000\""]; } \ No newline at end of file diff --git a/p2p/service.go b/p2p/service.go index a9a87387..4bc8be1d 100644 --- a/p2p/service.go +++ b/p2p/service.go @@ -667,7 +667,9 @@ func NewService(cfg *config.Config, consensus model.Consensus, param *params.Par bc := consensus.BlockChain().(*blockchain.BlockChain) services := defaultServices if bc.MeerChain().SyncMode() == downloader.SnapSync { - //services |= pv.Snap + if cfg.DevSnapSync { + services |= pv.Snap + } } s := &Service{ cfg: &common.Config{ diff --git a/p2p/synch/protohelper.go b/p2p/synch/protohelper.go index 0984dfef..b75385d7 100644 --- a/p2p/synch/protohelper.go +++ b/p2p/synch/protohelper.go @@ -101,6 +101,16 @@ func getMessageString(message interface{}) string { } str += fmt.Sprintf(" blockHash:%s", block.Hash().String()) return str + + case *pb.SnapSyncRsp: + if isLocatorEmpty(msg.Target) { + str += fmt.Sprintf(" datas:%d", len(msg.Datas)) + } else { + targetBlock := changePBHashToHash(msg.Target.Block) + stateRoot := changePBHashToHash(msg.Target.Root) + str += fmt.Sprintf(" targetBlock:%s stateRoot:%s datas:%d", targetBlock.String(), stateRoot.String(), len(msg.Datas)) + } + return str } str += fmt.Sprintf("%v", message) if len(str) > peers.MaxBadResponses { @@ -129,3 +139,51 @@ func changePBGraphStateToGraphState(csgs *pb.GraphState) *meerdag.GraphState { gs.SetTips(tips) return gs } + +func changePBLocatorsToLocators(locator []*pb.Locator) []*meerdag.SnapLocator { + if len(locator) <= 0 { + return nil + } + sls := []*meerdag.SnapLocator{} + for _, loc := range locator { + sls = append(sls, changePBLocatorToLocator(loc)) + } + return sls +} + +func changePBLocatorToLocator(locator *pb.Locator) *meerdag.SnapLocator { + if isLocatorEmpty(locator) { + return nil + } + return meerdag.NewSnapLocator(changePBHashToHash(locator.Block), changePBHashToHash(locator.Root)) +} + +func isLocatorEmpty(locator *pb.Locator) bool { + if locator == nil { + return true + } + if locator.Block == nil || + locator.Root == nil { + return true + } + if len(locator.Block.Hash) <= 0 || + len(locator.Root.Hash) <= 0 { + return true + } + if !isZeroPBHash(locator.Block) { + return false + } + return true +} + +func isZeroPBHash(ha *pb.Hash) bool { + if ha == nil || len(ha.Hash) <= 0 { + return true + } + for i := 0; i < len(ha.Hash); i++ { + if ha.Hash[i] != 0 { + return false + } + } + return true +} diff --git a/p2p/synch/snapstatus.go b/p2p/synch/snapstatus.go index 56c265bf..a5e27084 100644 --- a/p2p/synch/snapstatus.go +++ b/p2p/synch/snapstatus.go @@ -136,5 +136,8 @@ func (s *SnapStatus) isCompleted() bool { } func NewSnapStatus(peid peer.ID) *SnapStatus { - return &SnapStatus{peid: peid} + return &SnapStatus{ + peid: peid, + locker: &sync.RWMutex{}, + } } diff --git a/p2p/synch/snapsync.go b/p2p/synch/snapsync.go index 34ff678a..d23d8022 100644 --- a/p2p/synch/snapsync.go +++ b/p2p/synch/snapsync.go @@ -3,12 +3,14 @@ package synch import ( "context" "fmt" + "github.com/Qitmeer/qng/common/hash" "github.com/Qitmeer/qng/core/blockchain" "github.com/Qitmeer/qng/core/blockchain/token" "github.com/Qitmeer/qng/core/blockchain/utxo" "github.com/Qitmeer/qng/core/event" "github.com/Qitmeer/qng/core/json" "github.com/Qitmeer/qng/core/types" + "github.com/Qitmeer/qng/meerdag" "github.com/Qitmeer/qng/p2p/common" "github.com/Qitmeer/qng/p2p/peers" pb "github.com/Qitmeer/qng/p2p/proto/v1" @@ -86,12 +88,18 @@ cleanup: } latest, err := ps.Chain().ProcessBlockBySnap(sds) if err != nil { + log.Warn(err.Error()) break } ps.snapStatus.SetSyncPoint(latest) add += len(sds) } ps.sy.p2p.BlockChain().EndSnapSyncing() + sp := ps.snapStatus.GetSyncPoint() + if sp != nil { + bestPeer.UpdateSyncPoint(sp.GetHash()) + log.Debug("Snap-sync update point", "point", sp.GetHash().String()) + } // ------ ps.sy.p2p.Consensus().Events().Send(event.New(event.DownloaderEnd)) if ps.snapStatus.isCompleted() { @@ -103,7 +111,14 @@ cleanup: ps.SetSyncPeer(nil) ps.processwg.Done() - return true + if ps.snapStatus.isCompleted() { + ps.snapStatus = nil + return false + } else { + ps.snapStatus = nil + go ps.TryAgainUpdateSyncPeer(false) + return true + } } func (ps *PeerSync) syncSnapStatus(pe *peers.Peer) (*pb.SnapSyncRsp, error) { @@ -112,19 +127,20 @@ func (ps *PeerSync) syncSnapStatus(pe *peers.Peer) (*pb.SnapSyncRsp, error) { targetBlock, stateRoot := ps.snapStatus.GetTarget() if targetBlock != nil { sp := ps.snapStatus.GetSyncPoint() - req.TargetBlock = &pb.Hash{Hash: targetBlock.Bytes()} - req.StateRoot = &pb.Hash{Hash: stateRoot.Bytes()} + req.Target = &pb.Locator{Block: &pb.Hash{Hash: targetBlock.Bytes()}, Root: &pb.Hash{Hash: stateRoot.Bytes()}} req.Locator = append(req.Locator, &pb.Locator{ - Block: &pb.Hash{Hash: sp.GetHash().Bytes()}, - StateRoot: &pb.Hash{Hash: sp.GetState().Root().Bytes()}, + Block: &pb.Hash{Hash: sp.GetHash().Bytes()}, + Root: &pb.Hash{Hash: sp.GetState().Root().Bytes()}, }) } else { + zeroH := &pb.Hash{Hash: hash.ZeroHash.Bytes()} + req.Target = &pb.Locator{Block: zeroH, Root: zeroH} point := pe.SyncPoint() mainLocator, mainStateRoot := ps.dagSync.GetMainLocator(point, true) for i := 0; i < len(mainLocator); i++ { req.Locator = append(req.Locator, &pb.Locator{ - Block: &pb.Hash{Hash: mainLocator[i].Bytes()}, - StateRoot: &pb.Hash{Hash: mainStateRoot[i].Bytes()}, + Block: &pb.Hash{Hash: mainLocator[i].Bytes()}, + Root: &pb.Hash{Hash: mainStateRoot[i].Bytes()}, }) } } @@ -137,11 +153,11 @@ func (ps *PeerSync) syncSnapStatus(pe *peers.Peer) (*pb.SnapSyncRsp, error) { } func (ps *PeerSync) processRsp(ssr *pb.SnapSyncRsp) ([]*blockchain.SnapData, error) { - if len(ssr.TargetBlock.Hash) <= 0 || len(ssr.StateRoot.Hash) <= 0 { + if isLocatorEmpty(ssr.Target) { return nil, fmt.Errorf("No snap sync data") } - targetBlock := changePBHashToHash(ssr.TargetBlock) - stateRoot := changePBHashToHash(ssr.StateRoot) + targetBlock := changePBHashToHash(ssr.Target.Block) + stateRoot := changePBHashToHash(ssr.Target.Root) ps.snapStatus.SetTarget(targetBlock, stateRoot) log.Trace("Snap-sync receive", "targetBlock", targetBlock.String(), "stateRoot", stateRoot.String(), "dataNum", len(ssr.Datas), "processID", ps.getProcessID()) @@ -181,7 +197,7 @@ func (ps *PeerSync) processRsp(ssr *pb.SnapSyncRsp) ([]*blockchain.SnapData, err } sd.SetTokenState(ts) } - if data.PrevTSHash != nil && len(data.PrevTSHash.Hash) > 0 { + if !isZeroPBHash(data.PrevTSHash) { sd.SetPrevTSHash(changePBHashToHash(data.PrevTSHash)) } ret = append(ret, sd) @@ -205,12 +221,66 @@ func (s *Sync) sendSnapSyncRequest(stream network.Stream, pe *peers.Peer) (*pb.S func (s *Sync) snapSyncHandler(ctx context.Context, msg interface{}, stream libp2pcore.Stream, pe *peers.Peer) *common.Error { m, ok := msg.(*pb.SnapSyncReq) if !ok { - err := fmt.Errorf("message is not type *pb.Hash") + err := fmt.Errorf("message is not type *pb.SnapSyncReq") + return ErrMessage(err) + } + log.Debug("Received Snap-sync request", "peer", pe.GetID().String()) + blocks, target, err := s.peerSync.dagSync.CalcSnapSyncBlocks(changePBLocatorsToLocators(m.Locator), MaxBlockLocatorsPerMsg, changePBLocatorToLocator(m.Target)) + if err != nil { + log.Error(err.Error()) return ErrMessage(err) } - if m.TargetBlock == nil || len(m.TargetBlock.Hash) <= 0 { - log.Info("Received Snap-sync request", "peer", pe.GetID().String()) + if len(blocks) <= 0 { + return ErrMessage(fmt.Errorf("Can't find blocks for snap-sync")) } + rsp := &pb.SnapSyncRsp{Datas: []*pb.TransferData{}} + if isLocatorEmpty(m.Target) { + rsp.Target = &pb.Locator{ + Block: &pb.Hash{Hash: target.GetHash().Bytes()}, + Root: &pb.Hash{Hash: target.GetState().Root().Bytes()}, + } + } else { + rsp.Target = m.Target + } + for _, block := range blocks { + data := &pb.TransferData{} + blkBytes, err := s.p2p.BlockChain().FetchBlockBytesByHash(block.GetHash()) + if err != nil { + return ErrMessage(err) + } + data.Block = blkBytes - return s.EncodeResponseMsg(stream, m) + stxo, err := s.p2p.BlockChain().DB().GetSpendJournal(block.GetHash()) + if err != nil { + return ErrMessage(err) + } + data.Stxos = stxo + + data.DagBlock = block.Bytes() + data.Main = s.p2p.BlockChain().BlockDAG().IsOnMainChain(block.GetID()) + ts := s.p2p.BlockChain().GetTokenState(uint32(block.GetID())) + if ts != nil { + prevTSHash, err := meerdag.DBGetDAGBlockHashByID(s.p2p.BlockChain().DB(), uint64(ts.PrevStateID)) + if err != nil { + return ErrMessage(err) + } + serializedData, err := ts.Serialize() + if err != nil { + return ErrMessage(err) + } + data.TokenState = serializedData + data.PrevTSHash = &pb.Hash{ + Hash: prevTSHash.Bytes(), + } + } else { + data.PrevTSHash = &pb.Hash{ + Hash: hash.ZeroHash.Bytes(), + } + } + if uint64(rsp.SizeSSZ()+data.SizeSSZ()+BLOCKDATA_SSZ_HEAD_SIZE) >= s.p2p.Encoding().GetMaxChunkSize() { + break + } + rsp.Datas = append(rsp.Datas, data) + } + return s.EncodeResponseMsg(stream, rsp) } diff --git a/p2p/synch/sync.go b/p2p/synch/sync.go index c0c0ecbb..2b18f27c 100644 --- a/p2p/synch/sync.go +++ b/p2p/synch/sync.go @@ -249,7 +249,7 @@ func (s *Sync) registerRPCHandlers() { s.registerRPC( RPCSyncSnap, - &pb.SnapSyncRsp{}, + &pb.SnapSyncReq{}, s.snapSyncHandler, ) } diff --git a/services/common/flags.go b/services/common/flags.go index 97a9622b..934bc9d7 100644 --- a/services/common/flags.go +++ b/services/common/flags.go @@ -640,6 +640,16 @@ var ( Usage: "Build block template timeout by Millisecond.(Can limit the number of transactions included in the block)", Destination: &cfg.GBTTimeOut, }, + &cli.BoolFlag{ + Name: "dev_snapsync", + Usage: "Enable snap sync for P2P that only exist in development mode", + Destination: &cfg.DevSnapSync, + }, + &cli.BoolFlag{ + Name: "generatenodevgap", + Usage: "Generate (mine) coins using the CPU on develop mode whithout gap", + Destination: &cfg.GenerateNoDevGap, + }, } ) diff --git a/services/miner/cpuworker.go b/services/miner/cpuworker.go index b663377a..71330757 100644 --- a/services/miner/cpuworker.go +++ b/services/miner/cpuworker.go @@ -316,7 +316,7 @@ out: } if params.ActiveNetParams.Params.IsDevelopDiff() { w.miner.updateBlockTemplate(true) - if !w.miner.NoDevelopGap { + if !w.miner.cfg.GenerateNoDevGap { time.Sleep(params.ActiveNetParams.Params.TargetTimePerBlock) } } diff --git a/testutils/mocknode.go b/testutils/mocknode.go index c7790d13..646a00b3 100644 --- a/testutils/mocknode.go +++ b/testutils/mocknode.go @@ -47,6 +47,7 @@ func DefaultConfig(pb *testprivatekey.Builder) (*config.Config, error) { cfg.SubmitNoSynced = true cfg.AcctMode = true cfg.EVMEnv = "--nodiscover --v5disc=false --rpc.allow-unprotected-txs" + cfg.GenerateNoDevGap = true params.ActiveNetParams = ¶ms.PrivNetParam coinbasePKHex := pb.GetHex(testprivatekey.CoinbaseIdx) @@ -177,7 +178,6 @@ func (mn *MockNode) setup() error { log.Info("Import default key", "addr", account.String()) - mn.Node().GetQitmeerFull().GetMiner().NoDevelopGap = true params.ActiveNetParams.PowConfig.DifficultyMode = pow.DIFFICULTY_MODE_DEVELOP return nil }