From 8d7e52bed5bdf9a97862dcaa8fff8892a4fd2c01 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 13:50:57 +0800 Subject: [PATCH 01/26] #395 add skipped blocksmith table migration --- common/database/migration.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/database/migration.go b/common/database/migration.go index dd7355b11..aabb7f0ee 100644 --- a/common/database/migration.go +++ b/common/database/migration.go @@ -187,6 +187,14 @@ func (m *Migration) Init() error { ALTER TABLE "node_registry" RENAME COLUMN "queued" TO "registration_status" `, + ` + CREATE TABLE IF NOT EXISTS "skipped_blocksmith" ( + "blocksmith_public_key" BLOB, + "pop_change" INTEGER, + "block_height" INTEGER, + "blocksmith_index" INTEGER + ) + `, } return nil } From fa6e0bf546ceb689200755a4b6a1ecf86c4aaef1 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 13:51:22 +0800 Subject: [PATCH 02/26] #395 initialize skippedBlocksmithQuery --- common/query/skippedBlocksmithQuery.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 common/query/skippedBlocksmithQuery.go diff --git a/common/query/skippedBlocksmithQuery.go b/common/query/skippedBlocksmithQuery.go new file mode 100644 index 000000000..af207a985 --- /dev/null +++ b/common/query/skippedBlocksmithQuery.go @@ -0,0 +1,16 @@ +package query + +import ( + "github.com/zoobc/zoobc-core/common/chaintype" +) + +type ( + SkippedBlocksmithQueryInterface interface { + } + + SkippedBlocksmithQuery struct { + Fields []string + TableName string + ChainType chaintype.ChainType + } +) From 18e465d20fa693f2af36a35015010fd4178ee362 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 13:52:02 +0800 Subject: [PATCH 03/26] #395 add skipped blocksmith model --- common/model/skippedBlocksmith.pb.go | 107 +++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 common/model/skippedBlocksmith.pb.go diff --git a/common/model/skippedBlocksmith.pb.go b/common/model/skippedBlocksmith.pb.go new file mode 100644 index 000000000..1e85f0181 --- /dev/null +++ b/common/model/skippedBlocksmith.pb.go @@ -0,0 +1,107 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: model/skippedBlocksmith.proto + +package model + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type SkippedBlocksmith struct { + BlocksmithPublicKey []byte `protobuf:"bytes,1,opt,name=BlocksmithPublicKey,proto3" json:"BlocksmithPublicKey,omitempty"` + POPChange int64 `protobuf:"varint,2,opt,name=POPChange,proto3" json:"POPChange,omitempty"` + BlockHeight int64 `protobuf:"varint,3,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"` + BlocksmithIndex int32 `protobuf:"varint,4,opt,name=BlocksmithIndex,proto3" json:"BlocksmithIndex,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SkippedBlocksmith) Reset() { *m = SkippedBlocksmith{} } +func (m *SkippedBlocksmith) String() string { return proto.CompactTextString(m) } +func (*SkippedBlocksmith) ProtoMessage() {} +func (*SkippedBlocksmith) Descriptor() ([]byte, []int) { + return fileDescriptor_1c20326cefe017aa, []int{0} +} + +func (m *SkippedBlocksmith) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SkippedBlocksmith.Unmarshal(m, b) +} +func (m *SkippedBlocksmith) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SkippedBlocksmith.Marshal(b, m, deterministic) +} +func (m *SkippedBlocksmith) XXX_Merge(src proto.Message) { + xxx_messageInfo_SkippedBlocksmith.Merge(m, src) +} +func (m *SkippedBlocksmith) XXX_Size() int { + return xxx_messageInfo_SkippedBlocksmith.Size(m) +} +func (m *SkippedBlocksmith) XXX_DiscardUnknown() { + xxx_messageInfo_SkippedBlocksmith.DiscardUnknown(m) +} + +var xxx_messageInfo_SkippedBlocksmith proto.InternalMessageInfo + +func (m *SkippedBlocksmith) GetBlocksmithPublicKey() []byte { + if m != nil { + return m.BlocksmithPublicKey + } + return nil +} + +func (m *SkippedBlocksmith) GetPOPChange() int64 { + if m != nil { + return m.POPChange + } + return 0 +} + +func (m *SkippedBlocksmith) GetBlockHeight() int64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *SkippedBlocksmith) GetBlocksmithIndex() int32 { + if m != nil { + return m.BlocksmithIndex + } + return 0 +} + +func init() { + proto.RegisterType((*SkippedBlocksmith)(nil), "model.SkippedBlocksmith") +} + +func init() { proto.RegisterFile("model/skippedBlocksmith.proto", fileDescriptor_1c20326cefe017aa) } + +var fileDescriptor_1c20326cefe017aa = []byte{ + // 197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcd, 0xcd, 0x4f, 0x49, + 0xcd, 0xd1, 0x2f, 0xce, 0xce, 0x2c, 0x28, 0x48, 0x4d, 0x71, 0xca, 0xc9, 0x4f, 0xce, 0x2e, 0xce, + 0xcd, 0x2c, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x4b, 0x2b, 0x6d, 0x67, + 0xe4, 0x12, 0x0c, 0x46, 0x57, 0x22, 0x64, 0xc0, 0x25, 0x8c, 0xe0, 0x05, 0x94, 0x26, 0xe5, 0x64, + 0x26, 0x7b, 0xa7, 0x56, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x61, 0x93, 0x12, 0x52, 0xe0, + 0xe2, 0x0c, 0xf0, 0x0f, 0x70, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0x95, 0x60, 0x52, 0x60, 0xd4, 0x60, + 0x76, 0x62, 0x32, 0x60, 0x0c, 0x42, 0x08, 0x0a, 0xa9, 0x70, 0x71, 0x83, 0x35, 0x7a, 0xa4, 0x66, + 0xa6, 0x67, 0x94, 0x48, 0x30, 0xc3, 0xd5, 0x20, 0x0b, 0x0b, 0x69, 0x70, 0xf1, 0x23, 0x8c, 0xf7, + 0xcc, 0x4b, 0x49, 0xad, 0x90, 0x60, 0x51, 0x60, 0xd4, 0x60, 0x0d, 0x42, 0x17, 0x76, 0xd2, 0x8a, + 0xd2, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xaf, 0xca, 0xcf, 0x4f, + 0x4a, 0x86, 0x90, 0xba, 0xc9, 0xf9, 0x45, 0xa9, 0xfa, 0xc9, 0xf9, 0xb9, 0xb9, 0xf9, 0x79, 0xfa, + 0x60, 0x5f, 0x26, 0xb1, 0x81, 0xfd, 0x6c, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x96, 0xcd, 0x1a, + 0x23, 0x14, 0x01, 0x00, 0x00, +} From 1af6986e62b1fb293cbc4723e598d3761349f67f Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 14:51:03 +0800 Subject: [PATCH 04/26] #395 checkpoint: add skipped blocksmith query --- cmd/block/blockGenerator.go | 1 + cmd/genesisblock/genesisGenerator.go | 1 + common/query/skippedBlocksmithQuery.go | 88 ++++++++++++++++++++++++++ core/service/blockCoreService.go | 25 +++++++- main.go | 1 + 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/cmd/block/blockGenerator.go b/cmd/block/blockGenerator.go index 62ba459bc..40821277d 100644 --- a/cmd/block/blockGenerator.go +++ b/cmd/block/blockGenerator.go @@ -136,6 +136,7 @@ func initialize( query.NewTransactionQuery(chainType), query.NewMerkleTreeQuery(), query.NewPublishedReceiptQuery(), + query.NewSkippedBlocksmithQuery(), crypto.NewSignature(), mempoolService, receiptService, diff --git a/cmd/genesisblock/genesisGenerator.go b/cmd/genesisblock/genesisGenerator.go index ab5c852bc..92b0df906 100644 --- a/cmd/genesisblock/genesisGenerator.go +++ b/cmd/genesisblock/genesisGenerator.go @@ -316,6 +316,7 @@ func getGenesisBlockID(genesisEntries []genesisEntry) int64 { nil, nil, nil, + nil, &transaction.TypeSwitcher{}, nil, nil, diff --git a/common/query/skippedBlocksmithQuery.go b/common/query/skippedBlocksmithQuery.go index af207a985..39450ac50 100644 --- a/common/query/skippedBlocksmithQuery.go +++ b/common/query/skippedBlocksmithQuery.go @@ -1,11 +1,21 @@ package query import ( + "database/sql" + "fmt" + "strings" + "github.com/zoobc/zoobc-core/common/chaintype" + "github.com/zoobc/zoobc-core/common/model" ) type ( SkippedBlocksmithQueryInterface interface { + GetSkippedBlocksmithsByBlockHeight(blockHeight uint32) (qStr string) + InsertSkippedBlocksmith(skippedBlocksmith *model.SkippedBlocksmith) (qStr string, args []interface{}) + ExtractModel(skippedBlocksmith *model.SkippedBlocksmith) []interface{} + BuildModel(skippedBlocksmiths []*model.SkippedBlocksmith, rows *sql.Rows) ([]*model.SkippedBlocksmith, error) + Scan(skippedBlocksmith *model.SkippedBlocksmith, rows *sql.Row) error } SkippedBlocksmithQuery struct { @@ -14,3 +24,81 @@ type ( ChainType chaintype.ChainType } ) + +// NewSkippedBlocksmithQuery will create a new SkippedBlocksmithQuery instance +func NewSkippedBlocksmithQuery() *SkippedBlocksmithQuery { + return &SkippedBlocksmithQuery{ + Fields: []string{ + "blocksmith_public_key", + "pop_change", + "block_height", + "blocksmith_index", + }, + TableName: "skipped_blocksmith", + } +} + +func (sbq *SkippedBlocksmithQuery) getTableName() string { + return sbq.TableName +} + +func (sbq *SkippedBlocksmithQuery) GetSkippedBlocksmithsByBlockHeight(blockHeight uint32) string { + return fmt.Sprintf( + "SELECT %s FROM %s WHERE block_height = %d", + blockHeight, + ) +} + +func (sbq *SkippedBlocksmithQuery) InsertSkippedBlocksmith( + skippedBlocksmith *model.SkippedBlocksmith, +) (qStr string, args []interface{}) { + return fmt.Sprintf( + "INSERT INTO %s (%s) VALUES(%s)", + sbq.getTableName(), + strings.Join(sbq.Fields, ", "), + fmt.Sprintf("? %s", strings.Repeat(", ?", len(sbq.Fields)-1)), + ), + sbq.ExtractModel(skippedBlocksmith) +} + +func (*SkippedBlocksmithQuery) ExtractModel(skippedModel *model.SkippedBlocksmith) []interface{} { + return []interface{}{ + &skippedModel.BlocksmithPublicKey, + &skippedModel.POPChange, + &skippedModel.BlockHeight, + &skippedModel.BlocksmithIndex, + } +} + +func (*SkippedBlocksmithQuery) BuildModel( + skippedBlocksmiths []*model.SkippedBlocksmith, + rows *sql.Rows, +) ([]*model.SkippedBlocksmith, error) { + for rows.Next() { + var ( + skippedBlocksmith model.SkippedBlocksmith + err error + ) + err = rows.Scan( + &skippedBlocksmith.BlocksmithPublicKey, + &skippedBlocksmith.POPChange, + &skippedBlocksmith.BlockHeight, + &skippedBlocksmith.BlocksmithIndex, + ) + if err != nil { + return nil, err + } + skippedBlocksmiths = append(skippedBlocksmiths, &skippedBlocksmith) + } + return skippedBlocksmiths, nil +} + +func (*SkippedBlocksmithQuery) Scan(skippedBlocksmith *model.SkippedBlocksmith, row *sql.Row) error { + err := row.Scan( + &skippedBlocksmith.BlocksmithPublicKey, + &skippedBlocksmith.POPChange, + &skippedBlocksmith.BlockHeight, + &skippedBlocksmith.BlocksmithIndex, + ) + return err +} diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index ff11ad400..8a2f499c4 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -88,6 +88,7 @@ type ( TransactionQuery query.TransactionQueryInterface MerkleTreeQuery query.MerkleTreeQueryInterface PublishedReceiptQuery query.PublishedReceiptQueryInterface + SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface Signature crypto.SignatureInterface MempoolService MempoolServiceInterface ReceiptService ReceiptServiceInterface @@ -111,6 +112,7 @@ func NewBlockService( transactionQuery query.TransactionQueryInterface, merkleTreeQuery query.MerkleTreeQueryInterface, publishedReceiptQuery query.PublishedReceiptQueryInterface, + skippedBlocksmithQuery query.SkippedBlocksmithQueryInterface, signature crypto.SignatureInterface, mempoolService MempoolServiceInterface, receiptService ReceiptServiceInterface, @@ -132,6 +134,7 @@ func NewBlockService( TransactionQuery: transactionQuery, MerkleTreeQuery: merkleTreeQuery, PublishedReceiptQuery: publishedReceiptQuery, + SkippedBlocksmithQuery: skippedBlocksmithQuery, Signature: signature, MempoolService: mempoolService, ReceiptService: receiptService, @@ -538,7 +541,27 @@ func (bs *BlockService) updateNodeRegistry(block *model.Block) error { } func (bs *BlockService) updatePopScore(popScore int64, block *model.Block) error { - var blocksmithNode model.NodeRegistration + var ( + blocksmithNode model.NodeRegistration + blocksmithIndex int + ) + for i, bsm := range *bs.SortedBlocksmiths { + if reflect.DeepEqual(bsm.NodePublicKey, bsm.NodePublicKey) { + blocksmithIndex = i + } + } + + // punish the skipped (index earlier than current blocksmith) blocksmith + for _, bsm := range (*bs.SortedBlocksmiths)[:blocksmithIndex] { + qStr, args := bs.SkippedBlocksmithQuery.InsertSkippedBlocksmith( + &model.SkippedBlocksmith{ + BlocksmithPublicKey: nil, + POPChange: 0, + BlockHeight: block.Height, + BlocksmithIndex: 0, + }, + ) + } blocksmithNodeIDQ := bs.NodeRegistrationQuery.GetNodeRegistrationByNodePublicKey() row := bs.QueryExecutor.ExecuteSelectRow(blocksmithNodeIDQ, block.BlocksmithPublicKey) err := bs.NodeRegistrationQuery.Scan(&blocksmithNode, row) diff --git a/main.go b/main.go index 0227ee4e6..f9bf6d641 100644 --- a/main.go +++ b/main.go @@ -335,6 +335,7 @@ func startMainchain(mainchainSyncChannel chan bool) { query.NewTransactionQuery(mainchain), query.NewMerkleTreeQuery(), query.NewPublishedReceiptQuery(), + query.NewSkippedBlocksmithQuery(), crypto.NewSignature(), mempoolService, receiptService, From 9e8cd17b37a1a0cdeabaecbf09e0c53a5afb250f Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 14:53:10 +0800 Subject: [PATCH 05/26] #395 update block height to use uint32 --- common/model/skippedBlocksmith.pb.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/common/model/skippedBlocksmith.pb.go b/common/model/skippedBlocksmith.pb.go index 1e85f0181..854180aeb 100644 --- a/common/model/skippedBlocksmith.pb.go +++ b/common/model/skippedBlocksmith.pb.go @@ -23,7 +23,7 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type SkippedBlocksmith struct { BlocksmithPublicKey []byte `protobuf:"bytes,1,opt,name=BlocksmithPublicKey,proto3" json:"BlocksmithPublicKey,omitempty"` POPChange int64 `protobuf:"varint,2,opt,name=POPChange,proto3" json:"POPChange,omitempty"` - BlockHeight int64 `protobuf:"varint,3,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"` + BlockHeight uint32 `protobuf:"varint,3,opt,name=BlockHeight,proto3" json:"BlockHeight,omitempty"` BlocksmithIndex int32 `protobuf:"varint,4,opt,name=BlocksmithIndex,proto3" json:"BlocksmithIndex,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` @@ -69,7 +69,7 @@ func (m *SkippedBlocksmith) GetPOPChange() int64 { return 0 } -func (m *SkippedBlocksmith) GetBlockHeight() int64 { +func (m *SkippedBlocksmith) GetBlockHeight() uint32 { if m != nil { return m.BlockHeight } @@ -90,18 +90,18 @@ func init() { func init() { proto.RegisterFile("model/skippedBlocksmith.proto", fileDescriptor_1c20326cefe017aa) } var fileDescriptor_1c20326cefe017aa = []byte{ - // 197 bytes of a gzipped FileDescriptorProto + // 200 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0xcd, 0xcd, 0x4f, 0x49, 0xcd, 0xd1, 0x2f, 0xce, 0xce, 0x2c, 0x28, 0x48, 0x4d, 0x71, 0xca, 0xc9, 0x4f, 0xce, 0x2e, 0xce, - 0xcd, 0x2c, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x4b, 0x2b, 0x6d, 0x67, + 0xcd, 0x2c, 0xc9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x4b, 0x2b, 0x6d, 0x66, 0xe4, 0x12, 0x0c, 0x46, 0x57, 0x22, 0x64, 0xc0, 0x25, 0x8c, 0xe0, 0x05, 0x94, 0x26, 0xe5, 0x64, 0x26, 0x7b, 0xa7, 0x56, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04, 0x61, 0x93, 0x12, 0x52, 0xe0, 0xe2, 0x0c, 0xf0, 0x0f, 0x70, 0xce, 0x48, 0xcc, 0x4b, 0x4f, 0x95, 0x60, 0x52, 0x60, 0xd4, 0x60, - 0x76, 0x62, 0x32, 0x60, 0x0c, 0x42, 0x08, 0x0a, 0xa9, 0x70, 0x71, 0x83, 0x35, 0x7a, 0xa4, 0x66, - 0xa6, 0x67, 0x94, 0x48, 0x30, 0xc3, 0xd5, 0x20, 0x0b, 0x0b, 0x69, 0x70, 0xf1, 0x23, 0x8c, 0xf7, - 0xcc, 0x4b, 0x49, 0xad, 0x90, 0x60, 0x51, 0x60, 0xd4, 0x60, 0x0d, 0x42, 0x17, 0x76, 0xd2, 0x8a, - 0xd2, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xaf, 0xca, 0xcf, 0x4f, - 0x4a, 0x86, 0x90, 0xba, 0xc9, 0xf9, 0x45, 0xa9, 0xfa, 0xc9, 0xf9, 0xb9, 0xb9, 0xf9, 0x79, 0xfa, - 0x60, 0x5f, 0x26, 0xb1, 0x81, 0xfd, 0x6c, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x96, 0xcd, 0x1a, - 0x23, 0x14, 0x01, 0x00, 0x00, + 0x76, 0x62, 0x32, 0x60, 0x0c, 0x42, 0x08, 0x0a, 0x29, 0x70, 0x71, 0x83, 0x35, 0x7a, 0xa4, 0x66, + 0xa6, 0x67, 0x94, 0x48, 0x30, 0x2b, 0x30, 0x6a, 0xf0, 0x06, 0x21, 0x0b, 0x09, 0x69, 0x70, 0xf1, + 0x23, 0x8c, 0xf6, 0xcc, 0x4b, 0x49, 0xad, 0x90, 0x60, 0x51, 0x60, 0xd4, 0x60, 0x0d, 0x42, 0x17, + 0x76, 0xd2, 0x8a, 0xd2, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xaf, + 0xca, 0xcf, 0x4f, 0x4a, 0x86, 0x90, 0xba, 0xc9, 0xf9, 0x45, 0xa9, 0xfa, 0xc9, 0xf9, 0xb9, 0xb9, + 0xf9, 0x79, 0xfa, 0x60, 0x1f, 0x26, 0xb1, 0x81, 0xfd, 0x6b, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x02, 0x1f, 0x85, 0x10, 0x01, 0x00, 0x00, } From 3507d3a1bfeaaf68c8a2de4587eea5fb5cb59f24 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 17:07:34 +0800 Subject: [PATCH 06/26] #395 add punishment score constant --- common/constant/participationScore.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/constant/participationScore.go b/common/constant/participationScore.go index 2777bdcdd..e128ec8e0 100644 --- a/common/constant/participationScore.go +++ b/common/constant/participationScore.go @@ -10,6 +10,8 @@ const ( UnlinkedReceiptScore float32 = 0.5 // MaxScoreChange the maximum score that node wll get MaxScoreChange = 10 * int64(ScalarReceiptScore) + // punishment amount + ParticipationScorePunishAmount = -1 * MaxScoreChange / 2 // MaxReceipt the maximum receipt will publish in every block MaxReceipt uint32 = 20 // MaxParticipationScore maximum achievable score, this will be important to maintain smithing process so it doesn't From 29439da2d2119c3b6a10d26035c9e1e3bc7f5ecd Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Thu, 31 Oct 2019 17:08:18 +0800 Subject: [PATCH 07/26] #395 add rollback for skipped blocksmith --- common/query/query.go | 1 + common/query/skippedBlocksmithQuery.go | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/common/query/query.go b/common/query/query.go index 0edf47d96..3b5a782c7 100644 --- a/common/query/query.go +++ b/common/query/query.go @@ -18,5 +18,6 @@ func GetDerivedQuery(chainType chaintype.ChainType) []DerivedQuery { NewNodeRegistrationQuery(), NewAccountBalanceQuery(), NewAccountDatasetsQuery(), + NewSkippedBlocksmithQuery(), } } diff --git a/common/query/skippedBlocksmithQuery.go b/common/query/skippedBlocksmithQuery.go index 39450ac50..a93b4bf83 100644 --- a/common/query/skippedBlocksmithQuery.go +++ b/common/query/skippedBlocksmithQuery.go @@ -16,6 +16,7 @@ type ( ExtractModel(skippedBlocksmith *model.SkippedBlocksmith) []interface{} BuildModel(skippedBlocksmiths []*model.SkippedBlocksmith, rows *sql.Rows) ([]*model.SkippedBlocksmith, error) Scan(skippedBlocksmith *model.SkippedBlocksmith, rows *sql.Row) error + Rollback(height uint32) (multiQueries [][]interface{}) } SkippedBlocksmithQuery struct { @@ -45,6 +46,8 @@ func (sbq *SkippedBlocksmithQuery) getTableName() string { func (sbq *SkippedBlocksmithQuery) GetSkippedBlocksmithsByBlockHeight(blockHeight uint32) string { return fmt.Sprintf( "SELECT %s FROM %s WHERE block_height = %d", + strings.Join(sbq.Fields, ", "), + sbq.getTableName(), blockHeight, ) } @@ -102,3 +105,11 @@ func (*SkippedBlocksmithQuery) Scan(skippedBlocksmith *model.SkippedBlocksmith, ) return err } +func (sbq *SkippedBlocksmithQuery) Rollback(height uint32) (multiQueries [][]interface{}) { + return [][]interface{}{ + { + fmt.Sprintf("DELETE FROM %s WHERE block_height > ?", sbq.getTableName()), + height, + }, + } +} From 2f669235e5c4a0609a031953ad524ea7d0290a55 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 13:43:09 +0800 Subject: [PATCH 08/26] #395 handle error in buildblocksmith --- common/query/nodeRegistrationQuery.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/common/query/nodeRegistrationQuery.go b/common/query/nodeRegistrationQuery.go index 282632827..c1e42dc0f 100644 --- a/common/query/nodeRegistrationQuery.go +++ b/common/query/nodeRegistrationQuery.go @@ -26,7 +26,7 @@ type ( GetNodeRegistryAtHeight(height uint32) string ExtractModel(nr *model.NodeRegistration) []interface{} BuildModel(nodeRegistrations []*model.NodeRegistration, rows *sql.Rows) ([]*model.NodeRegistration, error) - BuildBlocksmith(blocksmiths []*model.Blocksmith, rows *sql.Rows) []*model.Blocksmith + BuildBlocksmith(blocksmiths []*model.Blocksmith, rows *sql.Rows) ([]*model.Blocksmith, error) BuildNodeAddress(fullNodeAddress string) *model.NodeAddress ExtractNodeAddress(nodeAddress *model.NodeAddress) string Scan(nr *model.NodeRegistration, row *sql.Row) error @@ -230,21 +230,26 @@ func (nrq *NodeRegistrationQuery) BuildModel( return nodeRegistrations, nil } -func (*NodeRegistrationQuery) BuildBlocksmith(blocksmiths []*model.Blocksmith, rows *sql.Rows) []*model.Blocksmith { +func (*NodeRegistrationQuery) BuildBlocksmith( + blocksmiths []*model.Blocksmith, rows *sql.Rows, +) ([]*model.Blocksmith, error) { for rows.Next() { var ( blocksmith model.Blocksmith scoreString string ) - _ = rows.Scan( + err := rows.Scan( &blocksmith.NodeID, &blocksmith.NodePublicKey, &scoreString, ) + if err != nil { + return nil, err + } blocksmith.Score, _ = new(big.Int).SetString(scoreString, 10) blocksmiths = append(blocksmiths, &blocksmith) } - return blocksmiths + return blocksmiths, nil } // Rollback delete records `WHERE block_height > `height` From 9dea5f8674e4933128e1c6de0a9aed911f54579c Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 13:43:43 +0800 Subject: [PATCH 09/26] #395 fix broken rollback in participation score query; --- common/query/participationScoreQuery.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/query/participationScoreQuery.go b/common/query/participationScoreQuery.go index 03ecb103d..b3845d602 100644 --- a/common/query/participationScoreQuery.go +++ b/common/query/participationScoreQuery.go @@ -175,20 +175,20 @@ func (ps *ParticipationScoreQuery) Rollback(height uint32) (multiQueries [][]int return [][]interface{}{ { fmt.Sprintf("DELETE FROM %s WHERE height > ?", ps.TableName), - []interface{}{height}, + height, }, { fmt.Sprintf(` UPDATE %s SET latest = ? - WHERE height || '_' || id) IN ( - SELECT (MAX(height) || '_' || id) as con + WHERE (height || '_' || node_id) IN ( + SELECT (MAX(height) || '_' || node_id) as con FROM %s - GROUP BY id + GROUP BY node_id )`, ps.TableName, ps.TableName, ), - []interface{}{1}, + 1, }, } } From f7d9fc5953136791704e221492d5ddc68a9b17dd Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 13:44:28 +0800 Subject: [PATCH 10/26] #395 register participation score query to derived query list --- common/query/query.go | 1 + 1 file changed, 1 insertion(+) diff --git a/common/query/query.go b/common/query/query.go index 3b5a782c7..259f54b54 100644 --- a/common/query/query.go +++ b/common/query/query.go @@ -19,5 +19,6 @@ func GetDerivedQuery(chainType chaintype.ChainType) []DerivedQuery { NewAccountBalanceQuery(), NewAccountDatasetsQuery(), NewSkippedBlocksmithQuery(), + NewParticipationScoreQuery(), } } From 79f2ed7000b01550cde57ce76a499c90bdd4a9a8 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 15:00:06 +0800 Subject: [PATCH 11/26] #395 move blocksmith sort to block service --- core/service/blockCoreService.go | 102 ++++++++++++++++++++---------- core/smith/blockchainProcessor.go | 56 ++++++---------- 2 files changed, 88 insertions(+), 70 deletions(-) diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index 8a2f499c4..6b827d911 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -76,6 +76,8 @@ type ( GetParticipationScore(nodePublicKey []byte) (int64, error) GetBlockExtendedInfo(block *model.Block) (*model.BlockExtendedInfo, error) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, error) + SortBlocksmiths(block *model.Block) + GetSortedBlocksmiths() *[]model.Blocksmith } BlockService struct { @@ -440,21 +442,8 @@ func (bs *BlockService) PushBlock(previousBlock, block *model.Block, needLock, b // this is to manage the edge case when the blocksmith array has not been initialized yet: // when start smithing from a block with height > 0, since SortedBlocksmiths are computed after a block is pushed, // for the first block that is pushed, we don't know who are the blocksmith to be rewarded - if len(*bs.SortedBlocksmiths) == 0 { - blocksmiths, err := bs.GetBlocksmiths(block) - if err != nil { - if rollbackErr := bs.QueryExecutor.RollbackTx(); rollbackErr != nil { - bs.Logger.Error(rollbackErr.Error()) - } - return err - } - tmpBlocksmiths := make([]model.Blocksmith, 0) - // copy the nextBlocksmiths pointers array into an array of blocksmiths - for _, blocksmith := range blocksmiths { - tmpBlocksmiths = append(tmpBlocksmiths, *blocksmith) - } - *bs.SortedBlocksmiths = tmpBlocksmiths - } + // sort blocksmiths for current block + bs.SortBlocksmiths(previousBlock) popScore, err := commonUtils.CalculateParticipationScore( uint32(linkedCount), uint32(len(block.GetPublishedReceipts())-linkedCount), @@ -513,6 +502,34 @@ func (bs *BlockService) PushBlock(previousBlock, block *model.Block, needLock, b return nil } +func (bs *BlockService) SortBlocksmiths(block *model.Block) { + // fetch valid blocksmiths + var blocksmiths []model.Blocksmith + nextBlocksmiths, err := bs.GetBlocksmiths(block) + if err != nil { + log.Errorf("SortBlocksmith: %s", err) + return + } + // copy the nextBlocksmiths pointers array into an array of blocksmiths + for _, blocksmith := range nextBlocksmiths { + blocksmiths = append(blocksmiths, *blocksmith) + } + // sort blocksmiths by SmithOrder + sort.SliceStable(blocksmiths, func(i, j int) bool { + bi, bj := blocksmiths[i], blocksmiths[j] + res := bi.SmithOrder.Cmp(bj.SmithOrder) + if res == 0 { + // compare node ID + nodePKI := new(big.Int).SetUint64(uint64(bi.NodeID)) + nodePKJ := new(big.Int).SetUint64(uint64(bj.NodeID)) + res = nodePKI.Cmp(nodePKJ) + } + // ascending sort + return res < 0 + }) + bs.SortedBlocksmiths = &blocksmiths +} + // updateNodeRegistry seelct and admit/expel nodes from node registry func (bs *BlockService) updateNodeRegistry(block *model.Block) error { // select n (= MaxNodeAdmittancePerCycle) queued nodes with the highest locked balance from node registry @@ -542,31 +559,43 @@ func (bs *BlockService) updateNodeRegistry(block *model.Block) error { func (bs *BlockService) updatePopScore(popScore int64, block *model.Block) error { var ( - blocksmithNode model.NodeRegistration - blocksmithIndex int + blocksmithNode model.Blocksmith + blocksmithIndex = -1 + err error ) for i, bsm := range *bs.SortedBlocksmiths { - if reflect.DeepEqual(bsm.NodePublicKey, bsm.NodePublicKey) { + if reflect.DeepEqual(block.BlocksmithPublicKey, bsm.NodePublicKey) { blocksmithIndex = i + blocksmithNode = bsm + break } } - + if blocksmithIndex < 0 { + return blocker.NewBlocker(blocker.BlockErr, "BlocksmithNotInBlocksmithList") + } // punish the skipped (index earlier than current blocksmith) blocksmith - for _, bsm := range (*bs.SortedBlocksmiths)[:blocksmithIndex] { + for i, bsm := range (*bs.SortedBlocksmiths)[:blocksmithIndex] { + skippedBlocksmith := &model.SkippedBlocksmith{ + BlocksmithPublicKey: bsm.NodePublicKey, + POPChange: constant.ParticipationScorePunishAmount, + BlockHeight: block.Height, + BlocksmithIndex: int32(i), + } + // store to skipped_blocksmith table qStr, args := bs.SkippedBlocksmithQuery.InsertSkippedBlocksmith( - &model.SkippedBlocksmith{ - BlocksmithPublicKey: nil, - POPChange: 0, - BlockHeight: block.Height, - BlocksmithIndex: 0, - }, + skippedBlocksmith, ) - } - blocksmithNodeIDQ := bs.NodeRegistrationQuery.GetNodeRegistrationByNodePublicKey() - row := bs.QueryExecutor.ExecuteSelectRow(blocksmithNodeIDQ, block.BlocksmithPublicKey) - err := bs.NodeRegistrationQuery.Scan(&blocksmithNode, row) - if err != nil { - return err + err = bs.QueryExecutor.ExecuteTransaction(qStr, args...) + if err != nil { + return err + } + // punish score + addParticipationScoreQueries := bs.ParticipationScoreQuery.AddParticipationScore( + bsm.NodeID, constant.ParticipationScorePunishAmount, block.Height) + err = bs.QueryExecutor.ExecuteTransactions(addParticipationScoreQueries) + if err != nil { + return err + } } addParticipationScoreQueries := bs.ParticipationScoreQuery.AddParticipationScore( blocksmithNode.NodeID, popScore, block.Height) @@ -1266,7 +1295,10 @@ func (bs *BlockService) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, return nil, err } defer rows.Close() - activeBlocksmiths = bs.NodeRegistrationQuery.BuildBlocksmith(activeBlocksmiths, rows) + activeBlocksmiths, err = bs.NodeRegistrationQuery.BuildBlocksmith(activeBlocksmiths, rows) + if err != nil { + return nil, err + } // add smithorder and nodeorder to be used to select blocksmith and coinbase rewards blockSeed := new(big.Int).SetBytes(block.BlockSeed) for _, blocksmith := range activeBlocksmiths { @@ -1277,3 +1309,7 @@ func (bs *BlockService) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, } return blocksmiths, nil } + +func (bs *BlockService) GetSortedBlocksmiths() *[]model.Blocksmith { + return bs.SortedBlocksmiths +} diff --git a/core/smith/blockchainProcessor.go b/core/smith/blockchainProcessor.go index 4a87ccff8..de6b4a78f 100644 --- a/core/smith/blockchainProcessor.go +++ b/core/smith/blockchainProcessor.go @@ -3,15 +3,13 @@ package smith import ( "math" "math/big" - "sort" + "reflect" "time" "github.com/zoobc/zoobc-core/common/constant" "github.com/zoobc/zoobc-core/common/blocker" - "github.com/zoobc/zoobc-core/observer" - log "github.com/sirupsen/logrus" "github.com/zoobc/zoobc-core/common/chaintype" @@ -24,7 +22,6 @@ type ( // BlockchainProcessorInterface represents interface for the blockchain processor's implementations BlockchainProcessorInterface interface { CalculateSmith(lastBlock *model.Block, generator *model.Blocksmith) *model.Blocksmith - SortBlocksmith(sortedBlocksmiths *[]model.Blocksmith) observer.Listener StartSmithing() error FakeSmithing(numberOfBlocks int, fromGenesis bool) error } @@ -36,6 +33,7 @@ type ( BlockService service.BlockServiceInterface NodeRegistrationService service.NodeRegistrationServiceInterface LastBlockID int64 + canSmith *bool } ) @@ -150,6 +148,7 @@ func (bp *BlockchainProcessor) FakeSmithing(numberOfBlocks int, fromGenesis bool // StartSmithing start smithing loop func (bp *BlockchainProcessor) StartSmithing() error { + var blocksmithIndex = -1 lastBlock, err := bp.BlockService.GetLastBlock() if err != nil { return blocker.NewBlocker( @@ -158,6 +157,19 @@ func (bp *BlockchainProcessor) StartSmithing() error { smithMax := time.Now().Unix() - bp.Chaintype.GetChainSmithingDelayTime() if lastBlock.GetID() != bp.LastBlockID { bp.LastBlockID = lastBlock.GetID() + bp.BlockService.SortBlocksmiths(lastBlock) + // check if eligible to create block in this round + for i, bs := range *(bp.BlockService.GetSortedBlocksmiths()) { + if reflect.DeepEqual(bs.NodePublicKey, bp.Generator.NodePublicKey) { + blocksmithIndex = i + break + } + } + if blocksmithIndex < 0 { + *(bp.canSmith) = false + return blocker.NewBlocker(blocker.SmithingErr, "BlocksmithNotInBlocksmithList") + } + *(bp.canSmith) = true // if lastBlock.Timestamp > time.Now().Unix()-bp.Chaintype.GetChainSmithingDelayTime()*10 { // TODO: andy-shi88 // pop off last block if has been absent for 10*delay @@ -166,6 +178,9 @@ func (bp *BlockchainProcessor) StartSmithing() error { // caching: only calculate smith time once per new block bp.Generator = bp.CalculateSmith(lastBlock, bp.Generator) } + if !*(bp.canSmith) { + return blocker.NewBlocker(blocker.SmithingErr, "BlocksmithNotInBlocksmithList") + } if bp.Generator.SmithTime > smithMax { return nil } @@ -200,36 +215,3 @@ func (bp *BlockchainProcessor) StartSmithing() error { } return nil } - -func (bp *BlockchainProcessor) SortBlocksmith(sortedBlocksmiths *[]model.Blocksmith) observer.Listener { - return observer.Listener{ - OnNotify: func(block interface{}, args interface{}) { - // fetch valid blocksmiths - lastBlock := block.(*model.Block) - var blocksmiths []model.Blocksmith - nextBlocksmiths, err := bp.BlockService.GetBlocksmiths(lastBlock) - if err != nil { - log.Errorf("SortBlocksmith: %s", err) - return - } - // copy the nextBlocksmiths pointers array into an array of blocksmiths - for _, blocksmith := range nextBlocksmiths { - blocksmiths = append(blocksmiths, *blocksmith) - } - // sort blocksmiths by SmithOrder - sort.SliceStable(blocksmiths, func(i, j int) bool { - bi, bj := blocksmiths[i], blocksmiths[j] - res := bi.SmithOrder.Cmp(bj.SmithOrder) - if res == 0 { - // compare node ID - nodePKI := new(big.Int).SetUint64(uint64(bi.NodeID)) - nodePKJ := new(big.Int).SetUint64(uint64(bj.NodeID)) - res = nodePKI.Cmp(nodePKJ) - } - // ascending sort - return res < 0 - }) - *sortedBlocksmiths = blocksmiths - }, - } -} From 49e1f28c64746062210eec76c0111ebb59804f4b Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 15:01:05 +0800 Subject: [PATCH 12/26] #395 remove sort blocksmith listener --- main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/main.go b/main.go index f9bf6d641..c79ad1aac 100644 --- a/main.go +++ b/main.go @@ -251,7 +251,6 @@ func initObserverListeners() { // init observer listeners // broadcast block will be different than other listener implementation, since there are few exception condition observerInstance.AddListener(observer.BroadcastBlock, p2pServiceInstance.SendBlockListener()) - observerInstance.AddListener(observer.BlockPushed, mainchainProcessor.SortBlocksmith(&sortedBlocksmiths)) observerInstance.AddListener(observer.BlockPushed, peerExplorer.PeerExplorerListener()) observerInstance.AddListener(observer.TransactionAdded, p2pServiceInstance.SendTransactionListener()) } From 26bfa7ef27a466d202d8317fb277fd084acb95a9 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 15:56:29 +0800 Subject: [PATCH 13/26] #395 use value instead of pointer --- core/smith/blockchainProcessor.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/smith/blockchainProcessor.go b/core/smith/blockchainProcessor.go index de6b4a78f..977c40e75 100644 --- a/core/smith/blockchainProcessor.go +++ b/core/smith/blockchainProcessor.go @@ -33,7 +33,7 @@ type ( BlockService service.BlockServiceInterface NodeRegistrationService service.NodeRegistrationServiceInterface LastBlockID int64 - canSmith *bool + canSmith bool } ) @@ -166,10 +166,10 @@ func (bp *BlockchainProcessor) StartSmithing() error { } } if blocksmithIndex < 0 { - *(bp.canSmith) = false + bp.canSmith = false return blocker.NewBlocker(blocker.SmithingErr, "BlocksmithNotInBlocksmithList") } - *(bp.canSmith) = true + bp.canSmith = true // if lastBlock.Timestamp > time.Now().Unix()-bp.Chaintype.GetChainSmithingDelayTime()*10 { // TODO: andy-shi88 // pop off last block if has been absent for 10*delay @@ -178,7 +178,7 @@ func (bp *BlockchainProcessor) StartSmithing() error { // caching: only calculate smith time once per new block bp.Generator = bp.CalculateSmith(lastBlock, bp.Generator) } - if !*(bp.canSmith) { + if !bp.canSmith { return blocker.NewBlocker(blocker.SmithingErr, "BlocksmithNotInBlocksmithList") } if bp.Generator.SmithTime > smithMax { From 0dc9afac7197fca9b9f64bf2cf08a90a5e055ca8 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 17:58:20 +0800 Subject: [PATCH 14/26] #395 fix query test --- common/query/query_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/query/query_test.go b/common/query/query_test.go index 91de6fd0b..895c61541 100644 --- a/common/query/query_test.go +++ b/common/query/query_test.go @@ -25,6 +25,8 @@ func TestGetDerivedQuery(t *testing.T) { NewNodeRegistrationQuery(), NewAccountBalanceQuery(), NewAccountDatasetsQuery(), + NewSkippedBlocksmithQuery(), + NewParticipationScoreQuery(), }, }, } From 1f135e7eafdd8396ce0e1336de3af283cc42eaf8 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 17:58:50 +0800 Subject: [PATCH 15/26] #395 fix blockchainsync test --- core/blockchainsync/downloadBlockchain_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/blockchainsync/downloadBlockchain_test.go b/core/blockchainsync/downloadBlockchain_test.go index 53ba8e2e9..b3bf7a603 100644 --- a/core/blockchainsync/downloadBlockchain_test.go +++ b/core/blockchainsync/downloadBlockchain_test.go @@ -297,6 +297,7 @@ func TestGetNextBlocks(t *testing.T) { nil, nil, nil, + nil, &[]model.Blocksmith{}, nil, ) From 37902744b5a8ff531297951dfa8b4bf5f3dd704d Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Fri, 1 Nov 2019 17:59:31 +0800 Subject: [PATCH 16/26] #395 fix blockcoreservice test --- core/service/blockCoreService_test.go | 37 +++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/core/service/blockCoreService_test.go b/core/service/blockCoreService_test.go index 91a7728c2..1395488e0 100644 --- a/core/service/blockCoreService_test.go +++ b/core/service/blockCoreService_test.go @@ -385,6 +385,18 @@ func (*mockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...inter mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ "ID", "FeePerByte", "ArrivalTimestamp", "TransactionBytes", "SenderAccountAddress", "RecipientAccountAddress", })) + case "SELECT nr.id AS nodeID, nr.node_public_key AS node_public_key, ps.score AS participation_score FROM node_registry " + + "AS nr INNER JOIN participation_score AS ps ON nr.id = ps.node_id WHERE nr.registration_status = 0 AND nr.latest " + + "= 1 AND ps.score > 0 AND ps.latest = 1": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "node_public_key", "score", + }).AddRow( + (*mockBlocksmiths)[0].NodePublicKey, + (*mockBlocksmiths)[0].Score, + ).AddRow( + (*mockBlocksmiths)[1].NodePublicKey, + (*mockBlocksmiths)[1].Score, + )) } rows, _ := db.Query(qe) return rows, nil @@ -423,6 +435,7 @@ func TestNewBlockService(t *testing.T) { transactionQuery query.TransactionQueryInterface merkleTreeQuery query.MerkleTreeQueryInterface publishedReceiptQuery query.PublishedReceiptQueryInterface + skippedBlocksmithQuery query.SkippedBlocksmithQueryInterface signature crypto.SignatureInterface mempoolService MempoolServiceInterface receiptService ReceiptServiceInterface @@ -465,6 +478,7 @@ func TestNewBlockService(t *testing.T) { tt.args.transactionQuery, tt.args.merkleTreeQuery, tt.args.publishedReceiptQuery, + tt.args.skippedBlocksmithQuery, tt.args.signature, tt.args.mempoolService, tt.args.receiptService, @@ -820,17 +834,20 @@ func TestBlockService_VerifySeed(t *testing.T) { } } +var mockBlocksmiths = &[]model.Blocksmith{ + { + NodePublicKey: bcsNodePubKey1, + NodeID: 2, + NodeOrder: new(big.Int).SetInt64(1000), + }, + { + NodePublicKey: bcsNodePubKey2, + NodeID: 3, + NodeOrder: new(big.Int).SetInt64(2000), + }, +} + func TestBlockService_PushBlock(t *testing.T) { - var mockBlocksmiths = &[]model.Blocksmith{ - { - NodeID: 2, - NodeOrder: new(big.Int).SetInt64(1000), - }, - { - NodeID: 3, - NodeOrder: new(big.Int).SetInt64(2000), - }, - } type fields struct { Chaintype chaintype.ChainType QueryExecutor query.ExecutorInterface From 89051ac2703a6fec6158809ef3d095acc7d44f3e Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 09:47:03 +0800 Subject: [PATCH 17/26] #395 fix tests --- core/service/blockCoreService.go | 1 + core/smith/blockchainProcessor_test.go | 249 ------------------------- 2 files changed, 1 insertion(+), 249 deletions(-) diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index 698c72805..82cf73a77 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -1249,6 +1249,7 @@ func (*BlockService) GetCoinbase() int64 { return 50 * constant.OneZBC } +// todo: move this to blocksmith service // GetBlocksmiths select the blocksmiths for a given block and calculate the SmithOrder (for smithing) and NodeOrder (for block rewards) func (bs *BlockService) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, error) { var ( diff --git a/core/smith/blockchainProcessor_test.go b/core/smith/blockchainProcessor_test.go index ffe97fe6d..f2961a28c 100644 --- a/core/smith/blockchainProcessor_test.go +++ b/core/smith/blockchainProcessor_test.go @@ -1,12 +1,10 @@ package smith import ( - "errors" "math/big" "reflect" "testing" - "github.com/zoobc/zoobc-core/common/util" coreUtil "github.com/zoobc/zoobc-core/core/util" "github.com/zoobc/zoobc-core/common/model" @@ -53,15 +51,6 @@ func TestNewBlockchainProcessor(t *testing.T) { } } -type ( - mockBlockService struct { - service.BlockService - } - mockBlockServiceFail struct { - service.BlockService - } -) - var ( blockSeed = new(big.Int).SetUint64(10000000) score1 = new(big.Int).SetInt64(8000) @@ -187,241 +176,3 @@ func getMockBlocksmiths() []*model.Blocksmith { }, } } - -func (*mockBlockService) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, error) { - return getMockBlocksmiths(), nil -} - -func (*mockBlockServiceFail) GetBlocksmiths(block *model.Block) ([]*model.Blocksmith, error) { - return nil, errors.New("mockedError") -} - -func TestBlockchainProcessor_SortBlocksmith_01(t *testing.T) { - t.Run("SortBlocksmith_01:success", func(t *testing.T) { - var sortedBlocksmiths []model.Blocksmith - bProcessor := NewBlockchainProcessor( - &chaintype.MainChain{}, - &model.Blocksmith{ - NodeID: 0, - NodePublicKey: nil, - Score: nil, - SmithTime: 0, - BlockSeed: nil, - SecretPhrase: "", - Deadline: 0, - }, - &mockBlockService{}, - nil, - ) - listener := bProcessor.SortBlocksmith(&sortedBlocksmiths) - listener.OnNotify(&model.Block{}, &chaintype.MainChain{}) - for i, s := range sortedBlocksmiths { - switch i { - case 0: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[8]) { - t.Error("invalid sort") - } - case 1: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[1]) { - t.Error("invalid sort") - } - case 2: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[2]) { - t.Error("invalid sort") - } - case 3: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[0]) { - t.Error("invalid sort") - } - case 4: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[4]) { - t.Error("invalid sort") - } - case 5: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[3]) { - t.Error("invalid sort") - } - case 6: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[7]) { - t.Error("invalid sort") - } - case 7: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[6]) { - t.Error("invalid sort") - } - case 8: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[5]) { - t.Error("invalid sort") - } - } - } - }) -} - -func TestBlockchainProcessor_SortBlocksmith_02(t *testing.T) { - t.Run("SortBlocksmith_02:success", func(t *testing.T) { - var sortedBlocksmiths []model.Blocksmith - bProcessor := NewBlockchainProcessor( - &chaintype.MainChain{}, - &model.Blocksmith{ - NodeID: 0, - NodePublicKey: nil, - Score: nil, - SmithTime: 0, - BlockSeed: nil, - SecretPhrase: "", - Deadline: 0, - }, - &mockBlockService{}, - nil, - ) - listener := bProcessor.SortBlocksmith(&sortedBlocksmiths) - listener.OnNotify(&model.Block{}, &chaintype.MainChain{}) - // sort with different seed - blockSeed = new(big.Int).SetUint64(999335345294492) - listener.OnNotify(&model.Block{}, &chaintype.MainChain{}) - for i, s := range sortedBlocksmiths { - switch i { - case 0: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[8]) { - t.Error("invalid sort") - } - case 1: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[1]) { - t.Error("invalid sort") - } - case 2: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[2]) { - t.Error("invalid sort") - } - case 3: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[0]) { - t.Error("invalid sort") - } - case 4: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[4]) { - t.Error("invalid sort") - } - case 5: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[3]) { - t.Error("invalid sort") - } - case 6: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[7]) { - t.Error("invalid sort") - } - case 7: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[6]) { - t.Error("invalid sort") - } - case 8: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[5]) { - t.Error("invalid sort") - } - } - } - }) -} -func TestBlockchainProcessor_SortBlocksmith_03(t *testing.T) { - t.Run("SortBlocksmith_03:success", func(t *testing.T) { - var sortedBlocksmiths []model.Blocksmith - bProcessor := NewBlockchainProcessor( - &chaintype.MainChain{}, - &model.Blocksmith{ - NodeID: 0, - NodePublicKey: nil, - Score: nil, - SmithTime: 0, - BlockSeed: nil, - SecretPhrase: "", - Deadline: 0, - }, - &mockBlockService{}, - nil, - ) - listener := bProcessor.SortBlocksmith(&sortedBlocksmiths) - listener.OnNotify(&model.Block{}, &chaintype.MainChain{}) - // sort randomizing node id between blocksmiths - nodeID1 = int64(273458748935) - nodeID2 = int64(4458748935) - nodeID3 = int64(2233432423) - nodeID4 = int64(89543289543289) - nodeID5 = int64(4378432789435897) - nodeID6 = int64(2985699456643) - nodeID7 = int64(1032547846084) - nodeID8 = int64(69023893290543834) - nodeID9 = int64(409580358990) - - listener.OnNotify(&model.Block{}, &chaintype.MainChain{}) - for i, s := range sortedBlocksmiths { - switch i { - case 0: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[8]) { - t.Error("invalid sort") - } - case 1: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[1]) { - t.Error("invalid sort") - } - case 2: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[3]) { - t.Error("invalid sort") - } - case 3: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[4]) { - t.Error("invalid sort") - } - case 4: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[2]) { - t.Error("invalid sort") - } - case 5: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[0]) { - t.Error("invalid sort") - } - case 6: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[6]) { - t.Error("invalid sort") - } - case 7: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[7]) { - t.Error("invalid sort") - } - case 8: - if !reflect.DeepEqual(s, *getMockBlocksmiths()[5]) { - t.Error("invalid sort") - } - } - } - }) -} - -func TestBlockchainProcessor_SortBlocksmith_fail(t *testing.T) { - t.Run("SortBlocksmith:getNodeFail", func(t *testing.T) { - var sortedBlocksmiths []model.Blocksmith - bProcessor := NewBlockchainProcessor( - &chaintype.MainChain{}, - &model.Blocksmith{ - NodeID: 0, - NodePublicKey: nil, - Score: nil, - SmithTime: 0, - BlockSeed: nil, - SecretPhrase: "", - Deadline: 0, - }, - &mockBlockServiceFail{}, - nil, - ) - listener := bProcessor.SortBlocksmith(&sortedBlocksmiths) - listener.OnNotify(&model.Block{ - BlockSeed: util.ConvertUint64ToBytes(10000000), - }, &chaintype.MainChain{}) - if len(sortedBlocksmiths) > 0 { - // note: if before there are success sort, the sorted blocksmiths will not be empty - // but stay the same as previous sorted list - t.Error("if get nodes fail, empty list won't be filled") - } - }) - -} From 04e984126d01e50c4d9ac74d765d51c90123bbb6 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 09:48:22 +0800 Subject: [PATCH 18/26] #395 add skipped blocksmith to block extended info --- common/model/block.pb.go | 127 +++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/common/model/block.pb.go b/common/model/block.pb.go index b3ee7f00e..756f8636c 100644 --- a/common/model/block.pb.go +++ b/common/model/block.pb.go @@ -190,14 +190,15 @@ func (m *Block) GetPublishedReceipts() []*PublishedReceipt { // BlockExtendedInfo represent the Block data plus part of block data not to be persisted to database type BlockExtendedInfo struct { - Block *Block `protobuf:"bytes,1,opt,name=Block,proto3" json:"Block,omitempty"` - TotalReceipts int64 `protobuf:"varint,2,opt,name=TotalReceipts,proto3" json:"TotalReceipts,omitempty"` - ReceiptValue int64 `protobuf:"varint,3,opt,name=ReceiptValue,proto3" json:"ReceiptValue,omitempty"` - BlocksmithAccountAddress string `protobuf:"bytes,4,opt,name=BlocksmithAccountAddress,proto3" json:"BlocksmithAccountAddress,omitempty"` - PopChange int64 `protobuf:"varint,5,opt,name=PopChange,proto3" json:"PopChange,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Block *Block `protobuf:"bytes,1,opt,name=Block,proto3" json:"Block,omitempty"` + TotalReceipts int64 `protobuf:"varint,2,opt,name=TotalReceipts,proto3" json:"TotalReceipts,omitempty"` + ReceiptValue int64 `protobuf:"varint,3,opt,name=ReceiptValue,proto3" json:"ReceiptValue,omitempty"` + BlocksmithAccountAddress string `protobuf:"bytes,4,opt,name=BlocksmithAccountAddress,proto3" json:"BlocksmithAccountAddress,omitempty"` + PopChange int64 `protobuf:"varint,5,opt,name=PopChange,proto3" json:"PopChange,omitempty"` + SkippedBlocksmiths []*SkippedBlocksmith `protobuf:"bytes,6,rep,name=SkippedBlocksmiths,proto3" json:"SkippedBlocksmiths,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *BlockExtendedInfo) Reset() { *m = BlockExtendedInfo{} } @@ -260,6 +261,13 @@ func (m *BlockExtendedInfo) GetPopChange() int64 { return 0 } +func (m *BlockExtendedInfo) GetSkippedBlocksmiths() []*SkippedBlocksmith { + if m != nil { + return m.SkippedBlocksmiths + } + return nil +} + // GetBlockRequest create request for single block type GetBlockRequest struct { // Number indicating chaintype @@ -746,55 +754,56 @@ func init() { func init() { proto.RegisterFile("model/block.proto", fileDescriptor_baa78346dbb08dbe) } var fileDescriptor_baa78346dbb08dbe = []byte{ - // 788 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x5f, 0x6b, 0x1b, 0x47, - 0x10, 0xe7, 0xa4, 0xc8, 0xb6, 0x46, 0x52, 0x6c, 0xad, 0x4d, 0xb2, 0x04, 0x13, 0x8e, 0x23, 0x84, - 0xa3, 0xa4, 0xb6, 0x51, 0xa1, 0x85, 0xbc, 0x59, 0x52, 0x9a, 0x88, 0x9a, 0x22, 0x4e, 0x22, 0x0f, - 0x2d, 0x14, 0x56, 0x77, 0x63, 0xdd, 0xb6, 0x77, 0xb7, 0xea, 0xed, 0x5e, 0x88, 0xfa, 0xd0, 0xef, - 0xd0, 0xef, 0xd0, 0xef, 0xd6, 0xaf, 0x51, 0xb4, 0xb7, 0xf7, 0x4f, 0xb1, 0xa8, 0x1f, 0xfa, 0x22, - 0xb4, 0xbf, 0xdf, 0xcc, 0xfc, 0x66, 0x66, 0x67, 0xf6, 0x60, 0x18, 0x8b, 0x00, 0xa3, 0xeb, 0x55, - 0x24, 0xfc, 0xdf, 0xae, 0x36, 0xa9, 0x50, 0x82, 0x74, 0x34, 0xf4, 0xe2, 0x79, 0xce, 0xa8, 0x94, - 0x25, 0x92, 0xf9, 0x8a, 0x8b, 0x24, 0xe7, 0x5f, 0x50, 0xe3, 0xc2, 0x94, 0x1f, 0x7a, 0xe8, 0x23, - 0xdf, 0x28, 0xc3, 0x9c, 0xe7, 0x4c, 0xda, 0x00, 0x2f, 0x73, 0x70, 0x93, 0xad, 0x22, 0x2e, 0x43, - 0x0c, 0x1a, 0x2e, 0xce, 0xdf, 0x1d, 0xe8, 0x8c, 0x77, 0xe2, 0x84, 0x40, 0x6b, 0x36, 0xa5, 0x96, - 0x6d, 0xb9, 0xed, 0x71, 0xeb, 0xc6, 0xf2, 0x5a, 0xb3, 0x29, 0x79, 0x03, 0xc3, 0x79, 0x8a, 0x9f, - 0xb8, 0xc8, 0xa4, 0x36, 0xfa, 0xc0, 0x64, 0x48, 0x5b, 0xb6, 0xe5, 0xf6, 0xbd, 0x2f, 0x09, 0xf2, - 0x0c, 0x8e, 0x3e, 0x20, 0x5f, 0x87, 0x8a, 0xb6, 0x6d, 0xcb, 0x1d, 0x78, 0xe6, 0x44, 0x6c, 0xe8, - 0x2e, 0x79, 0x8c, 0x52, 0xb1, 0x78, 0x43, 0x9f, 0x94, 0x02, 0x15, 0x48, 0x2e, 0xa1, 0xab, 0xc3, - 0x2c, 0x10, 0x03, 0xda, 0xd1, 0xf1, 0x2b, 0x80, 0xbc, 0x86, 0xa7, 0xf9, 0x81, 0xaf, 0x13, 0xa6, - 0xb2, 0x14, 0xe9, 0x91, 0x36, 0xd9, 0x43, 0xc9, 0x08, 0x2e, 0x26, 0x59, 0x9c, 0x45, 0x4c, 0xf1, - 0x4f, 0x38, 0xe5, 0xf7, 0xf7, 0xdc, 0xcf, 0x22, 0xb5, 0xa5, 0xc7, 0xb6, 0xe5, 0x76, 0xbd, 0x07, - 0x39, 0xe2, 0x00, 0x2c, 0x62, 0xae, 0xc2, 0x85, 0xcf, 0x22, 0xa4, 0x27, 0x65, 0x72, 0x35, 0x94, - 0xdc, 0xc0, 0xb9, 0x56, 0x92, 0x3b, 0x68, 0xbe, 0xeb, 0xa3, 0xff, 0x03, 0x6e, 0x69, 0x57, 0x27, - 0xf1, 0x10, 0x45, 0x5e, 0x41, 0x6f, 0x29, 0x14, 0x8b, 0x6e, 0x63, 0x91, 0x25, 0x8a, 0x42, 0x19, - 0xb6, 0x0e, 0x93, 0x97, 0x70, 0xa2, 0x8f, 0xdf, 0x23, 0xd2, 0x5e, 0x69, 0x52, 0x62, 0xc4, 0x85, - 0x81, 0xfe, 0x3f, 0x11, 0x3c, 0x19, 0x33, 0x89, 0xb4, 0x5f, 0x1a, 0x35, 0x09, 0x42, 0xe1, 0xf8, - 0x23, 0xa6, 0x92, 0x8b, 0x84, 0x0e, 0x74, 0xeb, 0x8b, 0x23, 0x79, 0x05, 0x83, 0x39, 0xdb, 0x46, - 0x82, 0x05, 0x77, 0x98, 0xac, 0x55, 0x48, 0x9f, 0x6a, 0xbe, 0x09, 0x12, 0x1b, 0x7a, 0x06, 0xd0, - 0x37, 0x7c, 0xaa, 0x2b, 0xab, 0x43, 0xe4, 0x5b, 0xe8, 0x2f, 0xab, 0x49, 0x94, 0xf4, 0xcc, 0x6e, - 0xbb, 0xbd, 0x11, 0xb9, 0xd2, 0xc3, 0x75, 0x55, 0xa3, 0xbc, 0x86, 0x1d, 0x79, 0x07, 0xc3, 0xf9, - 0xde, 0xe4, 0x49, 0x3a, 0xd4, 0xce, 0xcf, 0x8d, 0xf3, 0x3e, 0xef, 0x7d, 0xe9, 0xe1, 0xfc, 0x63, - 0xc1, 0x50, 0x37, 0xfa, 0xdd, 0x67, 0x85, 0x49, 0x80, 0xc1, 0x2c, 0xb9, 0x17, 0xc4, 0x31, 0xb3, - 0xab, 0xa7, 0xb6, 0x37, 0xea, 0x9b, 0x80, 0x1a, 0xf3, 0xcc, 0x58, 0x17, 0x4d, 0x2c, 0xc5, 0x5b, - 0x7b, 0x4d, 0x2c, 0x08, 0xf2, 0x1a, 0xfa, 0xe6, 0xff, 0x47, 0x16, 0x65, 0xa8, 0x87, 0x38, 0x37, - 0x6c, 0xe0, 0xe4, 0x2d, 0xd0, 0xea, 0xce, 0x6f, 0x7d, 0x7f, 0x77, 0x97, 0xb7, 0x41, 0x90, 0xa2, - 0x94, 0x7a, 0xba, 0xbb, 0xde, 0x41, 0x7e, 0xb7, 0x0a, 0x73, 0xb1, 0x99, 0x84, 0x2c, 0x59, 0xa3, - 0x1e, 0x74, 0xb3, 0x0a, 0x25, 0xe8, 0xfc, 0x0c, 0xa7, 0xef, 0x51, 0xe5, 0x25, 0xe0, 0xef, 0x19, - 0x4a, 0xb5, 0xdb, 0x8e, 0x49, 0xc8, 0x78, 0xb2, 0xdc, 0x6e, 0x50, 0x97, 0xda, 0xf1, 0x2a, 0xc0, - 0xec, 0x6d, 0xab, 0xb1, 0xb7, 0x07, 0x36, 0xd1, 0xf9, 0x05, 0xce, 0x8a, 0xe0, 0xf2, 0x71, 0xd1, - 0x2f, 0xa0, 0x73, 0xc7, 0x63, 0xae, 0xb4, 0xc0, 0xc0, 0xcb, 0x0f, 0x07, 0xe3, 0xff, 0x65, 0xc1, - 0xb0, 0x26, 0x20, 0x37, 0x22, 0x91, 0xf8, 0xdf, 0x0a, 0x13, 0xbd, 0x25, 0x46, 0x41, 0x1f, 0x0e, - 0xbe, 0x25, 0x37, 0x70, 0x94, 0x47, 0xa7, 0x4f, 0xf4, 0x10, 0xd1, 0xfa, 0x9d, 0xd7, 0x87, 0xc3, - 0x33, 0x76, 0xce, 0xaf, 0xf0, 0xec, 0x3d, 0xaa, 0x1f, 0xf1, 0x73, 0x9e, 0xd6, 0x2c, 0x78, 0x64, - 0xe5, 0x97, 0x70, 0x6c, 0x1c, 0x6a, 0xcd, 0x2d, 0xa0, 0xaa, 0x2f, 0xed, 0x5a, 0x5f, 0x9c, 0x11, - 0x9c, 0x55, 0x22, 0xa6, 0xfa, 0x97, 0x70, 0x52, 0x60, 0xd4, 0xb2, 0xdb, 0xc5, 0x96, 0x17, 0x98, - 0x93, 0xc2, 0x45, 0x3d, 0xbf, 0xff, 0x25, 0xbb, 0xba, 0x66, 0xfb, 0x01, 0xcd, 0xb7, 0x00, 0xb9, - 0xd8, 0x94, 0x29, 0x46, 0xde, 0x00, 0x54, 0xf2, 0x3a, 0xc7, 0xfd, 0x5d, 0xaa, 0xf1, 0xce, 0x9f, - 0x70, 0xb6, 0xc0, 0x24, 0x68, 0x4c, 0xe8, 0x63, 0x16, 0xb1, 0x51, 0x4f, 0x6b, 0xbf, 0x1e, 0x17, - 0x4e, 0x77, 0x51, 0x31, 0xad, 0xde, 0xd7, 0xb6, 0x7e, 0x85, 0xf6, 0x61, 0xe7, 0x0e, 0x86, 0x35, - 0x7d, 0xd3, 0xe4, 0xef, 0xa0, 0x3f, 0xae, 0x7d, 0x0f, 0x4d, 0x1e, 0xe7, 0x45, 0x1e, 0x35, 0xca, - 0x6b, 0x18, 0x8e, 0xbf, 0xfa, 0xc9, 0x5d, 0x73, 0x15, 0x66, 0xab, 0x2b, 0x5f, 0xc4, 0xd7, 0x7f, - 0x08, 0xb1, 0xf2, 0xf3, 0xdf, 0xaf, 0x7d, 0x91, 0xe2, 0xb5, 0x2f, 0xe2, 0x58, 0x24, 0xd7, 0x3a, - 0xcc, 0xea, 0x48, 0x7f, 0x32, 0xbf, 0xf9, 0x37, 0x00, 0x00, 0xff, 0xff, 0xba, 0x1f, 0x72, 0x8c, - 0xb4, 0x07, 0x00, 0x00, + // 815 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xdd, 0x6a, 0xe3, 0x46, + 0x14, 0xc6, 0xf6, 0xda, 0x89, 0x8f, 0xed, 0x4d, 0x3c, 0x09, 0xbb, 0xc3, 0x92, 0x2e, 0x42, 0x2c, + 0x8b, 0x28, 0xdb, 0x24, 0xa4, 0xd0, 0xc2, 0xde, 0xc5, 0xce, 0x76, 0x13, 0x1a, 0x8a, 0x91, 0xc3, + 0x5e, 0xb4, 0x50, 0x18, 0x4b, 0x27, 0xd6, 0x74, 0x25, 0x8d, 0xaa, 0x19, 0x2d, 0x49, 0x2f, 0xfa, + 0x0e, 0x7d, 0x87, 0xbe, 0x40, 0xdf, 0xb0, 0x78, 0x34, 0xfa, 0x4d, 0x4c, 0x73, 0xd1, 0x1b, 0xe3, + 0xf9, 0xbe, 0xf3, 0x37, 0xdf, 0x9c, 0x73, 0x04, 0xd3, 0x48, 0xf8, 0x18, 0x9e, 0xac, 0x42, 0xe1, + 0x7d, 0x3e, 0x4e, 0x52, 0xa1, 0x04, 0xe9, 0x6b, 0xe8, 0xd5, 0xcb, 0x9c, 0x51, 0x29, 0x8b, 0x25, + 0xf3, 0x14, 0x17, 0x71, 0xce, 0xbf, 0xa2, 0xc6, 0x85, 0x29, 0x2f, 0x70, 0xd1, 0x43, 0x9e, 0x28, + 0xc3, 0x1c, 0xe4, 0x4c, 0xda, 0x00, 0x8f, 0x72, 0x30, 0xc9, 0x56, 0x21, 0x97, 0x01, 0xfa, 0x4d, + 0x97, 0xaf, 0x72, 0x56, 0x7e, 0xe6, 0x49, 0x82, 0xfe, 0x6c, 0x53, 0x86, 0x8c, 0xb8, 0x0a, 0x72, + 0xda, 0xfe, 0xbb, 0x0f, 0x7d, 0x0d, 0x12, 0x02, 0xdd, 0xab, 0x0b, 0xda, 0xb1, 0x3a, 0x4e, 0x6f, + 0xd6, 0x3d, 0xed, 0xb8, 0xdd, 0xab, 0x0b, 0xf2, 0x0e, 0xa6, 0x8b, 0x14, 0xbf, 0x70, 0x91, 0x49, + 0x6d, 0x74, 0xc9, 0x64, 0x40, 0xbb, 0x56, 0xc7, 0x19, 0xbb, 0x0f, 0x09, 0xf2, 0x02, 0x06, 0x97, + 0xc8, 0xd7, 0x81, 0xa2, 0x3d, 0xab, 0xe3, 0x4c, 0x5c, 0x73, 0x22, 0x16, 0x0c, 0x6f, 0x78, 0x84, + 0x52, 0xb1, 0x28, 0xa1, 0xcf, 0xca, 0x04, 0x15, 0x48, 0x8e, 0x60, 0xa8, 0xc3, 0x2c, 0x11, 0x7d, + 0xda, 0xd7, 0xf1, 0x2b, 0x80, 0xbc, 0x85, 0xe7, 0xf9, 0x81, 0xaf, 0x63, 0xa6, 0xb2, 0x14, 0xe9, + 0x40, 0x9b, 0xb4, 0x50, 0x72, 0x06, 0x87, 0xf3, 0x2c, 0xca, 0x42, 0xa6, 0xf8, 0x17, 0xbc, 0xe0, + 0xb7, 0xb7, 0xdc, 0xcb, 0x42, 0x75, 0x4f, 0x77, 0xac, 0x8e, 0x33, 0x74, 0x1f, 0xe5, 0x88, 0x0d, + 0xb0, 0xdc, 0xc8, 0xb1, 0xf4, 0x58, 0x88, 0x74, 0xb7, 0x2c, 0xae, 0x86, 0x92, 0x53, 0x38, 0xa8, + 0x74, 0x5b, 0x6c, 0x64, 0xf6, 0x7e, 0xc4, 0x7b, 0x3a, 0xd4, 0x45, 0x3c, 0x46, 0x91, 0x37, 0x30, + 0xba, 0x11, 0x8a, 0x85, 0xe7, 0x91, 0xc8, 0x62, 0x45, 0xa1, 0x0c, 0x5b, 0x87, 0xc9, 0x6b, 0xd8, + 0xd5, 0xc7, 0x1f, 0x10, 0xe9, 0xa8, 0x34, 0x29, 0x31, 0xe2, 0xc0, 0x44, 0xff, 0x9f, 0x0b, 0x1e, + 0xcf, 0x98, 0x44, 0x3a, 0x2e, 0x8d, 0x9a, 0x04, 0xa1, 0xb0, 0xf3, 0x09, 0x53, 0xc9, 0x45, 0x4c, + 0x27, 0x5a, 0xfa, 0xe2, 0x48, 0xde, 0xc0, 0x64, 0xc1, 0xee, 0x43, 0xc1, 0xfc, 0x6b, 0x8c, 0xd7, + 0x2a, 0xa0, 0xcf, 0x35, 0xdf, 0x04, 0x89, 0x05, 0x23, 0x03, 0xe8, 0x17, 0xde, 0xd3, 0x37, 0xab, + 0x43, 0xe4, 0x3b, 0x18, 0xdf, 0x54, 0x8d, 0x2a, 0xe9, 0xbe, 0xd5, 0x73, 0x46, 0x67, 0xe4, 0x58, + 0x77, 0xd7, 0x71, 0x8d, 0x72, 0x1b, 0x76, 0xe4, 0x03, 0x4c, 0x17, 0xad, 0xc6, 0x94, 0x74, 0xaa, + 0x9d, 0x5f, 0x1a, 0xe7, 0x36, 0xef, 0x3e, 0xf4, 0xb0, 0xff, 0xe9, 0xc2, 0x54, 0x0b, 0xfd, 0xe1, + 0x4e, 0x61, 0xec, 0xa3, 0x7f, 0x15, 0xdf, 0x0a, 0x62, 0x9b, 0xde, 0xd5, 0x5d, 0x3b, 0x3a, 0x1b, + 0x9b, 0x80, 0x1a, 0x73, 0x4d, 0x5b, 0x17, 0x22, 0x96, 0xc9, 0xbb, 0x2d, 0x11, 0x0b, 0x82, 0xbc, + 0x85, 0xb1, 0xf9, 0xff, 0x89, 0x85, 0x19, 0xea, 0x26, 0xce, 0x0d, 0x1b, 0x38, 0x79, 0x0f, 0xb4, + 0x7a, 0xf3, 0x73, 0xcf, 0xdb, 0xbc, 0xe5, 0xb9, 0xef, 0xa7, 0x28, 0xa5, 0xee, 0xee, 0xa1, 0xbb, + 0x95, 0xdf, 0x8c, 0xc2, 0x42, 0x24, 0xf3, 0x80, 0xc5, 0x6b, 0xd4, 0x8d, 0x6e, 0x46, 0xa1, 0x04, + 0xc9, 0x25, 0x90, 0x65, 0x7b, 0x56, 0x25, 0x1d, 0x68, 0xc5, 0xa8, 0xb9, 0xe0, 0x03, 0x03, 0xf7, + 0x11, 0x1f, 0xfb, 0x17, 0xd8, 0xfb, 0x88, 0x2a, 0x17, 0x03, 0x7f, 0xcf, 0x50, 0xaa, 0xcd, 0x9c, + 0xcd, 0x03, 0xc6, 0xe3, 0x9b, 0xfb, 0x04, 0xb5, 0x68, 0x7d, 0xb7, 0x02, 0xcc, 0x06, 0xe8, 0x36, + 0x36, 0xc0, 0x96, 0x99, 0xb6, 0x7f, 0x85, 0xfd, 0x22, 0xb8, 0x7c, 0x5a, 0xf4, 0x43, 0xe8, 0x5f, + 0xf3, 0x88, 0x2b, 0x9d, 0x60, 0xe2, 0xe6, 0x87, 0xad, 0xf1, 0xff, 0xea, 0xc0, 0xb4, 0x96, 0x40, + 0x26, 0x22, 0x96, 0xf8, 0xdf, 0x19, 0xe6, 0x7a, 0xde, 0x4c, 0x06, 0x7d, 0xd8, 0xba, 0x95, 0x4e, + 0x61, 0x90, 0x47, 0xa7, 0xcf, 0x1a, 0xe2, 0x3e, 0x68, 0x33, 0xd7, 0xd8, 0xd9, 0xbf, 0xc1, 0x8b, + 0x8f, 0xa8, 0x7e, 0xc2, 0xbb, 0xbc, 0xac, 0x2b, 0xff, 0x89, 0x37, 0x3f, 0x82, 0x1d, 0xe3, 0x50, + 0x13, 0xb7, 0x80, 0x2a, 0x5d, 0x7a, 0x35, 0x5d, 0xec, 0x33, 0xd8, 0xaf, 0x92, 0x98, 0xdb, 0xbf, + 0x86, 0xdd, 0x02, 0xa3, 0x1d, 0xab, 0x57, 0xec, 0x8b, 0x02, 0xb3, 0x53, 0x38, 0xac, 0xd7, 0xf7, + 0xbf, 0x54, 0x57, 0xcf, 0xd9, 0x7b, 0x24, 0xe7, 0x7b, 0x80, 0x3c, 0xd9, 0x05, 0x53, 0x8c, 0xbc, + 0x03, 0xa8, 0xd2, 0xeb, 0x1a, 0xdb, 0x53, 0x59, 0xe3, 0xed, 0x3f, 0x61, 0x7f, 0x89, 0xb1, 0xdf, + 0xe8, 0xd0, 0xa7, 0x8c, 0x74, 0xe3, 0x3e, 0xdd, 0xf6, 0x7d, 0x1c, 0xd8, 0xdb, 0x44, 0xc5, 0xb4, + 0xda, 0xd4, 0x3d, 0xbd, 0xcf, 0xda, 0xb0, 0x7d, 0x0d, 0xd3, 0x5a, 0x7e, 0x23, 0xf2, 0xf7, 0x30, + 0x9e, 0xd5, 0x3e, 0xbc, 0xa6, 0x8e, 0x83, 0xa2, 0x8e, 0x1a, 0xe5, 0x36, 0x0c, 0x67, 0x5f, 0xff, + 0xec, 0xac, 0xb9, 0x0a, 0xb2, 0xd5, 0xb1, 0x27, 0xa2, 0x93, 0x3f, 0x84, 0x58, 0x79, 0xf9, 0xef, + 0x37, 0x9e, 0x48, 0xf1, 0xc4, 0x13, 0x51, 0x24, 0xe2, 0x13, 0x1d, 0x66, 0x35, 0xd0, 0x1f, 0xdf, + 0x6f, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x4d, 0xc1, 0x4e, 0x20, 0x1d, 0x08, 0x00, 0x00, } From 7abe84299b68f353181cd75adfacb1da96ab7801 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 11:28:21 +0800 Subject: [PATCH 19/26] #395 fill real data for block extended info --- core/service/blockCoreService.go | 53 +++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index 82cf73a77..463879507 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -1201,8 +1201,12 @@ func (bs *BlockService) GetParticipationScore(nodePublicKey []byte) (int64, erro // GetParticipationScore handle received block from another node func (bs *BlockService) GetBlockExtendedInfo(block *model.Block) (*model.BlockExtendedInfo, error) { var ( - blExt = &model.BlockExtendedInfo{} - err error + blExt = &model.BlockExtendedInfo{} + skippedBlocksmiths []*model.SkippedBlocksmith + publishedReceipts []*model.PublishedReceipt + linkedPublishedReceiptCount uint32 + unLinkedPublishedReceiptCount uint32 + err error ) blExt.Block = block // block extra (computed) info @@ -1214,15 +1218,42 @@ func (bs *BlockService) GetBlockExtendedInfo(block *model.Block) (*model.BlockEx } else { blExt.BlocksmithAccountAddress = constant.MainchainGenesisAccountAddress } - // Total number of receipts at a block height - // STEF: do we need to get all receipts that have reference_block_height <= block.height - blExt.TotalReceipts = 99 - //TODO: from @barton: Receipt value will be the "score" of all the receipts in a block added together - // STEF: how to compute the receipt score? - blExt.ReceiptValue = 99 - // once we have the receipt for this blExt we should be able to calculate this using util.CalculateParticipationScore - blExt.PopChange = -20 - + skippedBlocksmithsQuery := bs.SkippedBlocksmithQuery.GetSkippedBlocksmithsByBlockHeight(block.Height) + skippedBlocksmithsRows, err := bs.QueryExecutor.ExecuteSelect(skippedBlocksmithsQuery, false) + if err != nil { + return nil, err + } + blExt.SkippedBlocksmiths, err = bs.SkippedBlocksmithQuery.BuildModel(skippedBlocksmiths, skippedBlocksmithsRows) + if err != nil { + return nil, err + } + publishedReceiptQ, publishedReceiptArgs := bs.PublishedReceiptQuery.GetPublishedReceiptByBlockHeight(block.Height) + publishedReceiptRows, err := bs.QueryExecutor.ExecuteSelect(publishedReceiptQ, false, publishedReceiptArgs...) + if err != nil { + return nil, err + } + publishedReceipts, err = bs.PublishedReceiptQuery.BuildModel(publishedReceipts, publishedReceiptRows) + if err != nil { + return nil, err + } + blExt.TotalReceipts = int64(len(publishedReceipts)) + for _, pr := range publishedReceipts { + if pr.IntermediateHashes != nil { + linkedPublishedReceiptCount++ + } else { + unLinkedPublishedReceiptCount++ + } + } + blExt.ReceiptValue = commonUtils.GetReceiptValue(linkedPublishedReceiptCount, unLinkedPublishedReceiptCount) + // todo: POPChange value will not be correct until we have scrambled node list at n-th height for `maxReceipt` parameter + blExt.PopChange, err = util.CalculateParticipationScore( + linkedPublishedReceiptCount, + unLinkedPublishedReceiptCount, + uint32(len(publishedReceipts)), + ) + if err != nil { + return nil, err + } return blExt, nil } From 1decc4c7980b58fc141ace57c57405a9bf4ef265 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 11:28:47 +0800 Subject: [PATCH 20/26] #395 add method for getting receipt score --- common/util/ParticipationScore.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/util/ParticipationScore.go b/common/util/ParticipationScore.go index 04e976617..f9a394331 100644 --- a/common/util/ParticipationScore.go +++ b/common/util/ParticipationScore.go @@ -8,10 +8,7 @@ import ( // CalculateParticipationScore to calculate score change of node func CalculateParticipationScore(linkedReceipt, unlinkedReceipt, maxReceipt uint32) (int64, error) { if maxReceipt == 0 { - return 0, blocker.NewBlocker( - blocker.ValidationErr, - "CalculateParticipationScore, maxreceipt cannot be 0", - ) + return constant.MaxScoreChange, nil } if (linkedReceipt + unlinkedReceipt) > maxReceipt { return 0, blocker.NewBlocker( @@ -31,3 +28,10 @@ func CalculateParticipationScore(linkedReceipt, unlinkedReceipt, maxReceipt uint scoreChangeOfANode := ((blockScore - halfMaxBlockScore) * constant.MaxScoreChange) / halfMaxBlockScore return scoreChangeOfANode, nil } + +func GetReceiptValue(linkedReceipt, unlinkedReceipt uint32) int64 { + linkedBlockScore := float32(linkedReceipt) * constant.LinkedReceiptScore * constant.ScalarReceiptScore + unlinkedBlockScore := float32(unlinkedReceipt) * constant.UnlinkedReceiptScore * constant.ScalarReceiptScore + blockScore := int64(linkedBlockScore + unlinkedBlockScore) + return blockScore +} From 4ba442989e2eade323c8ee8ac33be94938a874d2 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 12:22:59 +0800 Subject: [PATCH 21/26] #395 fix test --- common/util/ParticipationScore_test.go | 4 +- core/service/blockCoreService_test.go | 106 ++++++++++++++++++++++--- 2 files changed, 96 insertions(+), 14 deletions(-) diff --git a/common/util/ParticipationScore_test.go b/common/util/ParticipationScore_test.go index 88e0e2bd1..3f038cbdd 100644 --- a/common/util/ParticipationScore_test.go +++ b/common/util/ParticipationScore_test.go @@ -75,8 +75,8 @@ func TestCalculateParticipationScore(t *testing.T) { unlinkedReceipt: 0, maxReceipt: 0, }, - want: 0, - wantErr: true, + want: 1000000000, + wantErr: false, }, } for _, tt := range tests { diff --git a/core/service/blockCoreService_test.go b/core/service/blockCoreService_test.go index 1395488e0..bd2ea8a80 100644 --- a/core/service/blockCoreService_test.go +++ b/core/service/blockCoreService_test.go @@ -397,11 +397,69 @@ func (*mockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...inter (*mockBlocksmiths)[1].NodePublicKey, (*mockBlocksmiths)[1].Score, )) + case "SELECT blocksmith_public_key, pop_change, block_height, blocksmith_index FROM skipped_blocksmith WHERE block_height = 0": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "blocksmith_public_key", "pop_change", "block_height", "blocksmith_index", + }).AddRow( + (*mockBlocksmiths)[0].NodePublicKey, + 5000, + mockPublishedReceipt[0].BlockHeight, + 0, + )) + case "SELECT blocksmith_public_key, pop_change, block_height, blocksmith_index FROM skipped_blocksmith WHERE block_height = 1": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "blocksmith_public_key", "pop_change", "block_height", "blocksmith_index", + }).AddRow( + (*mockBlocksmiths)[0].NodePublicKey, + 5000, + mockPublishedReceipt[0].BlockHeight, + 0, + )) + case "SELECT sender_public_key, recipient_public_key, datum_type, datum_hash, reference_block_height, " + + "reference_block_hash, rmr_linked, recipient_signature, intermediate_hashes, block_height, receipt_index, " + + "published_index FROM published_receipt WHERE block_height = ? ORDER BY published_index ASC": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "sender_public_key", "recipient_public_key", "datum_type", "datum_hash", "reference_block_height", + "reference_block_hash", "rmr_linked", "recipient_signature", "intermediate_hashes", "block_height", + "receipt_index", "published_index", + }).AddRow( + mockPublishedReceipt[0].BatchReceipt.SenderPublicKey, + mockPublishedReceipt[0].BatchReceipt.RecipientPublicKey, + mockPublishedReceipt[0].BatchReceipt.DatumType, + mockPublishedReceipt[0].BatchReceipt.DatumHash, + mockPublishedReceipt[0].BatchReceipt.ReferenceBlockHeight, + mockPublishedReceipt[0].BatchReceipt.ReferenceBlockHash, + mockPublishedReceipt[0].BatchReceipt.RMRLinked, + mockPublishedReceipt[0].BatchReceipt.RecipientSignature, + mockPublishedReceipt[0].IntermediateHashes, + mockPublishedReceipt[0].BlockHeight, + mockPublishedReceipt[0].ReceiptIndex, + mockPublishedReceipt[0].PublishedIndex, + )) } rows, _ := db.Query(qe) return rows, nil } +var mockPublishedReceipt = []*model.PublishedReceipt{ + { + BatchReceipt: &model.BatchReceipt{ + SenderPublicKey: make([]byte, 32), + RecipientPublicKey: make([]byte, 32), + DatumType: 0, + DatumHash: make([]byte, 32), + ReferenceBlockHeight: 0, + ReferenceBlockHash: make([]byte, 32), + RMRLinked: nil, + RecipientSignature: make([]byte, 64), + }, + IntermediateHashes: nil, + BlockHeight: 1, + ReceiptIndex: 0, + PublishedIndex: 0, + }, +} + func (*mockQueryExecutorValidateBlock) ExecuteSelect(qe string, tx bool, args ...interface{}) (*sql.Rows, error) { db, mock, _ := sqlmock.New() defer db.Close() @@ -2323,6 +2381,8 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { TransactionQuery query.TransactionQueryInterface Signature crypto.SignatureInterface MempoolService MempoolServiceInterface + PublishedReceiptQuery query.PublishedReceiptQueryInterface + SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface ActionTypeSwitcher transaction.TypeActionSwitcher AccountBalanceQuery query.AccountBalanceQueryInterface ParticipationScoreQuery query.ParticipationScoreQueryInterface @@ -2345,8 +2405,10 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { block: block, }, fields: fields{ - QueryExecutor: &mockQueryExecutorNotFound{}, - NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + QueryExecutor: &mockQueryExecutorNotFound{}, + NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + PublishedReceiptQuery: query.NewPublishedReceiptQuery(), + SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), }, wantErr: true, want: nil, @@ -2357,8 +2419,10 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { block: genesisBlock, }, fields: fields{ - QueryExecutor: &mockQueryExecutorSuccess{}, - NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + QueryExecutor: &mockQueryExecutorSuccess{}, + NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + PublishedReceiptQuery: query.NewPublishedReceiptQuery(), + SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), }, wantErr: false, want: &model.BlockExtendedInfo{ @@ -2380,9 +2444,16 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { Version: 0, }, BlocksmithAccountAddress: constant.MainchainGenesisAccountAddress, - TotalReceipts: 99, - ReceiptValue: 99, - PopChange: -20, + TotalReceipts: 1, + ReceiptValue: 50000000, + PopChange: -500000000, + SkippedBlocksmiths: []*model.SkippedBlocksmith{ + { + BlocksmithPublicKey: (*mockBlocksmiths)[0].NodePublicKey, + POPChange: 5000, + BlockHeight: 1, + }, + }, }, }, { @@ -2391,8 +2462,10 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { block: block, }, fields: fields{ - QueryExecutor: &mockQueryExecutorSuccess{}, - NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + QueryExecutor: &mockQueryExecutorSuccess{}, + NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + PublishedReceiptQuery: query.NewPublishedReceiptQuery(), + SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), }, wantErr: false, want: &model.BlockExtendedInfo{ @@ -2414,9 +2487,16 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { Version: 0, }, BlocksmithAccountAddress: bcsAddress1, - TotalReceipts: 99, - ReceiptValue: 99, - PopChange: -20, + TotalReceipts: int64(len(mockPublishedReceipt)), + ReceiptValue: 50000000, + PopChange: -500000000, + SkippedBlocksmiths: []*model.SkippedBlocksmith{ + { + BlocksmithPublicKey: (*mockBlocksmiths)[0].NodePublicKey, + POPChange: 5000, + BlockHeight: 1, + }, + }, }, }, } @@ -2431,6 +2511,8 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { Signature: tt.fields.Signature, MempoolService: tt.fields.MempoolService, ActionTypeSwitcher: tt.fields.ActionTypeSwitcher, + PublishedReceiptQuery: tt.fields.PublishedReceiptQuery, + SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, AccountBalanceQuery: tt.fields.AccountBalanceQuery, ParticipationScoreQuery: tt.fields.ParticipationScoreQuery, NodeRegistrationQuery: tt.fields.NodeRegistrationQuery, From e77b9fcf16e05f385f161a9a0acb549fa074d704 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 13:43:00 +0800 Subject: [PATCH 22/26] #395 move tests to block core service --- core/service/blockCoreService_test.go | 270 +++++++++++++++++++++++-- core/smith/blockchainProcessor_test.go | 129 ------------ 2 files changed, 256 insertions(+), 143 deletions(-) diff --git a/core/service/blockCoreService_test.go b/core/service/blockCoreService_test.go index bd2ea8a80..18f14f5ee 100644 --- a/core/service/blockCoreService_test.go +++ b/core/service/blockCoreService_test.go @@ -7,6 +7,7 @@ import ( "math/big" "reflect" "regexp" + "sync" "testing" "golang.org/x/crypto/sha3" @@ -22,7 +23,7 @@ import ( "github.com/zoobc/zoobc-core/common/model" "github.com/zoobc/zoobc-core/common/query" "github.com/zoobc/zoobc-core/common/transaction" - util2 "github.com/zoobc/zoobc-core/core/util" + coreUtil "github.com/zoobc/zoobc-core/core/util" "github.com/zoobc/zoobc-core/observer" ) @@ -389,13 +390,15 @@ func (*mockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...inter "AS nr INNER JOIN participation_score AS ps ON nr.id = ps.node_id WHERE nr.registration_status = 0 AND nr.latest " + "= 1 AND ps.score > 0 AND ps.latest = 1": mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ - "node_public_key", "score", + "node_id", "node_public_key", "score", }).AddRow( + (*mockBlocksmiths)[0].NodeID, (*mockBlocksmiths)[0].NodePublicKey, - (*mockBlocksmiths)[0].Score, + score1.String(), ).AddRow( + (*mockBlocksmiths)[1].NodeID, (*mockBlocksmiths)[1].NodePublicKey, - (*mockBlocksmiths)[1].Score, + score2.String(), )) case "SELECT blocksmith_public_key, pop_change, block_height, blocksmith_index FROM skipped_blocksmith WHERE block_height = 0": mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ @@ -915,6 +918,7 @@ func TestBlockService_PushBlock(t *testing.T) { AccountBalanceQuery query.AccountBalanceQueryInterface NodeRegistrationQuery query.NodeRegistrationQueryInterface Signature crypto.SignatureInterface + SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface ActionTypeSwitcher transaction.TypeActionSwitcher Observer *observer.Observer SortedBlocksmiths *[]model.Blocksmith @@ -942,6 +946,7 @@ func TestBlockService_PushBlock(t *testing.T) { NodeRegistrationQuery: query.NewNodeRegistrationQuery(), Observer: observer.NewObserver(), MempoolQuery: query.NewMempoolQuery(&chaintype.MainChain{}), + SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), NodeRegistrationService: &mockNodeRegistrationServiceSuccess{}, SortedBlocksmiths: mockBlocksmiths, ParticipationScoreQuery: query.NewParticipationScoreQuery(), @@ -992,6 +997,7 @@ func TestBlockService_PushBlock(t *testing.T) { NodeRegistrationQuery: query.NewNodeRegistrationQuery(), MempoolQuery: query.NewMempoolQuery(&chaintype.MainChain{}), ParticipationScoreQuery: query.NewParticipationScoreQuery(), + SkippedBlocksmithQuery: query.NewSkippedBlocksmithQuery(), Observer: observer.NewObserver(), SortedBlocksmiths: mockBlocksmiths, }, @@ -1041,6 +1047,7 @@ func TestBlockService_PushBlock(t *testing.T) { AccountBalanceQuery: tt.fields.AccountBalanceQuery, TransactionQuery: tt.fields.TransactionQuery, NodeRegistrationQuery: tt.fields.NodeRegistrationQuery, + SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, Signature: tt.fields.Signature, ActionTypeSwitcher: tt.fields.ActionTypeSwitcher, Observer: tt.fields.Observer, @@ -2248,9 +2255,10 @@ func TestBlockService_ReceiveBlock(t *testing.T) { block: &model.Block{ PreviousBlockHash: []byte{133, 198, 93, 19, 200, 113, 155, 159, 136, 63, 230, 29, 21, 173, 160, 40, 169, 25, 61, 85, 203, 79, 43, 182, 5, 236, 141, 124, 46, 193, 223, 255}, - BlockSignature: nil, - SmithScale: 1, - BlocksmithPublicKey: []byte{1, 3, 4, 5, 6}, + BlockSignature: nil, + SmithScale: 1, + BlocksmithPublicKey: []byte{1, 2, 3, 200, 7, 61, 108, 229, 204, 48, 199, 145, 21, 99, 125, 75, 49, + 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, }, nodeSecretPhrase: "", }, @@ -2270,16 +2278,17 @@ func TestBlockService_ReceiveBlock(t *testing.T) { AccountBalanceQuery: query.NewAccountBalanceQuery(), Observer: observer.NewObserver(), SortedBlocksmiths: &[]model.Blocksmith{ - { - NodePublicKey: []byte{1, 3, 4, 5, 6}, - NodeID: 2, - NodeOrder: big.NewInt(2), - }, { NodePublicKey: []byte{1, 3, 4, 5, 7}, NodeID: 1, NodeOrder: big.NewInt(1), }, + { + NodePublicKey: []byte{1, 2, 3, 200, 7, 61, 108, 229, 204, 48, 199, 145, 21, 99, 125, 75, 49, + 45, 118, 97, 219, 80, 242, 244, 100, 134, 144, 246, 37, 144, 213, 135}, + NodeID: 2, + NodeOrder: big.NewInt(2), + }, }, NodeRegistrationService: &mockNodeRegistrationServiceSuccess{}, }, @@ -2716,8 +2725,8 @@ func TestBlockService_GetBlocksmiths(t *testing.T) { { NodeID: 1, NodePublicKey: nrsNodePubKey1, - SmithOrder: util2.CalculateSmithOrder(new(big.Int).SetInt64(8000), new(big.Int).SetBytes(nrsBlock2.BlockSeed), 1), - NodeOrder: util2.CalculateNodeOrder(new(big.Int).SetInt64(8000), new(big.Int).SetBytes(nrsBlock2.BlockSeed), 1), + SmithOrder: coreUtil.CalculateSmithOrder(new(big.Int).SetInt64(8000), new(big.Int).SetBytes(nrsBlock2.BlockSeed), 1), + NodeOrder: coreUtil.CalculateNodeOrder(new(big.Int).SetInt64(8000), new(big.Int).SetBytes(nrsBlock2.BlockSeed), 1), BlockSeed: new(big.Int).SetBytes(nrsBlock2.BlockSeed), Score: new(big.Int).SetInt64(8000), }, @@ -3033,3 +3042,236 @@ func TestBlockService_ValidateBlock(t *testing.T) { }) } } + +var ( + blockSeed = new(big.Int).SetUint64(10000000) + score1 = new(big.Int).SetInt64(8000) + nodeID1 = int64(12536845) + score2 = new(big.Int).SetInt64(1000) + nodeID2 = int64(12536845) + score3 = new(big.Int).SetInt64(5000) + nodeID3 = int64(12536845) + score4 = new(big.Int).SetInt64(10000) + nodeID4 = int64(12536845) + score5 = new(big.Int).SetInt64(9000) + nodeID5 = int64(12536845) + score6 = new(big.Int).SetInt64(100000) + nodeID6 = int64(12536845) + score7 = new(big.Int).SetInt64(90000) + nodeID7 = int64(12536845) + score8 = new(big.Int).SetInt64(65000) + nodeID8 = int64(12536845) + score9 = new(big.Int).SetInt64(999) + nodeID9 = int64(12536845) +) + +func getMockBlocksmiths() *[]model.Blocksmith { + mockBlocksmiths := []model.Blocksmith{ + { + NodeID: nodeID1, + NodePublicKey: []byte{1}, + Score: score1, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score1, blockSeed, nodeID1), + NodeOrder: coreUtil.CalculateNodeOrder(score1, blockSeed, nodeID1), + }, + { + NodeID: nodeID2, + NodePublicKey: []byte{2}, + Score: score2, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score2, blockSeed, nodeID2), + NodeOrder: coreUtil.CalculateNodeOrder(score2, blockSeed, nodeID2), + }, + { + NodeID: nodeID3, + NodePublicKey: []byte{3}, + Score: score3, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score3, blockSeed, nodeID3), + NodeOrder: coreUtil.CalculateNodeOrder(score3, blockSeed, nodeID3), + }, + { + NodeID: nodeID4, + NodePublicKey: []byte{4}, + Score: score4, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score4, blockSeed, nodeID4), + NodeOrder: coreUtil.CalculateNodeOrder(score4, blockSeed, nodeID4), + }, + { + NodeID: nodeID5, + NodePublicKey: []byte{5}, + Score: score5, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score5, blockSeed, nodeID5), + NodeOrder: coreUtil.CalculateNodeOrder(score5, blockSeed, nodeID5), + }, + { + NodeID: nodeID6, + NodePublicKey: []byte{6}, + Score: score6, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score6, blockSeed, nodeID6), + NodeOrder: coreUtil.CalculateNodeOrder(score6, blockSeed, nodeID6), + }, + { + NodeID: nodeID7, + NodePublicKey: []byte{7}, + Score: score7, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score7, blockSeed, nodeID7), + NodeOrder: coreUtil.CalculateNodeOrder(score7, blockSeed, nodeID7), + }, + { + NodeID: nodeID8, + NodePublicKey: []byte{8}, + Score: score8, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score8, blockSeed, nodeID8), + NodeOrder: coreUtil.CalculateNodeOrder(score8, blockSeed, nodeID8), + }, + { + NodeID: nodeID9, + NodePublicKey: []byte{9}, + Score: score9, + SmithTime: 0, + BlockSeed: blockSeed, + SecretPhrase: "", + Deadline: 0, + SmithOrder: coreUtil.CalculateSmithOrder(score9, blockSeed, nodeID9), + NodeOrder: coreUtil.CalculateNodeOrder(score9, blockSeed, nodeID9), + }, + } + return &mockBlocksmiths +} + +func TestBlockService_SortBlocksmiths(t *testing.T) { + type fields struct { + WaitGroup sync.WaitGroup + Chaintype chaintype.ChainType + KVExecutor kvdb.KVExecutorInterface + QueryExecutor query.ExecutorInterface + BlockQuery query.BlockQueryInterface + MempoolQuery query.MempoolQueryInterface + TransactionQuery query.TransactionQueryInterface + MerkleTreeQuery query.MerkleTreeQueryInterface + PublishedReceiptQuery query.PublishedReceiptQueryInterface + SkippedBlocksmithQuery query.SkippedBlocksmithQueryInterface + Signature crypto.SignatureInterface + MempoolService MempoolServiceInterface + ReceiptService ReceiptServiceInterface + NodeRegistrationService NodeRegistrationServiceInterface + ActionTypeSwitcher transaction.TypeActionSwitcher + AccountBalanceQuery query.AccountBalanceQueryInterface + ParticipationScoreQuery query.ParticipationScoreQueryInterface + NodeRegistrationQuery query.NodeRegistrationQueryInterface + Observer *observer.Observer + SortedBlocksmiths *[]model.Blocksmith + Logger *log.Logger + } + type args struct { + block *model.Block + } + tests := []struct { + name string + fields fields + args args + }{ + { + name: "success", + fields: fields{ + WaitGroup: sync.WaitGroup{}, + Chaintype: &chaintype.MainChain{}, + KVExecutor: nil, + QueryExecutor: &mockQueryExecutorSuccess{}, + BlockQuery: nil, + NodeRegistrationQuery: query.NewNodeRegistrationQuery(), + SortedBlocksmiths: getMockBlocksmiths(), + Logger: logrus.New(), + }, + args: args{ + block: &model.Block{ + ID: 0, + PreviousBlockHash: nil, + Height: 0, + Timestamp: 0, + BlockSeed: nil, + BlockSignature: nil, + CumulativeDifficulty: "", + SmithScale: 0, + BlocksmithPublicKey: nil, + TotalAmount: 0, + TotalFee: 0, + TotalCoinBase: 0, + Version: 0, + PayloadLength: 0, + PayloadHash: nil, + Transactions: nil, + PublishedReceipts: nil, + XXX_NoUnkeyedLiteral: struct{}{}, + XXX_unrecognized: nil, + XXX_sizecache: 0, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + bs := &BlockService{ + WaitGroup: tt.fields.WaitGroup, + Chaintype: tt.fields.Chaintype, + KVExecutor: tt.fields.KVExecutor, + QueryExecutor: tt.fields.QueryExecutor, + BlockQuery: tt.fields.BlockQuery, + MempoolQuery: tt.fields.MempoolQuery, + TransactionQuery: tt.fields.TransactionQuery, + MerkleTreeQuery: tt.fields.MerkleTreeQuery, + PublishedReceiptQuery: tt.fields.PublishedReceiptQuery, + SkippedBlocksmithQuery: tt.fields.SkippedBlocksmithQuery, + Signature: tt.fields.Signature, + MempoolService: tt.fields.MempoolService, + ReceiptService: tt.fields.ReceiptService, + NodeRegistrationService: tt.fields.NodeRegistrationService, + ActionTypeSwitcher: tt.fields.ActionTypeSwitcher, + AccountBalanceQuery: tt.fields.AccountBalanceQuery, + ParticipationScoreQuery: tt.fields.ParticipationScoreQuery, + NodeRegistrationQuery: tt.fields.NodeRegistrationQuery, + Observer: tt.fields.Observer, + SortedBlocksmiths: tt.fields.SortedBlocksmiths, + Logger: tt.fields.Logger, + } + bs.SortBlocksmiths(tt.args.block) + + if (*bs.SortedBlocksmiths)[0].NodeID != (*mockBlocksmiths)[1].NodeID || + (*bs.SortedBlocksmiths)[1].NodeID != (*mockBlocksmiths)[0].NodeID { + t.Error("invalid sort") + } + + }) + } +} diff --git a/core/smith/blockchainProcessor_test.go b/core/smith/blockchainProcessor_test.go index f2961a28c..587dc33e0 100644 --- a/core/smith/blockchainProcessor_test.go +++ b/core/smith/blockchainProcessor_test.go @@ -1,12 +1,9 @@ package smith import ( - "math/big" "reflect" "testing" - coreUtil "github.com/zoobc/zoobc-core/core/util" - "github.com/zoobc/zoobc-core/common/model" "github.com/zoobc/zoobc-core/common/chaintype" @@ -50,129 +47,3 @@ func TestNewBlockchainProcessor(t *testing.T) { }) } } - -var ( - blockSeed = new(big.Int).SetUint64(10000000) - score1 = new(big.Int).SetInt64(8000) - nodeID1 = int64(12536845) - score2 = new(big.Int).SetInt64(1000) - nodeID2 = int64(12536845) - score3 = new(big.Int).SetInt64(5000) - nodeID3 = int64(12536845) - score4 = new(big.Int).SetInt64(10000) - nodeID4 = int64(12536845) - score5 = new(big.Int).SetInt64(9000) - nodeID5 = int64(12536845) - score6 = new(big.Int).SetInt64(100000) - nodeID6 = int64(12536845) - score7 = new(big.Int).SetInt64(90000) - nodeID7 = int64(12536845) - score8 = new(big.Int).SetInt64(65000) - nodeID8 = int64(12536845) - score9 = new(big.Int).SetInt64(999) - nodeID9 = int64(12536845) -) - -func getMockBlocksmiths() []*model.Blocksmith { - return []*model.Blocksmith{ - { - NodeID: nodeID1, - NodePublicKey: []byte{1}, - Score: score1, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score1, blockSeed, nodeID1), - NodeOrder: coreUtil.CalculateNodeOrder(score1, blockSeed, nodeID1), - }, - { - NodeID: nodeID2, - NodePublicKey: []byte{2}, - Score: score2, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score2, blockSeed, nodeID2), - NodeOrder: coreUtil.CalculateNodeOrder(score2, blockSeed, nodeID2), - }, - { - NodeID: nodeID3, - NodePublicKey: []byte{3}, - Score: score3, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score3, blockSeed, nodeID3), - NodeOrder: coreUtil.CalculateNodeOrder(score3, blockSeed, nodeID3), - }, - { - NodeID: nodeID4, - NodePublicKey: []byte{4}, - Score: score4, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score4, blockSeed, nodeID4), - NodeOrder: coreUtil.CalculateNodeOrder(score4, blockSeed, nodeID4), - }, - { - NodeID: nodeID5, - NodePublicKey: []byte{5}, - Score: score5, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score5, blockSeed, nodeID5), - NodeOrder: coreUtil.CalculateNodeOrder(score5, blockSeed, nodeID5), - }, - { - NodeID: nodeID6, - NodePublicKey: []byte{6}, - Score: score6, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score6, blockSeed, nodeID6), - NodeOrder: coreUtil.CalculateNodeOrder(score6, blockSeed, nodeID6), - }, - { - NodeID: nodeID7, - NodePublicKey: []byte{7}, - Score: score7, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score7, blockSeed, nodeID7), - NodeOrder: coreUtil.CalculateNodeOrder(score7, blockSeed, nodeID7), - }, - { - NodeID: nodeID8, - NodePublicKey: []byte{8}, - Score: score8, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score8, blockSeed, nodeID8), - NodeOrder: coreUtil.CalculateNodeOrder(score8, blockSeed, nodeID8), - }, - { - NodeID: nodeID9, - NodePublicKey: []byte{9}, - Score: score9, - SmithTime: 0, - BlockSeed: blockSeed, - SecretPhrase: "", - Deadline: 0, - SmithOrder: coreUtil.CalculateSmithOrder(score9, blockSeed, nodeID9), - NodeOrder: coreUtil.CalculateNodeOrder(score9, blockSeed, nodeID9), - }, - } -} From 35726037ab5f4d61fe68228ed7a94d9228239a0c Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 14:50:21 +0800 Subject: [PATCH 23/26] handle error in build model --- common/query/nodeRegistrationQuery.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/query/nodeRegistrationQuery.go b/common/query/nodeRegistrationQuery.go index c1e42dc0f..2b3abfa21 100644 --- a/common/query/nodeRegistrationQuery.go +++ b/common/query/nodeRegistrationQuery.go @@ -172,7 +172,6 @@ func (nrq *NodeRegistrationQuery) GetNodeRegistryAtHeight(height uint32) string // ExtractModel extract the model struct fields to the order of NodeRegistrationQuery.Fields func (nrq *NodeRegistrationQuery) ExtractModel(tx *model.NodeRegistration) []interface{} { - return []interface{}{ tx.NodeID, tx.NodePublicKey, @@ -198,7 +197,10 @@ func (nrq *NodeRegistrationQuery) BuildModel( dumpString string ) - columns, _ := rows.Columns() + columns, err := rows.Columns() + if err != nil { + return nil, err + } for i := 0; i < len(columns)-len(nrq.Fields); i++ { ignoredAggregateColumns = append(ignoredAggregateColumns, &dumpString) } @@ -222,8 +224,10 @@ func (nrq *NodeRegistrationQuery) BuildModel( &nr.Height, ) basicFieldsReceiver = append(basicFieldsReceiver, ignoredAggregateColumns...) - _ = rows.Scan(basicFieldsReceiver...) - + err := rows.Scan(basicFieldsReceiver...) + if err != nil { + return nil, err + } nr.NodeAddress = nrq.BuildNodeAddress(fullNodeAddress) nodeRegistrations = append(nodeRegistrations, &nr) } From 6e9326e45bef624cf36c0b9d992cbea790ae2cbc Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 14:51:10 +0800 Subject: [PATCH 24/26] #395 get total node registry at height n when calculating total max receipt --- core/service/blockCoreService.go | 13 +++++++++++-- core/service/blockCoreService_test.go | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/core/service/blockCoreService.go b/core/service/blockCoreService.go index 463879507..3adf853ad 100644 --- a/core/service/blockCoreService.go +++ b/core/service/blockCoreService.go @@ -1204,6 +1204,7 @@ func (bs *BlockService) GetBlockExtendedInfo(block *model.Block) (*model.BlockEx blExt = &model.BlockExtendedInfo{} skippedBlocksmiths []*model.SkippedBlocksmith publishedReceipts []*model.PublishedReceipt + nodeRegistryAtHeight []*model.NodeRegistration linkedPublishedReceiptCount uint32 unLinkedPublishedReceiptCount uint32 err error @@ -1244,12 +1245,20 @@ func (bs *BlockService) GetBlockExtendedInfo(block *model.Block) (*model.BlockEx unLinkedPublishedReceiptCount++ } } + nodeRegistryAtHeightQ := bs.NodeRegistrationQuery.GetNodeRegistryAtHeight(block.Height) + nodeRegistryAtHeightRows, err := bs.QueryExecutor.ExecuteSelect(nodeRegistryAtHeightQ, false) + if err != nil { + return nil, err + } + nodeRegistryAtHeight, err = bs.NodeRegistrationQuery.BuildModel(nodeRegistryAtHeight, nodeRegistryAtHeightRows) + if err != nil { + return nil, err + } blExt.ReceiptValue = commonUtils.GetReceiptValue(linkedPublishedReceiptCount, unLinkedPublishedReceiptCount) - // todo: POPChange value will not be correct until we have scrambled node list at n-th height for `maxReceipt` parameter blExt.PopChange, err = util.CalculateParticipationScore( linkedPublishedReceiptCount, unLinkedPublishedReceiptCount, - uint32(len(publishedReceipts)), + uint32(len(nodeRegistryAtHeight)), ) if err != nil { return nil, err diff --git a/core/service/blockCoreService_test.go b/core/service/blockCoreService_test.go index 18f14f5ee..e24541cbd 100644 --- a/core/service/blockCoreService_test.go +++ b/core/service/blockCoreService_test.go @@ -439,6 +439,20 @@ func (*mockQueryExecutorSuccess) ExecuteSelect(qe string, tx bool, args ...inter mockPublishedReceipt[0].ReceiptIndex, mockPublishedReceipt[0].PublishedIndex, )) + case "SELECT id, node_public_key, account_address, registration_height, node_address, locked_balance, " + + "registration_status, latest, height, max(height) AS max_height FROM node_registry where height <= 0 AND " + + "registration_status = 0 GROUP BY id ORDER BY height DESC": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "id", "node_public_key", "account_address", "registration_height", "node_address", "locked_balance", + "registration_status", "latest", "height", + })) + case "SELECT id, node_public_key, account_address, registration_height, node_address, locked_balance, " + + "registration_status, latest, height, max(height) AS max_height FROM node_registry where height <= 1 " + + "AND registration_status = 0 GROUP BY id ORDER BY height DESC": + mock.ExpectQuery(regexp.QuoteMeta(qe)).WillReturnRows(sqlmock.NewRows([]string{ + "id", "node_public_key", "account_address", "registration_height", "node_address", "locked_balance", + "registration_status", "latest", "height", + })) } rows, _ := db.Query(qe) return rows, nil @@ -2455,7 +2469,7 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { BlocksmithAccountAddress: constant.MainchainGenesisAccountAddress, TotalReceipts: 1, ReceiptValue: 50000000, - PopChange: -500000000, + PopChange: 1000000000, SkippedBlocksmiths: []*model.SkippedBlocksmith{ { BlocksmithPublicKey: (*mockBlocksmiths)[0].NodePublicKey, @@ -2498,7 +2512,7 @@ func TestBlockService_GetBlockExtendedInfo(t *testing.T) { BlocksmithAccountAddress: bcsAddress1, TotalReceipts: int64(len(mockPublishedReceipt)), ReceiptValue: 50000000, - PopChange: -500000000, + PopChange: 1000000000, SkippedBlocksmiths: []*model.SkippedBlocksmith{ { BlocksmithPublicKey: (*mockBlocksmiths)[0].NodePublicKey, From fc3c1b75edd8b31d4f817b09c940891d1f595441 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Mon, 4 Nov 2019 14:51:28 +0800 Subject: [PATCH 25/26] #395 update schema model --- common/schema | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/schema b/common/schema index e379e92d0..76e74405a 160000 --- a/common/schema +++ b/common/schema @@ -1 +1 @@ -Subproject commit e379e92d0b8d940dc650ae39e23422ba867df3f9 +Subproject commit 76e74405a7eeafc65858b1c48b4e85a4696562f1 From e5439daab6a7587d27aebed304cc571978b45ef2 Mon Sep 17 00:00:00 2001 From: andy-shi88 Date: Tue, 5 Nov 2019 14:04:36 +0800 Subject: [PATCH 26/26] #395 use constant max score change --- common/util/ParticipationScore_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/util/ParticipationScore_test.go b/common/util/ParticipationScore_test.go index 3f038cbdd..f51e578ed 100644 --- a/common/util/ParticipationScore_test.go +++ b/common/util/ParticipationScore_test.go @@ -75,7 +75,7 @@ func TestCalculateParticipationScore(t *testing.T) { unlinkedReceipt: 0, maxReceipt: 0, }, - want: 1000000000, + want: constant.MaxScoreChange, wantErr: false, }, }