From 50c886903b29daced632a201ff9447d8d613b65f Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Thu, 28 Mar 2019 11:48:29 +0800 Subject: [PATCH 1/4] Support version upgrade in update billing tx header --- blockproducer/metastate_test.go | 4 + sqlchain/chain.go | 1 + types/updatebilling.go | 1 + types/updatebilling_gen.go | 73 ++++++++++--------- ...ebilling_updatebillingheader_9ef447_gen.go | 57 +++++++++++++++ ...ing_updatebillingheader_9ef447_gen_test.go | 47 ++++++++++++ ...ebilling_updatebillingheader_oldver_gen.go | 51 +++++++++++++ ...ing_updatebillingheader_oldver_gen_test.go | 47 ++++++++++++ 8 files changed, 245 insertions(+), 36 deletions(-) create mode 100644 types/updatebilling_updatebillingheader_9ef447_gen.go create mode 100644 types/updatebilling_updatebillingheader_9ef447_gen_test.go create mode 100644 types/updatebilling_updatebillingheader_oldver_gen.go create mode 100644 types/updatebilling_updatebillingheader_oldver_gen_test.go diff --git a/blockproducer/metastate_test.go b/blockproducer/metastate_test.go index 75b8b6050..0978dc5f1 100644 --- a/blockproducer/metastate_test.go +++ b/blockproducer/metastate_test.go @@ -1169,6 +1169,7 @@ func TestMetaState(t *testing.T) { To: 10, }, }) + ub.Version = int32(ub.HSPDefaultVersion()) nonce, err = ms.nextNonce(addr2) So(err, ShouldBeNil) ub.Nonce = nonce @@ -1352,6 +1353,7 @@ func TestMetaState(t *testing.T) { }, }, } + ub1.Version = int32(ub1.HSPDefaultVersion()) err = ub1.Sign(privKey1) So(err, ShouldBeNil) err = ms.apply(ub1) @@ -1442,6 +1444,7 @@ func TestMetaState(t *testing.T) { }, }, } + ub2.Version = int32(ub2.HSPDefaultVersion()) err = ub2.Sign(privKey2) So(err, ShouldBeNil) err = ms.apply(ub2) @@ -1493,6 +1496,7 @@ func TestMetaState(t *testing.T) { }, }, } + ub3.Version = int32(ub3.HSPDefaultVersion()) err = ub3.Sign(privKey2) So(err, ShouldBeNil) err = ms.apply(ub3) diff --git a/sqlchain/chain.go b/sqlchain/chain.go index b2b7f87b7..dba3dff1d 100644 --- a/sqlchain/chain.go +++ b/sqlchain/chain.go @@ -1059,6 +1059,7 @@ func (c *Chain) billing(h int32, node *blockNode) (ub *types.UpdateBilling, err ub = types.NewUpdateBilling(&types.UpdateBillingHeader{ Users: make([]*types.UserCost, len(usersMap)), }) + ub.Version = int32(ub.HSPDefaultVersion()) i = 0 j = 0 diff --git a/types/updatebilling.go b/types/updatebilling.go index 9b9b12e4e..144bfc91a 100644 --- a/types/updatebilling.go +++ b/types/updatebilling.go @@ -50,6 +50,7 @@ type UpdateBillingHeader struct { Nonce pi.AccountNonce Users []*UserCost Range Range + Version int32 `hsp:"v,version"` } // UpdateBilling defines the UpdateBilling transaction. diff --git a/types/updatebilling_gen.go b/types/updatebilling_gen.go index 36e465be5..b14103749 100644 --- a/types/updatebilling_gen.go +++ b/types/updatebilling_gen.go @@ -3,6 +3,8 @@ package types // Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT. import ( + herr "errors" + hsp "github.com/CovenantSQL/HashStablePack/marshalhash" ) @@ -74,50 +76,49 @@ func (z *UpdateBilling) Msgsize() (s int) { return } +var hspVersionsUpdateBillingHeader = []string{ + "oldver", + "9ef447", +} + +// HSPCurrentVersion returns current struct version +func (z *UpdateBillingHeader) HSPCurrentVersion() int { + return int(z.Version) +} + +// HSPMaxVersion returns max struct version +func (z *UpdateBillingHeader) HSPMaxVersion() int { + return 1 +} + +// HSPDefaultVersion returns default struct version +func (z *UpdateBillingHeader) HSPDefaultVersion() int { + return 1 +} + // MarshalHash marshals for hash func (z *UpdateBillingHeader) MarshalHash() (o []byte, err error) { - var b []byte - o = hsp.Require(b, z.Msgsize()) - // map header, size 4 - o = append(o, 0x84) - if oTemp, err := z.Nonce.MarshalHash(); err != nil { - return nil, err - } else { - o = hsp.AppendBytes(o, oTemp) - } - // map header, size 2 - o = append(o, 0x82) - o = hsp.AppendUint32(o, z.Range.From) - o = hsp.AppendUint32(o, z.Range.To) - if oTemp, err := z.Receiver.MarshalHash(); err != nil { - return nil, err - } else { - o = hsp.AppendBytes(o, oTemp) - } - o = hsp.AppendArrayHeader(o, uint32(len(z.Users))) - for za0001 := range z.Users { - if z.Users[za0001] == nil { - o = hsp.AppendNil(o) - } else { - if oTemp, err := z.Users[za0001].MarshalHash(); err != nil { - return nil, err - } else { - o = hsp.AppendBytes(o, oTemp) - } - } + switch z.HSPCurrentVersion() { + case 0: + return z.MarshalHasholdver() + case 1: + return z.MarshalHash9ef447() + default: + err = herr.New("invalid struct version") + return } return } // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *UpdateBillingHeader) Msgsize() (s int) { - s = 1 + 6 + z.Nonce.Msgsize() + 6 + 1 + 5 + hsp.Uint32Size + 3 + hsp.Uint32Size + 9 + z.Receiver.Msgsize() + 6 + hsp.ArrayHeaderSize - for za0001 := range z.Users { - if z.Users[za0001] == nil { - s += hsp.NilSize - } else { - s += z.Users[za0001].Msgsize() - } + switch z.HSPCurrentVersion() { + case 0: + return z.Msgsizeoldver() + case 1: + return z.Msgsize9ef447() + default: + return 0 } return } diff --git a/types/updatebilling_updatebillingheader_9ef447_gen.go b/types/updatebilling_updatebillingheader_9ef447_gen.go new file mode 100644 index 000000000..d90f54b01 --- /dev/null +++ b/types/updatebilling_updatebillingheader_9ef447_gen.go @@ -0,0 +1,57 @@ +package types + +// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT. + +import ( + hsp "github.com/CovenantSQL/HashStablePack/marshalhash" +) + +// MarshalHash9ef447 marshals for hash +func (z *UpdateBillingHeader) MarshalHash9ef447() (o []byte, err error) { + var b []byte + o = hsp.Require(b, z.Msgsize9ef447()) + // map header, size 5 + o = append(o, 0x85) + if oTemp, err := z.Nonce.MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + // map header, size 2 + o = append(o, 0x82) + o = hsp.AppendUint32(o, z.Range.From) + o = hsp.AppendUint32(o, z.Range.To) + if oTemp, err := z.Receiver.MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + o = hsp.AppendArrayHeader(o, uint32(len(z.Users))) + for za0001 := range z.Users { + if z.Users[za0001] == nil { + o = hsp.AppendNil(o) + } else { + if oTemp, err := z.Users[za0001].MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + } + } + o = hsp.AppendInt32(o, z.Version) + return +} + +// Msgsize9ef447 returns an upper bound estimate of the number of bytes occupied by the serialized message +func (z *UpdateBillingHeader) Msgsize9ef447() (s int) { + s = 1 + 6 + z.Nonce.Msgsize() + 6 + 1 + 5 + hsp.Uint32Size + 3 + hsp.Uint32Size + 9 + z.Receiver.Msgsize() + 6 + hsp.ArrayHeaderSize + for za0001 := range z.Users { + if z.Users[za0001] == nil { + s += hsp.NilSize + } else { + s += z.Users[za0001].Msgsize() + } + } + s += 2 + hsp.Int32Size + return +} diff --git a/types/updatebilling_updatebillingheader_9ef447_gen_test.go b/types/updatebilling_updatebillingheader_9ef447_gen_test.go new file mode 100644 index 000000000..3f48bd2e1 --- /dev/null +++ b/types/updatebilling_updatebillingheader_9ef447_gen_test.go @@ -0,0 +1,47 @@ +package types + +// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT. + +import ( + "bytes" + "crypto/rand" + "encoding/binary" + "testing" +) + +func TestMarshalHash9ef447UpdateBillingHeader(t *testing.T) { + v := UpdateBillingHeader{} + binary.Read(rand.Reader, binary.BigEndian, &v) + bts1, err := v.MarshalHash9ef447() + if err != nil { + t.Fatal(err) + } + bts2, err := v.MarshalHash9ef447() + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(bts1, bts2) { + t.Fatal("hash not stable") + } +} + +func BenchmarkMarshalHash9ef447UpdateBillingHeader(b *testing.B) { + v := UpdateBillingHeader{} + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + v.MarshalHash9ef447() + } +} + +func BenchmarkAppendMsg9ef447UpdateBillingHeader(b *testing.B) { + v := UpdateBillingHeader{} + bts := make([]byte, 0, v.Msgsize9ef447()) + bts, _ = v.MarshalHash9ef447() + b.SetBytes(int64(len(bts))) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + bts, _ = v.MarshalHash9ef447() + } +} diff --git a/types/updatebilling_updatebillingheader_oldver_gen.go b/types/updatebilling_updatebillingheader_oldver_gen.go new file mode 100644 index 000000000..681658afd --- /dev/null +++ b/types/updatebilling_updatebillingheader_oldver_gen.go @@ -0,0 +1,51 @@ +package types + +// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT. + +import ( + hsp "github.com/CovenantSQL/HashStablePack/marshalhash" +) + +// MarshalHasholdver marshals for hash +func (z *UpdateBillingHeader) MarshalHasholdver() (o []byte, err error) { + var b []byte + o = hsp.Require(b, z.Msgsize()) + + o = append(o, 0x83) + if oTemp, err := z.Nonce.MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + if oTemp, err := z.Receiver.MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + o = hsp.AppendArrayHeader(o, uint32(len(z.Users))) + for za0001 := range z.Users { + if z.Users[za0001] == nil { + o = hsp.AppendNil(o) + } else { + if oTemp, err := z.Users[za0001].MarshalHash(); err != nil { + return nil, err + } else { + o = hsp.AppendBytes(o, oTemp) + } + } + } + return +} + +// Msgsizeoldver returns an upper bound estimate of the number of bytes occupied by the serialized message +func (z *UpdateBillingHeader) Msgsizeoldver() (s int) { + s = 1 + 6 + z.Nonce.Msgsize() + 9 + z.Receiver.Msgsize() + 6 + hsp.ArrayHeaderSize + for za0001 := range z.Users { + if z.Users[za0001] == nil { + s += hsp.NilSize + } else { + s += z.Users[za0001].Msgsize() + } + } + return +} diff --git a/types/updatebilling_updatebillingheader_oldver_gen_test.go b/types/updatebilling_updatebillingheader_oldver_gen_test.go new file mode 100644 index 000000000..818fb978d --- /dev/null +++ b/types/updatebilling_updatebillingheader_oldver_gen_test.go @@ -0,0 +1,47 @@ +package types + +// Code generated by github.com/CovenantSQL/HashStablePack DO NOT EDIT. + +import ( + "bytes" + "crypto/rand" + "encoding/binary" + "testing" +) + +func TestMarshalHasholdverUpdateBillingHeader(t *testing.T) { + v := UpdateBillingHeader{} + binary.Read(rand.Reader, binary.BigEndian, &v) + bts1, err := v.MarshalHasholdver() + if err != nil { + t.Fatal(err) + } + bts2, err := v.MarshalHasholdver() + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(bts1, bts2) { + t.Fatal("hash not stable") + } +} + +func BenchmarkMarshalHasholdverUpdateBillingHeader(b *testing.B) { + v := UpdateBillingHeader{} + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + v.MarshalHasholdver() + } +} + +func BenchmarkAppendMsgoldverUpdateBillingHeader(b *testing.B) { + v := UpdateBillingHeader{} + bts := make([]byte, 0, v.Msgsizeoldver()) + bts, _ = v.MarshalHasholdver() + b.SetBytes(int64(len(bts))) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + bts, _ = v.MarshalHasholdver() + } +} From 86333a42b892df182a29cf3e66401ca0d0d51696 Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Thu, 28 Mar 2019 11:59:34 +0800 Subject: [PATCH 2/4] Increase goroutine leak threshold to 150 --- cmd/cql-minerd/integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cql-minerd/integration_test.go b/cmd/cql-minerd/integration_test.go index 44745276f..e1253842b 100644 --- a/cmd/cql-minerd/integration_test.go +++ b/cmd/cql-minerd/integration_test.go @@ -735,7 +735,7 @@ func benchDB(b *testing.B, db *sql.DB, createDB bool) { }) routineCount := runtime.NumGoroutine() - if routineCount > 100 { + if routineCount > 150 { b.Errorf("go routine count: %d", routineCount) } else { log.Infof("go routine count: %d", routineCount) From 5a8c774b0dda27522ae70b37d468f0f38e20ca7c Mon Sep 17 00:00:00 2001 From: Levente Liu Date: Thu, 28 Mar 2019 12:03:15 +0800 Subject: [PATCH 3/4] Skip old version billing --- blockproducer/metastate.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/blockproducer/metastate.go b/blockproducer/metastate.go index a5ffd9925..43fcb8252 100644 --- a/blockproducer/metastate.go +++ b/blockproducer/metastate.go @@ -900,7 +900,8 @@ func (s *metaState) updateBilling(tx *types.UpdateBilling) (err error) { err = errors.Wrap(ErrDatabaseNotFound, "update billing failed") return } - if tx.Range.From >= tx.Range.To || newProfile.LastUpdatedHeight != tx.Range.From { + + if tx.Version > 0 && (tx.Range.From >= tx.Range.To || newProfile.LastUpdatedHeight != tx.Range.From) { err = errors.Wrapf(ErrInvalidRange, "update billing within range %d:(%d, %d]", newProfile.LastUpdatedHeight, tx.Range.From, tx.Range.To) From 0537f6fb3bbe632a1e31ce2b9997c31ad0b0e6ae Mon Sep 17 00:00:00 2001 From: Qi Xiao Date: Thu, 28 Mar 2019 12:20:47 +0800 Subject: [PATCH 4/4] Increase another threshold of go routine count --- cmd/cql-minerd/integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/cql-minerd/integration_test.go b/cmd/cql-minerd/integration_test.go index e1253842b..4ab6a6ca0 100644 --- a/cmd/cql-minerd/integration_test.go +++ b/cmd/cql-minerd/integration_test.go @@ -777,7 +777,7 @@ func benchDB(b *testing.B, db *sql.DB, createDB bool) { }) routineCount = runtime.NumGoroutine() - if routineCount > 100 { + if routineCount > 150 { b.Errorf("go routine count: %d", routineCount) } else { log.Infof("go routine count: %d", routineCount)