From ae803ff7eb7b61bb0b7980c962212d5261eb2767 Mon Sep 17 00:00:00 2001 From: Devin Date: Wed, 10 Jul 2019 17:31:19 +0800 Subject: [PATCH 01/44] Refactor validator --- consensus/jury/contractReq.go | 7 +++ consensus/jury/service.go | 5 +- dag/dag.go | 75 +++++++++++++++-------------- dag/dag_mock.go | 28 ----------- dag/init_manage.go | 7 +-- dag/interface.go | 4 +- dag/memunit/memdag.go | 15 ++++-- dag/txspool/txpool.go | 6 ++- ptn/handler.go | 2 +- validator/interface.go | 2 +- validator/validate_tx_test.go | 14 ++++-- validator/validate_unit.go | 88 +++++++++++++++++++++++------------ validator/validator.go | 9 ++-- validator/validator_cache.go | 36 +++++++------- validator/validator_test.go | 4 +- 15 files changed, 163 insertions(+), 139 deletions(-) diff --git a/consensus/jury/contractReq.go b/consensus/jury/contractReq.go index add404be7..2aa87aa8d 100755 --- a/consensus/jury/contractReq.go +++ b/consensus/jury/contractReq.go @@ -28,6 +28,8 @@ import ( "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/common/util" + "encoding/json" + "github.com/ethereum/go-ethereum/rlp" "github.com/palletone/go-palletone/common/crypto" "github.com/palletone/go-palletone/dag/errors" "github.com/palletone/go-palletone/dag/modules" @@ -149,6 +151,11 @@ func (p *Processor) ContractInvokeReq(from, to common.Address, daoAmount, daoFee return common.Hash{}, err } log.Infof("[%s]ContractInvokeReq ok, reqId[%s], contractId[%s]", shortId(reqId.String()), reqId.String(), contractId.String()) + log.DebugDynamic(func() string { + rjson, _ := json.Marshal(tx) + rdata, _ := rlp.EncodeToBytes(tx) + return fmt.Sprintf("Request data fro debug json:%s,\r\n rlp:%x", string(rjson), rdata) + }) //broadcast go p.ptn.ContractBroadcast(ContractEvent{Ele: p.mtx[reqId].eleInf, CType: CONTRACT_EVENT_EXEC, Tx: tx}, true) return reqId, nil diff --git a/consensus/jury/service.go b/consensus/jury/service.go index 6ced04657..6b73c3630 100755 --- a/consensus/jury/service.go +++ b/consensus/jury/service.go @@ -27,6 +27,7 @@ import ( "encoding/json" + "github.com/coocood/freecache" "github.com/ethereum/go-ethereum/rlp" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/crypto" @@ -200,8 +201,8 @@ func NewContractProcessor(ptn PalletOne, dag iDag, contract *contracts.Contract, if contractEleNum < 1 { contractEleNum = core.DefaultContractElectionNum } - - validator := validator.NewValidate(dag, dag, dag, nil) + cache := freecache.NewCache(20 * 1024 * 1024) + validator := validator.NewValidate(dag, dag, dag, nil, cache) p := &Processor{ name: "contractProcessor", ptn: ptn, diff --git a/dag/dag.go b/dag/dag.go index 949441515..910b3220c 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -44,7 +44,6 @@ import ( "github.com/palletone/go-palletone/dag/storage" "github.com/palletone/go-palletone/dag/txspool" "github.com/palletone/go-palletone/tokenengine" - "github.com/palletone/go-palletone/validator" ) type Dag struct { @@ -64,8 +63,8 @@ type Dag struct { stablePropRep dagcommon.IPropRepository stableUnitProduceRep dagcommon.IUnitProduceRepository - validate validator.Validator - ChainHeadFeed *event.Feed + //validate validator.Validator + ChainHeadFeed *event.Feed Mutex sync.RWMutex Memdag memunit.IMemDag // memory unit @@ -389,22 +388,22 @@ func (d *Dag) InsertHeaderDag(headers []*modules.Header) (int, error) { //VerifyHeader checks whether a header conforms to the consensus rules of the stock //Ethereum ethash engine.go -func (d *Dag) VerifyHeader(header *modules.Header) error { - // step1. check unit signature, should be compare to mediator list - unitState := validator.NewValidateError( d.validate.ValidateHeader(header)) - if unitState != nil { - log.Errorf("Validate unit header error, errno=%s", unitState.Error()) - return unitState - } - - // step2. check extra data - // Ensure that the header's extra-data section is of a reasonable size - if uint64(len(header.Extra)) > uint64(32) { - return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), configure.MaximumExtraDataSize) - } - - return nil -} +//func (d *Dag) VerifyHeader(header *modules.Header) error { +// // step1. check unit signature, should be compare to mediator list +// unitState := validator.NewValidateError(d.validate.ValidateHeader(header)) +// if unitState != nil { +// log.Errorf("Validate unit header error, errno=%s", unitState.Error()) +// return unitState +// } +// +// // step2. check extra data +// // Ensure that the header's extra-data section is of a reasonable size +// if uint64(len(header.Extra)) > uint64(32) { +// return fmt.Errorf("extra-data too long: %d > %d", len(header.Extra), configure.MaximumExtraDataSize) +// } +// +// return nil +//} /** 获取account address下面的token信息 @@ -531,7 +530,7 @@ func (d *Dag) initDataForMainChainHeader(mainChain *modules.MainChain) { d.stableUnitRep.SaveNewestHeader(pHeader) } } -func NewDag(db ptndb.Database,light bool) (*Dag, error) { +func NewDag(db ptndb.Database, light bool) (*Dag, error) { mutex := new(sync.RWMutex) dagDb := storage.NewDagDb(db) @@ -549,9 +548,9 @@ func NewDag(db ptndb.Database,light bool) (*Dag, error) { //hash, idx, _ := stablePropRep.GetLastStableUnit(modules.PTNCOIN) gasToken := dagconfig.DagConfig.GetGasToken() threshold, _ := propRep.GetChainThreshold() - unstableChain := memunit.NewMemDag(gasToken, threshold, light/*false*/, db, unitRep, propRep, stateRep) + unstableChain := memunit.NewMemDag(gasToken, threshold, light /*false*/, db, unitRep, propRep, stateRep) tunitRep, tutxoRep, tstateRep, tpropRep, tUnitProduceRep := unstableChain.GetUnstableRepositories() - validate := validator.NewValidate(tunitRep, tutxoRep, tstateRep, tpropRep) + //validate := validator.NewValidate(tunitRep, tutxoRep, tstateRep, tpropRep) //partitionMemdag := make(map[modules.AssetId]memunit.IMemDag) //for _, ptoken := range dagconfig.DagConfig.GeSyncPartitionTokens() { // partitionMemdag[ptoken] = memunit.NewMemDag(ptoken, true, db, unitRep, propRep, stateRep) @@ -570,10 +569,10 @@ func NewDag(db ptndb.Database,light bool) (*Dag, error) { stableUtxoRep: utxoRep, stableStateRep: stateRep, stableUnitProduceRep: stableUnitProduceRep, - validate: validate, - ChainHeadFeed: new(event.Feed), - Mutex: *mutex, - Memdag: unstableChain, + //validate: validate, + ChainHeadFeed: new(event.Feed), + Mutex: *mutex, + Memdag: unstableChain, //PartitionMemDag: partitionMemdag, } dag.stableUnitRep.SubscribeSysContractStateChangeEvent(dag.AfterSysContractStateChangeEvent) @@ -669,7 +668,7 @@ func NewDag4GenesisInit(db ptndb.Database) (*Dag, error) { utxoRep := dagcommon.NewUtxoRepository(utxoDb, idxDb, stateDb, propDb) unitRep := dagcommon.NewUnitRepository(dagDb, idxDb, utxoDb, stateDb, propDb) - validate := validator.NewValidate(dagDb, utxoRep, stateDb, nil) + //validate := validator.NewValidate(dagDb, utxoRep, stateDb, nil) propRep := dagcommon.NewPropRepository(propDb) stateRep := dagcommon.NewStateRepository(stateDb) @@ -683,9 +682,9 @@ func NewDag4GenesisInit(db ptndb.Database) (*Dag, error) { stablePropRep: propRep, stableStateRep: stateRep, stableUnitProduceRep: statleUnitProduceRep, - validate: validate, - ChainHeadFeed: new(event.Feed), - Mutex: *mutex, + //validate: validate, + ChainHeadFeed: new(event.Feed), + Mutex: *mutex, //Memdag: memunit.NewMemDag(dagDb, stateDb, unstableUnitRep), //utxos_cache: make(map[common.Hash]map[modules.OutPoint]*modules.Utxo), } @@ -708,19 +707,19 @@ func NewDagForTest(db ptndb.Database) (*Dag, error) { statleUnitProduceRep := dagcommon.NewUnitProduceRepository(unitRep, propRep, stateRep) threshold, _ := propRep.GetChainThreshold() - validate := validator.NewValidate(dagDb, utxoRep, stateDb, propRep) + //validate := validator.NewValidate(dagDb, utxoRep, stateDb, propRep) unstableChain := memunit.NewMemDag(modules.PTNCOIN, threshold, false, db, unitRep, propRep, stateRep) tunitRep, tutxoRep, tstateRep, tpropRep, tUnitProduceRep := unstableChain.GetUnstableRepositories() dag := &Dag{ //Cache: freecache.NewCache(200 * 1024 * 1024), - Db: db, - stableUnitRep: unitRep, - stableUtxoRep: utxoRep, - stableStateRep: stateRep, - stablePropRep: propRep, - stableUnitProduceRep: statleUnitProduceRep, - validate: validate, + Db: db, + stableUnitRep: unitRep, + stableUtxoRep: utxoRep, + stableStateRep: stateRep, + stablePropRep: propRep, + stableUnitProduceRep: statleUnitProduceRep, + //validate: validate, ChainHeadFeed: new(event.Feed), Mutex: *mutex, Memdag: unstableChain, diff --git a/dag/dag_mock.go b/dag/dag_mock.go index 09c7b38f4..de1cbf2ca 100644 --- a/dag/dag_mock.go +++ b/dag/dag_mock.go @@ -123,20 +123,6 @@ func (mr *MockIDagMockRecorder) CurrentUnit(token interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentUnit", reflect.TypeOf((*MockIDag)(nil).CurrentUnit), token) } -// VerifyHeader mocks base method -func (m *MockIDag) VerifyHeader(header *modules.Header) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VerifyHeader", header) - ret0, _ := ret[0].(error) - return ret0 -} - -// VerifyHeader indicates an expected call of VerifyHeader -func (mr *MockIDagMockRecorder) VerifyHeader(header interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyHeader", reflect.TypeOf((*MockIDag)(nil).VerifyHeader), header) -} - // GetCurrentUnit mocks base method func (m *MockIDag) GetCurrentUnit(assetId modules.AssetId) *modules.Unit { m.ctrl.T.Helper() @@ -1320,20 +1306,6 @@ func (mr *MockIDagMockRecorder) GetIrreversibleUnitNum(id interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIrreversibleUnitNum", reflect.TypeOf((*MockIDag)(nil).GetIrreversibleUnitNum), id) } -// ValidateUnitExceptPayment mocks base method -func (m *MockIDag) ValidateUnitExceptPayment(unit *modules.Unit) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateUnitExceptPayment", unit) - ret0, _ := ret[0].(error) - return ret0 -} - -// ValidateUnitExceptPayment indicates an expected call of ValidateUnitExceptPayment -func (mr *MockIDagMockRecorder) ValidateUnitExceptPayment(unit interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateUnitExceptPayment", reflect.TypeOf((*MockIDag)(nil).ValidateUnitExceptPayment), unit) -} - // SaveChaincode mocks base method func (m *MockIDag) SaveChaincode(contractId common.Address, cc *list.CCInfo) error { m.ctrl.T.Helper() diff --git a/dag/init_manage.go b/dag/init_manage.go index 0a61ac64f..c87721082 100755 --- a/dag/init_manage.go +++ b/dag/init_manage.go @@ -37,9 +37,10 @@ import ( func (d *Dag) SubscribeToGroupSignEvent(ch chan<- modules.ToGroupSignEvent) event.Subscription { return d.Memdag.SubscribeToGroupSignEvent(ch) } -func (d *Dag) ValidateUnitExceptPayment(unit *modules.Unit) error { - return d.validate.ValidateUnitExceptPayment(unit) -} + +//func (d *Dag) ValidateUnitExceptPayment(unit *modules.Unit) error { +// return d.validate.ValidateUnitExceptPayment(unit) +//} func (d *Dag) IsActiveMediator(add common.Address) bool { return d.GetGlobalProp().IsActiveMediator(add) } diff --git a/dag/interface.go b/dag/interface.go index 2d52b9c69..6e47862ec 100644 --- a/dag/interface.go +++ b/dag/interface.go @@ -42,7 +42,7 @@ type IDag interface { IsEmpty() bool CurrentUnit(token modules.AssetId) *modules.Unit - VerifyHeader(header *modules.Header) error + //VerifyHeader(header *modules.Header) error GetCurrentUnit(assetId modules.AssetId) *modules.Unit GetMainCurrentUnit() *modules.Unit GetCurrentMemUnit(assetId modules.AssetId, index uint64) *modules.Unit @@ -148,7 +148,7 @@ type IDag interface { HeadUnitNum() uint64 HeadUnitHash() common.Hash GetIrreversibleUnitNum(id modules.AssetId) uint64 - ValidateUnitExceptPayment(unit *modules.Unit) error + //ValidateUnitExceptPayment(unit *modules.Unit) error SaveChaincode(contractId common.Address, cc *list.CCInfo) error GetChaincodes(contractId common.Address) (*list.CCInfo, error) diff --git a/dag/memunit/memdag.go b/dag/memunit/memdag.go index 6996e5d2a..2635f1cac 100644 --- a/dag/memunit/memdag.go +++ b/dag/memunit/memdag.go @@ -25,6 +25,7 @@ import ( "sync" "time" + "github.com/coocood/freecache" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/event" "github.com/palletone/go-palletone/common/hexutil" @@ -34,6 +35,7 @@ import ( common2 "github.com/palletone/go-palletone/dag/common" "github.com/palletone/go-palletone/dag/errors" "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/dag/txspool" "github.com/palletone/go-palletone/validator" "go.dedis.ch/kyber/v3/sign/bls" @@ -61,6 +63,7 @@ type MemDag struct { saveHeaderOnly bool lock sync.RWMutex validator validator.Validator + cache palletcache.ICache // append by albert·gou 用于通知群签名 toGroupSignFeed event.Feed toGroupSignScope event.SubscriptionScope @@ -84,6 +87,7 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn stableUnitRep common2.IUnitRepository, propRep common2.IPropRepository, stableStateRep common2.IStateRepository) *MemDag { tempdb, _ := NewTempdb(db) + cache := freecache.NewCache(20 * 1024 * 1024) trep := common2.NewUnitRepository4Db(tempdb) tutxoRep := common2.NewUtxoRepository4Db(tempdb) tstateRep := common2.NewStateRepository4Db(tempdb) @@ -111,7 +115,7 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn } } log.Debugf("Init MemDag[%s], get last stable unit[%s] to set lastMainChainUnit", token.String(), stablehash.String()) - v := validator.NewValidate(trep, tutxoRep, tstateRep, tpropRep) + v := validator.NewValidate(trep, tutxoRep, tstateRep, tpropRep, cache) memdag := &MemDag{ token: token, threshold: threshold, @@ -130,6 +134,7 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn lastMainChainUnit: stableUnit, saveHeaderOnly: saveHeaderOnly, validator: v, + cache: cache, ldbUnitProduceRep: ldbUnitProduceRep, tempUnitProduceRep: tempUnitProduceRep, } @@ -470,10 +475,10 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) error { //Check unit and it's txs are valid //只有主链上添加单元时才能判断整个Unit的有效性 validateCode := validator.TxValidationCode_VALID - if chain.saveHeaderOnly{ - validateCode=chain.validator.ValidateHeader(unit.UnitHeader) - }else { - validateCode=chain.validator.ValidateUnitExceptGroupSig(unit) + if chain.saveHeaderOnly { + validateCode = chain.validator.ValidateHeader(unit.UnitHeader) + } else { + validateCode = chain.validator.ValidateUnitExceptGroupSig(unit) } if validateCode != validator.TxValidationCode_VALID { return validator.NewValidateError(validateCode) diff --git a/dag/txspool/txpool.go b/dag/txspool/txpool.go index f3402cd06..93877b75d 100755 --- a/dag/txspool/txpool.go +++ b/dag/txspool/txpool.go @@ -25,12 +25,14 @@ import ( "sync" "time" + "github.com/coocood/freecache" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/event" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/core" "github.com/palletone/go-palletone/dag/errors" "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/dag/parameter" "github.com/palletone/go-palletone/tokenengine" "github.com/palletone/go-palletone/validator" @@ -179,6 +181,7 @@ type TxPool struct { wg sync.WaitGroup // for shutdown sync quit chan struct{} // used for exit nextExpireScan time.Time + cache palletcache.ICache } type sTxDesc struct { @@ -219,10 +222,11 @@ func NewTxPool(config TxPoolConfig, unit dags) *TxPool { // chainconfig *params. nextExpireScan: time.Now().Add(config.OrphanTTL), orphans: sync.Map{}, outputs: sync.Map{}, + cache: freecache.NewCache(20 * 1024 * 1024), } pool.mu = new(sync.RWMutex) pool.priority_sorted = newTxPrioritiedList(&pool.all) - pool.txValidator = validator.NewValidate(unit, pool, unit, unit) + pool.txValidator = validator.NewValidate(unit, pool, unit, unit, pool.cache) // If local transactions and journaling is enabled, load from disk if !config.NoLocals && config.Journal != "" { log.Info("Journal path:" + config.Journal) diff --git a/ptn/handler.go b/ptn/handler.go index 8938c55ed..caafe8efd 100755 --- a/ptn/handler.go +++ b/ptn/handler.go @@ -267,7 +267,7 @@ func (pm *ProtocolManager) newFetcher() *fetcher.Fetcher { validatorFn := func(unit *modules.Unit) error { //return dagerrors.ErrFutureBlock hash := unit.Hash() - verr := pm.dag.ValidateUnitExceptPayment(unit) + verr := validator.ValidateUnitBasic(unit) if verr != nil && !validator.IsOrphanError(verr) { return verr } diff --git a/validator/interface.go b/validator/interface.go index 0cdce17e3..c3470b51a 100644 --- a/validator/interface.go +++ b/validator/interface.go @@ -37,7 +37,7 @@ type Validator interface { //ValidateTransactions(txs modules.Transactions) error //除了群签名外,验证Unit是否是合法Unit,包括其中的所有交易都会逐一验证 ValidateUnitExceptGroupSig(unit *modules.Unit) ValidationCode - ValidateUnitExceptPayment(unit *modules.Unit) error + //ValidateUnitExceptPayment(unit *modules.Unit) error //验证一个Header是否合法(Mediator签名有效) ValidateHeader(h *modules.Header) ValidationCode ValidateUnitGroupSign(h *modules.Header) error diff --git a/validator/validate_tx_test.go b/validator/validate_tx_test.go index 2ddae017a..64b808b6c 100644 --- a/validator/validate_tx_test.go +++ b/validator/validate_tx_test.go @@ -27,10 +27,12 @@ import ( "log" "testing" + "github.com/coocood/freecache" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/crypto" "github.com/palletone/go-palletone/dag/errors" "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/tokenengine" "github.com/stretchr/testify/assert" "time" @@ -44,10 +46,12 @@ func getAccount() (*ecdsa.PrivateKey, []byte, common.Address) { addr := crypto.PubkeyBytesToAddress(pubKey) return privKey, pubKey, addr } - +func newCache() palletcache.ICache { + return freecache.NewCache(100 * 1024) +} func TestValidate_ValidateTx_EmptyTx_NoPayment(t *testing.T) { tx := &modules.Transaction{} //Empty Tx - validat := NewValidate(nil, nil, nil, nil) + validat := NewValidate(nil, nil, nil, nil, newCache()) _, _, err := validat.ValidateTx(tx, true) assert.NotNil(t, err) t.Log(err) @@ -60,7 +64,7 @@ func TestValidate_ValidateTx_MsgCodeIncorrect(t *testing.T) { tx := &modules.Transaction{} tx.AddMessage(modules.NewMessage(modules.APP_PAYMENT, &modules.DataPayload{MainData: []byte("m")})) - validat := NewValidate(nil, nil, nil, nil) + validat := NewValidate(nil, nil, nil, nil, newCache()) _, _, err := validat.ValidateTx(tx, true) assert.NotNil(t, err) t.Log(err) @@ -209,7 +213,7 @@ func TestValidateDoubleSpendOn1Tx(t *testing.T) { signTx(tx, outPoint) utxoq := &testutxoQuery{} - validate := NewValidate(nil, utxoq, nil, nil) + validate := NewValidate(nil, utxoq, nil, nil, newCache()) _, _, err := validate.ValidateTx(tx, true) assert.Nil(t, err) pay2 := newTestPayment(outPoint, 2) @@ -254,7 +258,7 @@ func TestValidateLargeInputPayment(t *testing.T) { //t.Logf("Signed Tx:%s", string(data)) utxoq := &testutxoQuery{} - validate := NewValidate(nil, utxoq, nil, nil) + validate := NewValidate(nil, utxoq, nil, nil, newCache()) _, _, err := validate.ValidateTx(tx, true) t1 := time.Now() diff --git a/validator/validate_unit.go b/validator/validate_unit.go index 94fee290e..59bbeb732 100755 --- a/validator/validate_unit.go +++ b/validator/validate_unit.go @@ -24,7 +24,6 @@ import ( "fmt" "time" - "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/crypto" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/configure" @@ -37,7 +36,7 @@ import ( 验证unit的签名,需要比对见证人列表 To validate unit's signature, and mediators' signature */ -func (validate *Validate) validateUnitSignature(h *modules.Header) ValidationCode { +func validateUnitSignature(h *modules.Header) ValidationCode { // copy unit's header header := modules.CopyHeader(h) // signature does not contain authors and witness fields @@ -59,7 +58,7 @@ func (validate *Validate) validateUnitSignature(h *modules.Header) ValidationCod // pubKey to pubKey_bytes //pubKey_bytes := crypto.CompressPubkey(pubKey) - if pass,_:=crypto.MyCryptoLib.Verify(h.Authors.PubKey, h.Authors.Signature, hash.Bytes());!pass { + if pass, _ := crypto.MyCryptoLib.Verify(h.Authors.PubKey, h.Authors.Signature, hash.Bytes()); !pass { log.Debug("Verify unit signature error.") return UNIT_STATE_INVALID_AUTHOR_SIGNATURE } @@ -121,24 +120,54 @@ func (validate *Validate) validateMediatorSchedule(header *modules.Header) Valid return TxValidationCode_VALID } -func (validate *Validate) ValidateUnitExceptPayment(unit *modules.Unit) error { - unitHeaderValidateResult := validate.validateHeaderExceptGroupSig(unit.UnitHeader) - if unitHeaderValidateResult != TxValidationCode_VALID && - unitHeaderValidateResult != UNIT_STATE_AUTHOR_SIGNATURE_PASSED && - unitHeaderValidateResult != UNIT_STATE_ORPHAN { - log.Debug("Validate unit's header failed.", "error code", unitHeaderValidateResult) - return NewValidateError(unitHeaderValidateResult) + +//不基于数据库,进行Unit最基本的验证 +func ValidateUnitBasic(unit *modules.Unit) error { + return NewValidateError(validateUnitBasic(unit)) +} + +//不基于数据库,进行Unit最基本的验证 +func validateUnitBasic(unit *modules.Unit) ValidationCode { + header := unit.UnitHeader + if header == nil { + log.Info("header is nil.") + return UNIT_STATE_INVALID_HEADER + } + + if len(header.ParentsHash) == 0 { + log.Info("the header's parentHash is null.") + return UNIT_STATE_INVALID_HEADER + } + + // check header's extra data + if uint64(len(header.Extra)) > configure.MaximumExtraDataSize { + msg := fmt.Sprintf("extra-data too long: %d > %d", len(header.Extra), configure.MaximumExtraDataSize) + log.Info(msg) + return UNIT_STATE_INVALID_EXTRA_DATA + } + + // check creation_time + if header.Time <= modules.UNIT_CREATION_DATE_INITIAL_UINT64 { + return UNIT_STATE_INVALID_HEADER_TIME + } + + // check header's number + if header.Number == nil { + return UNIT_STATE_INVALID_HEADER_NUMBER + } + var thisUnitIsNotTransmitted bool + if thisUnitIsNotTransmitted { + sigState := validateUnitSignature(header) + return sigState } //validate tx root root := core.DeriveSha(unit.Txs) if root != unit.UnitHeader.TxRoot { log.Debugf("Validate unit's header failed, root:[%#x], unit.UnitHeader.TxRoot:[%#x], txs:[%#x]", root, unit.UnitHeader.TxRoot, unit.Txs.GetTxIds()) - return NewValidateError(UNIT_STATE_INVALID_HEADER_TXROOT) - } - if unitHeaderValidateResult != TxValidationCode_VALID { - return NewValidateError(unitHeaderValidateResult) + return UNIT_STATE_INVALID_HEADER_TXROOT } - return nil + + return TxValidationCode_VALID } /** @@ -147,8 +176,8 @@ Validate unit(除群签名以外), 新生产的unit暂时还没有群签名 */ //func (validate *Validate) ValidateUnit(unit *modules.Unit, isGenesis bool) byte { func (validate *Validate) ValidateUnitExceptGroupSig(unit *modules.Unit) ValidationCode { - unitHash:=unit.Hash() - if has,code:=validate.cache.HasUnitValidateResult(unitHash);has{ + unitHash := unit.Hash() + if has, code := validate.cache.HasUnitValidateResult(unitHash); has { return code } start := time.Now() @@ -182,7 +211,7 @@ func (validate *Validate) ValidateUnitExceptGroupSig(unit *modules.Unit) Validat if unitHeaderValidateResult != TxValidationCode_VALID { return (unitHeaderValidateResult) } - validate.cache.AddUnitValidateResult(unitHash,TxValidationCode_VALID) + validate.cache.AddUnitValidateResult(unitHash, TxValidationCode_VALID) return TxValidationCode_VALID } @@ -204,11 +233,11 @@ func (validate *Validate) validateHeaderExceptGroupSig(header *modules.Header) V return UNIT_STATE_INVALID_EXTRA_DATA } - // check txroot - if header.TxRoot == (common.Hash{}) { - log.Info("the header's txroot is null.") - return UNIT_STATE_INVALID_HEADER_TXROOT - } + // Only check txroot when has unit body + //if header.TxRoot == (common.Hash{}) { + // log.Info("the header's txroot is null.") + // return UNIT_STATE_INVALID_HEADER_TXROOT + //} // check creation_time if header.Time <= modules.UNIT_CREATION_DATE_INITIAL_UINT64 { @@ -221,7 +250,7 @@ func (validate *Validate) validateHeaderExceptGroupSig(header *modules.Header) V } var thisUnitIsNotTransmitted bool if thisUnitIsNotTransmitted { - sigState := validate.validateUnitSignature(header) + sigState := validateUnitSignature(header) return sigState } @@ -245,9 +274,10 @@ func (validate *Validate) validateHeaderExceptGroupSig(header *modules.Header) V } func (validate *Validate) ValidateHeader(h *modules.Header) ValidationCode { - hash:=h.Hash() - if validate.cache.HasHeaderValidateResult(hash){ - return TxValidationCode_VALID + hash := h.Hash() + has, code := validate.cache.HasHeaderValidateResult(hash) + if has { + return code } unitHeaderValidateResult := validate.validateHeaderExceptGroupSig(h) if unitHeaderValidateResult != TxValidationCode_VALID && @@ -256,8 +286,8 @@ func (validate *Validate) ValidateHeader(h *modules.Header) ValidationCode { log.Debug("Validate unit's header failed.", "error code", unitHeaderValidateResult) return unitHeaderValidateResult } - if unitHeaderValidateResult==TxValidationCode_VALID{ - validate.cache.AddHeaderValidateResult(hash) + if unitHeaderValidateResult == TxValidationCode_VALID { + validate.cache.AddHeaderValidateResult(hash, unitHeaderValidateResult) } return TxValidationCode_VALID } diff --git a/validator/validator.go b/validator/validator.go index 141c66679..7be93bb7c 100755 --- a/validator/validator.go +++ b/validator/validator.go @@ -21,16 +21,15 @@ package validator import ( - "sync" - "encoding/json" "fmt" - "github.com/coocood/freecache" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/dag/dagconfig" "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/dag/parameter" + "sync" ) type Validate struct { @@ -43,8 +42,8 @@ type Validate struct { const MAX_DATA_PAYLOAD_MAIN_DATA_SIZE = 128 -func NewValidate(dagdb IDagQuery, utxoRep IUtxoQuery, statedb IStateQuery, propquery IPropQuery) *Validate { - cache := freecache.NewCache(20 * 1024 * 1024) +func NewValidate(dagdb IDagQuery, utxoRep IUtxoQuery, statedb IStateQuery, propquery IPropQuery, cache palletcache.ICache) *Validate { + //cache := freecache.NewCache(20 * 1024 * 1024) vcache := NewValidatorCache(cache) return &Validate{cache: vcache, dagquery: dagdb, utxoquery: utxoRep, statequery: statedb, propquery: propquery} } diff --git a/validator/validator_cache.go b/validator/validator_cache.go index 03bbb3f77..0b586836f 100644 --- a/validator/validator_cache.go +++ b/validator/validator_cache.go @@ -34,7 +34,9 @@ type ValidatorCache struct { cache palletcache.ICache } -var prefix = []byte("VA") +var expireSeconds = 60 +var prefixTx = []byte("VT") +var prefixUnit = []byte("VU") var prefixHeader = []byte("VH") func NewValidatorCache(cache palletcache.ICache) *ValidatorCache { @@ -45,42 +47,42 @@ func (s *ValidatorCache) AddTxValidateResult(txId common.Hash, validateResult [] if err != nil { log.Errorf("Json marsal struct fail,error:%s", err.Error()) } - s.cache.Set(append(prefix, txId.Bytes()...), data, 60) + s.cache.Set(append(prefixTx, txId.Bytes()...), data, expireSeconds) } func (s *ValidatorCache) HasTxValidateResult(txId common.Hash) (bool, []*modules.Addition) { - data, err := s.cache.Get(append(prefix, txId.Bytes()...)) + data, err := s.cache.Get(append(prefixTx, txId.Bytes()...)) if err != nil { return false, nil } result := []*modules.Addition{} json.Unmarshal(data, &result) - log.Debugf("Validate cache has tx hash:%s",txId.String()) + log.Debugf("Validate cache has tx hash:%s", txId.String()) return true, result } -func (s *ValidatorCache) AddUnitValidateResult(unitHash common.Hash,code ValidationCode) { +func (s *ValidatorCache) AddUnitValidateResult(unitHash common.Hash, code ValidationCode) { - s.cache.Set(append(prefix, unitHash.Bytes()...), []byte{byte(code)}, 60) + s.cache.Set(append(prefixUnit, unitHash.Bytes()...), []byte{byte(code)}, expireSeconds) } -func (s *ValidatorCache) HasUnitValidateResult(unitHash common.Hash) (bool,ValidationCode) { - data, err := s.cache.Get(append(prefix, unitHash.Bytes()...)) +func (s *ValidatorCache) HasUnitValidateResult(unitHash common.Hash) (bool, ValidationCode) { + data, err := s.cache.Get(append(prefixUnit, unitHash.Bytes()...)) if err != nil { - return false,TxValidationCode_NOT_VALIDATED + return false, TxValidationCode_NOT_VALIDATED } - log.Debugf("Validate cache has unit hash:%s",unitHash.String()) + log.Debugf("Validate cache has unit hash:%s", unitHash.String()) return true, ValidationCode(data[0]) } -func (s *ValidatorCache) AddHeaderValidateResult(unitHash common.Hash) { +func (s *ValidatorCache) AddHeaderValidateResult(unitHash common.Hash, code ValidationCode) { - s.cache.Set(append(prefixHeader, unitHash.Bytes()...), []byte{0x1}, 60) + s.cache.Set(append(prefixHeader, unitHash.Bytes()...), []byte{byte(code)}, expireSeconds) } -func (s *ValidatorCache) HasHeaderValidateResult(unitHash common.Hash) bool { - _, err := s.cache.Get(append(prefixHeader, unitHash.Bytes()...)) +func (s *ValidatorCache) HasHeaderValidateResult(unitHash common.Hash) (bool, ValidationCode) { + data, err := s.cache.Get(append(prefixHeader, unitHash.Bytes()...)) if err != nil { - return false + return false, TxValidationCode_NOT_VALIDATED } - log.Debugf("Validate cache has header hash:%s",unitHash.String()) - return true + log.Debugf("Validate cache has header hash:%s", unitHash.String()) + return true, ValidationCode(data[0]) } diff --git a/validator/validator_test.go b/validator/validator_test.go index 2cf161241..ecd23f06e 100644 --- a/validator/validator_test.go +++ b/validator/validator_test.go @@ -49,7 +49,7 @@ func TestValidate_ValidateUnitTxs(t *testing.T) { utxoQuery := &mockUtxoQuery{} mockStatedbQuery := &mockStatedbQuery{} - validate := NewValidate(nil, utxoQuery, mockStatedbQuery, nil) + validate := NewValidate(nil, utxoQuery, mockStatedbQuery, nil, newCache()) addr, _ := common.StringToAddress("P1HXNZReTByQHgWQNGMXotMyTkMG9XeEQfX") code := validate.validateTransactions(txs, time.Now().Unix(), addr) assert.Equal(t, code, TxValidationCode_VALID) @@ -226,7 +226,7 @@ func TestValidate_ValidateHeader(t *testing.T) { tx := newTx1(t) header := newHeader(modules.Transactions{tx}) - v := NewValidate(nil, nil, nil, nil) + v := NewValidate(nil, nil, nil, nil, newCache()) vresult := v.validateHeaderExceptGroupSig(header) t.Log(vresult) assert.Equal(t, vresult, TxValidationCode_VALID) From fc76fda5ccf69d4c01c7f6c688258892a573fa57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Wed, 10 Jul 2019 18:03:02 +0800 Subject: [PATCH 02/44] Update mediator_connection.go --- ptn/mediator_connection.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ptn/mediator_connection.go b/ptn/mediator_connection.go index 893ae074b..dd53228e0 100755 --- a/ptn/mediator_connection.go +++ b/ptn/mediator_connection.go @@ -121,6 +121,7 @@ func (pm *ProtocolManager) checkConnectedAndSynced() { } // 2. 是否和所有其他活跃mediator节点相连完成 + headNum := pm.dag.HeadUnitNum() checkFn := func() bool { nodes := pm.dag.GetActiveMediatorNodes() for id, node := range nodes { @@ -134,10 +135,9 @@ func (pm *ProtocolManager) checkConnectedAndSynced() { return false } - headHash := pm.dag.HeadUnitHash() gasToken := dagconfig.DagConfig.GetGasToken() - pHeadHash, _ := peer.Head(gasToken) - if common.EmptyHash(pHeadHash) || headHash != pHeadHash { + _, pHeadNum := peer.Head(gasToken) + if pHeadNum == nil || pHeadNum.Index < headNum { return false } } From 27f07b5d371dd6249fcc5666883a0a4808810611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Wed, 10 Jul 2019 18:16:36 +0800 Subject: [PATCH 03/44] reduce the limit on starting the vss protocol --- ptn/mediator_connection.go | 15 ++++++++------- ptn/message.go | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/ptn/mediator_connection.go b/ptn/mediator_connection.go index dd53228e0..1d4ae5538 100755 --- a/ptn/mediator_connection.go +++ b/ptn/mediator_connection.go @@ -26,7 +26,6 @@ import ( "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/common/p2p/discover" mp "github.com/palletone/go-palletone/consensus/mediatorplugin" - "github.com/palletone/go-palletone/dag/dagconfig" "github.com/palletone/go-palletone/dag/modules" ) @@ -121,7 +120,8 @@ func (pm *ProtocolManager) checkConnectedAndSynced() { } // 2. 是否和所有其他活跃mediator节点相连完成 - headNum := pm.dag.HeadUnitNum() + //headNum := pm.dag.HeadUnitNum() + //gasToken := dagconfig.DagConfig.GetGasToken() checkFn := func() bool { nodes := pm.dag.GetActiveMediatorNodes() for id, node := range nodes { @@ -135,14 +135,15 @@ func (pm *ProtocolManager) checkConnectedAndSynced() { return false } - gasToken := dagconfig.DagConfig.GetGasToken() - _, pHeadNum := peer.Head(gasToken) - if pHeadNum == nil || pHeadNum.Index < headNum { - return false - } + // todo Albert 待使用 + //_, pHeadNum := peer.Head(gasToken) + //if pHeadNum == nil || pHeadNum.Index < headNum { + // return false + //} } log.Debugf("connected with all active mediator peers") + //log.Debugf("connected with all active mediator peers, all all peers synced") return true } diff --git a/ptn/message.go b/ptn/message.go index b85f0b65b..0add351cb 100755 --- a/ptn/message.go +++ b/ptn/message.go @@ -370,7 +370,7 @@ func (pm *ProtocolManager) NewBlockMsg(msg p2p.Msg, p *peer) error { unit.Author().Str()) latency := time.Now().Sub(timestamp) - if latency < -3*time.Second { + if latency < -5*time.Second { errStr := fmt.Sprintf("Rejecting unit #%v with timestamp(%v) in the future signed by %v", unit.NumberU64(), timestamp.Format("2006-01-02 15:04:05"), unit.Author().Str()) log.Debugf(errStr) From dccbf91f024e2ea7b34cb532122cf1dea6ab7884 Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Wed, 10 Jul 2019 18:44:21 +0800 Subject: [PATCH 04/44] Fix bug when got the error logs of container --- contracts/core/chaincode_support.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/core/chaincode_support.go b/contracts/core/chaincode_support.go index b2c28686b..7b4fc9859 100755 --- a/contracts/core/chaincode_support.go +++ b/contracts/core/chaincode_support.go @@ -894,6 +894,7 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, cccid *c Follow: true, Stdout: true, Stderr: true, + Tail: "30", } err = client.Logs(logsO) if err != nil { @@ -905,7 +906,6 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, cccid *c line, _ := buf.ReadString('\n') line = strings.TrimSpace(line) if strings.Contains(line, "panic: runtime error") || strings.Contains(line, "fatal error: runtime") { - err = errors.New(line) } else { //log.Info("===================2=================timeout expired while executing transaction") From 6939d479ca97ceaa174c68a25435d1caf622ba6d Mon Sep 17 00:00:00 2001 From: etying Date: Wed, 10 Jul 2019 18:58:38 -0700 Subject: [PATCH 05/44] modify Full protocal Fetcher loop --- ptn/fetcher/fetcher.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ptn/fetcher/fetcher.go b/ptn/fetcher/fetcher.go index 68fd33c34..17f5d6a3b 100755 --- a/ptn/fetcher/fetcher.go +++ b/ptn/fetcher/fetcher.go @@ -292,22 +292,22 @@ func (f *Fetcher) loop() { } } // Import any queued blocks that could potentially fit - var height uint64 + //var height uint64 for !f.queue.Empty() { op := f.queue.PopItem().(*inject) if f.queueChangeHook != nil { f.queueChangeHook(op.unit.UnitHash, false) } // If too high up the chain or phase, continue later - height = f.chainHeight(op.unit.Header().ChainIndex().AssetID) - number := op.unit.NumberU64() - if number > height+1 { - f.queue.Push(op, -float32(op.unit.NumberU64())) - if f.queueChangeHook != nil { - f.queueChangeHook(op.unit.Hash(), true) - } - break - } + //height = f.chainHeight(op.unit.Header().ChainIndex().AssetID) + //number := op.unit.NumberU64() + //if number > height+1 { + // f.queue.Push(op, -float32(op.unit.NumberU64())) + // if f.queueChangeHook != nil { + // f.queueChangeHook(op.unit.Hash(), true) + // } + // break + //} // Otherwise if fresh and still unknown, try and import hash := op.unit.Hash() //block, _ := f.isHeaderExist(hash) From 21d77432cc924bc3876a752bd29ce642305e04ee Mon Sep 17 00:00:00 2001 From: etying Date: Wed, 10 Jul 2019 20:26:28 -0700 Subject: [PATCH 06/44] modify NewBlockMsg --- ptn/message.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ptn/message.go b/ptn/message.go index 0add351cb..3c8633d66 100755 --- a/ptn/message.go +++ b/ptn/message.go @@ -355,16 +355,9 @@ func (pm *ProtocolManager) NewBlockMsg(msg p2p.Msg, p *peer) error { return nil } - unitHash := unit.Hash() - if pm.IsExistInCache(unitHash.Bytes()) { - //log.Debugf("Received unit(%v) again, ignore it", unitHash.TerminalString()) - p.MarkUnit(unitHash) - p.SetHead(unitHash, unit.Number()) - return nil - } - // append by Albert·Gou timestamp := time.Unix(unit.Timestamp(), 0) + unitHash := unit.Hash() log.Debugf("Received unit(%v) #%v parent(%v) @%v signed by %v", unitHash.TerminalString(), unit.NumberU64(), unit.ParentHash()[0].TerminalString(), timestamp.Format("2006-01-02 15:04:05"), unit.Author().Str()) @@ -377,6 +370,13 @@ func (pm *ProtocolManager) NewBlockMsg(msg p2p.Msg, p *peer) error { return fmt.Errorf(errStr) } + if pm.IsExistInCache(unitHash.Bytes()) { + //log.Debugf("Received unit(%v) again, ignore it", unitHash.TerminalString()) + p.MarkUnit(unitHash) + p.SetHead(unitHash, unit.Number()) + return nil + } + log.DebugDynamic(func() string { txids := []common.Hash{} for _, tx := range unit.Txs { From 9c2bb2236ea6f85e4643d8b87f8c861844f838d3 Mon Sep 17 00:00:00 2001 From: etying Date: Wed, 10 Jul 2019 20:31:04 -0700 Subject: [PATCH 07/44] modify light protocal AnnounceMsg --- light/message.go | 1 + 1 file changed, 1 insertion(+) diff --git a/light/message.go b/light/message.go index b37721146..dd26af825 100644 --- a/light/message.go +++ b/light/message.go @@ -51,6 +51,7 @@ func (pm *ProtocolManager) AnnounceMsg(msg p2p.Msg, p *peer) error { if pm.IsExistInCache(req.Header.Hash().Bytes()) { //log.Debugf("Received unit(%v) again, ignore it", unitHash.TerminalString()) + p.SetHead(&req) return nil } From c82d84e6cf12c777de976cbbfc70f15a5df290aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Thu, 11 Jul 2019 11:57:39 +0800 Subject: [PATCH 08/44] Update mediator_api.go --- internal/ptnapi/mediator_api.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/internal/ptnapi/mediator_api.go b/internal/ptnapi/mediator_api.go index 8b8b8dbbc..883c9eeef 100755 --- a/internal/ptnapi/mediator_api.go +++ b/internal/ptnapi/mediator_api.go @@ -231,6 +231,11 @@ func (a *PrivateMediatorAPI) Apply(args MediatorCreateArgs) (*TxExecuteResult, e return nil, err } + // 判断本节点是否同步完成,数据是否最新 + if !a.Dag().IsSynced() { + return nil, fmt.Errorf("this node is not synced, and can't apply mediator now") + } + addr := args.FeePayer() // 判断是否已经是mediator if a.Dag().IsMediator(addr) { @@ -276,6 +281,11 @@ func (a *PrivateMediatorAPI) PayDeposit(from string, amount decimal.Decimal) (*T return nil, fmt.Errorf("the amount of the deposit must be greater than 0") } + // 判断本节点是否同步完成,数据是否最新 + if !a.Dag().IsSynced() { + return nil, fmt.Errorf("this node is not synced, and can't pay deposit now") + } + // 调用系统合约 cArgs := [][]byte{[]byte(modules.MediatorPayDeposit)} //fee := a.Dag().CurrentFeeSchedule().TransferFee.BaseFee @@ -305,6 +315,11 @@ func (a *PrivateMediatorAPI) WithdrawDeposit(medAddStr string, amount decimal.De return nil, fmt.Errorf("invalid account address: %v", medAddStr) } + // 判断本节点是否同步完成,数据是否最新 + if !a.Dag().IsSynced() { + return nil, fmt.Errorf("this node is not synced, and can't withdraw deposit now") + } + // 判断是否是mediator if !a.Dag().IsMediator(medAdd) { return nil, fmt.Errorf("account %v is not a mediator", medAddStr) @@ -345,6 +360,11 @@ func (a *PrivateMediatorAPI) Quit(medAddStr string) (*TxExecuteResult, error) { return nil, fmt.Errorf("invalid account address: %v", medAddStr) } + // 判断本节点是否同步完成,数据是否最新 + if !a.Dag().IsSynced() { + return nil, fmt.Errorf("this node is not synced, and can't quit now") + } + // 判断是否是mediator if !a.Dag().IsMediator(medAdd) { return nil, fmt.Errorf("account %v is not a mediator", medAddStr) @@ -380,7 +400,7 @@ func (a *PrivateMediatorAPI) Vote(voterStr string, mediatorStrs []string) (*TxEx // 判断本节点是否同步完成,数据是否最新 if !a.Dag().IsSynced() { - return nil, fmt.Errorf("the data of this node is not synced, and can't vote now") + return nil, fmt.Errorf("this node is not synced, and can't vote now") } maxMediatorCount := int(a.Dag().GetChainParameters().MaximumMediatorCount) From 849c2cb5c7b3fbd37b2ac5f318716f90613259f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Thu, 11 Jul 2019 12:56:46 +0800 Subject: [PATCH 09/44] Update prop_repository.go --- dag/common/prop_repository.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/dag/common/prop_repository.go b/dag/common/prop_repository.go index c99f2fd2d..958c8de45 100755 --- a/dag/common/prop_repository.go +++ b/dag/common/prop_repository.go @@ -22,6 +22,7 @@ package common import ( "time" + "encoding/binary" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/common/ptndb" @@ -134,15 +135,15 @@ func (pRep *PropRepository) GetNewestUnitTimestamp(token modules.AssetId) (int64 func (pRep *PropRepository) UpdateMediatorSchedule(ms *modules.MediatorSchedule, gp *modules.GlobalProperty, dgp *modules.DynamicGlobalProperty) bool { token := dagconfig.DagConfig.GetGasToken() - _, idx, timestamp, err := pRep.db.GetNewestUnit(token) + hash, idx, _, err := pRep.db.GetNewestUnit(token) if err != nil { - log.Debug("GetNewestUnit error:" + err.Error()) + log.Debugf("GetNewestUnit error:" + err.Error()) return false } aSize := uint64(len(gp.ActiveMediators)) if aSize == 0 { - log.Debug("The current number of active mediators is 0!") + log.Debugf("the current number of active mediators is 0") return false } @@ -161,11 +162,12 @@ func (pRep *PropRepository) UpdateMediatorSchedule(ms *modules.MediatorSchedule, } // 4. 打乱证人的调度顺序 - Shuffle(ms.CurrentShuffledMediators, uint64(timestamp)) + shuffleMediators(ms.CurrentShuffledMediators, binary.BigEndian.Uint64(hash[8:])) return true } -func Shuffle(mediators []common.Address, timestamp uint64) { - nowHi := uint64(timestamp << 32) + +func shuffleMediators(mediators []common.Address, seed uint64) { + nowHi := uint64(seed << 32) aSize := len(mediators) for i := 0; i < aSize; i++ { // 高性能随机生成器(High performance random generator) From 79ee0bf071f8ddf9c14bb34b674d3076477c4cf6 Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Thu, 11 Jul 2019 16:32:24 +0800 Subject: [PATCH 10/44] =?UTF-8?q?Add=20description=E3=80=81abi=E3=80=81lan?= =?UTF-8?q?guage=20params=20for=20ccinstalltx=20func?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contracts/core/chaincode_support.go | 12 +- contracts/core/chaincodeexec.go | 3 +- contracts/core/exectransaction.go | 2 + contracts/core/handler.go | 202 ++++++++++++---------------- contracts/manger/ccapi.go | 8 +- contracts/manger/endorser.go | 6 + contracts/manger/support.go | 3 + contracts/shim/chaincode.go | 1 + internal/ptnapi/contract_api.go | 15 ++- internal/web3ext/contractjs.go | 4 +- 10 files changed, 126 insertions(+), 130 deletions(-) diff --git a/contracts/core/chaincode_support.go b/contracts/core/chaincode_support.go index 7b4fc9859..cc518506f 100755 --- a/contracts/core/chaincode_support.go +++ b/contracts/core/chaincode_support.go @@ -302,11 +302,11 @@ func (chaincodeSupport *ChaincodeSupport) registerHandler(chaincodehandler *Hand func (chaincodeSupport *ChaincodeSupport) deregisterHandler(chaincodehandler *Handler) error { // clean up queryIteratorMap - for _, txcontext := range chaincodehandler.txCtxs { - for _, v := range txcontext.queryIteratorMap { - v.Close() - } - } + //for _, txcontext := range chaincodehandler.txCtxs { + // for _, v := range txcontext.queryIteratorMap { + // v.Close() + // } + //} key := chaincodehandler.ChaincodeID.Name log.Debugf("Deregister handler: %s", key) @@ -681,6 +681,7 @@ func (chaincodeSupport *ChaincodeSupport) Destory(context context.Context, cccid // Launch will launch the chaincode if not running (if running return nil) and will wait for handler of the chaincode to get into FSM ready state. func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, cccid *ccprovider.CCContext, spec interface{}) (*pb.ChaincodeID, *pb.ChaincodeInput, error) { + log.Debugf("launch enter") //build the chaincode var cID *pb.ChaincodeID var cMsg *pb.ChaincodeInput @@ -847,6 +848,7 @@ func createCCMessage(contractid []byte, typ pb.ChaincodeMessage_Type, cid string // Execute executes a transaction and waits for it to complete until a timeout value. func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, cccid *ccprovider.CCContext, msg *pb.ChaincodeMessage, timeout time.Duration) (*pb.ChaincodeMessage, error) { + log.Debugf("chain code support execute") log.Debugf("Entry, chainId[%s], txid[%s]", msg.ChannelId, msg.Txid) defer log.Debugf("Exit") //glh diff --git a/contracts/core/chaincodeexec.go b/contracts/core/chaincodeexec.go index c84db6728..8c9dce724 100755 --- a/contracts/core/chaincodeexec.go +++ b/contracts/core/chaincodeexec.go @@ -108,6 +108,7 @@ func GetChaincodeDefinition(ctxt context.Context, txid string, signedProp *pb.Si // ExecuteChaincode executes a given chaincode given chaincode name and arguments func ExecuteChaincode(ctxt context.Context, cccid *ccprovider.CCContext, args [][]byte, timeout time.Duration) (*pb.Response, *pb.ChaincodeEvent, error) { + log.Debugf("execute chain code") var spec *pb.ChaincodeInvocationSpec var err error var res *pb.Response @@ -117,7 +118,7 @@ func ExecuteChaincode(ctxt context.Context, cccid *ccprovider.CCContext, args [] res, ccevent, err = Execute(ctxt, cccid, spec, timeout) if err != nil { err = errors.WithMessage(err, "error executing chaincode") - log.Errorf("%+v", err) + log.Errorf("execute %+v", err) return nil, nil, err } diff --git a/contracts/core/exectransaction.go b/contracts/core/exectransaction.go index c8934d956..c42854a7a 100755 --- a/contracts/core/exectransaction.go +++ b/contracts/core/exectransaction.go @@ -35,6 +35,7 @@ import ( //Execute - execute proposal, return original response of chaincode func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{}, timeout time.Duration) (*pb.Response, *pb.ChaincodeEvent, error) { + log.Debugf("execute enter") var err error var cds *pb.ChaincodeDeploymentSpec var ci *pb.ChaincodeInvocationSpec @@ -63,6 +64,7 @@ func Execute(ctxt context.Context, cccid *ccprovider.CCContext, spec interface{} } resp, err := theChaincodeSupport.Execute(ctxt, cccid, ccMsg, timeout) //theChaincodeSupport.executetimeout + log.Debugf("resp") if err != nil { // Rollback transaction return nil, nil, errors.WithMessage(err, "failed to execute transaction") diff --git a/contracts/core/handler.go b/contracts/core/handler.go index e3775afa2..ea65fd2c2 100755 --- a/contracts/core/handler.go +++ b/contracts/core/handler.go @@ -23,7 +23,6 @@ package core import ( "bytes" "fmt" - "github.com/palletone/go-palletone/contracts/syscontract" "io" "sync" "time" @@ -37,7 +36,7 @@ import ( cfg "github.com/palletone/go-palletone/contracts/contractcfg" "github.com/palletone/go-palletone/contracts/outchain" "github.com/palletone/go-palletone/core/vmContractPub/ccprovider" - commonledger "github.com/palletone/go-palletone/core/vmContractPub/ledger" + //commonledger "github.com/palletone/go-palletone/core/vmContractPub/ledger" pb "github.com/palletone/go-palletone/core/vmContractPub/protos/peer" "github.com/palletone/go-palletone/core/vmContractPub/sysccprovider" "github.com/palletone/go-palletone/core/vmContractPub/util" @@ -65,16 +64,16 @@ type transactionContext struct { responseNotifier chan *pb.ChaincodeMessage // tracks open iterators used for range queries - queryIteratorMap map[string]commonledger.ResultsIterator - pendingQueryResults map[string]*pendingQueryResult + //queryIteratorMap map[string]commonledger.ResultsIterator + //pendingQueryResults map[string]*pendingQueryResult txsimulator rwset.TxSimulator } -type pendingQueryResult struct { - batch []*pb.QueryResultBytes - count int -} +//type pendingQueryResult struct { +// batch []*pb.QueryResultBytes +// count int +//} type nextStateInfo struct { msg *pb.ChaincodeMessage @@ -225,7 +224,7 @@ func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStre {Name: pb.ChaincodeMessage_PAY_OUT_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_SUPPLY_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_DEFINE_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, - {Name: pb.ChaincodeMessage_GET_CERT_STATE.String(), Src: []string{readystate}, Dst: readystate}, + //{Name: pb.ChaincodeMessage_GET_CERT_STATE.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_SEND_JURY.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_RECV_JURY.String(), Src: []string{readystate}, Dst: readystate}, }, @@ -256,30 +255,30 @@ func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStre "after_" + pb.ChaincodeMessage_PAY_OUT_TOKEN.String(): func(e *fsm.Event) { v.enterPayOutToken(e) }, "after_" + pb.ChaincodeMessage_DEFINE_TOKEN.String(): func(e *fsm.Event) { v.enterDefineToken(e) }, "after_" + pb.ChaincodeMessage_SUPPLY_TOKEN.String(): func(e *fsm.Event) { v.enterSupplyToken(e) }, - "after_" + pb.ChaincodeMessage_GET_CERT_STATE.String(): func(e *fsm.Event) { v.enterGetCertByID(e) }, + //"after_" + pb.ChaincodeMessage_GET_CERT_STATE.String(): func(e *fsm.Event) { v.enterGetCertByID(e) }, }, ) return v } -func (p *pendingQueryResult) cut() []*pb.QueryResultBytes { - batch := p.batch - p.batch = nil - p.count = 0 - return batch -} - -func (p *pendingQueryResult) add(queryResult commonledger.QueryResult) error { - queryResultBytes, err := proto.Marshal(queryResult.(proto.Message)) - if err != nil { - log.Errorf("Failed to get encode query result as bytes") - return err - } - p.batch = append(p.batch, &pb.QueryResultBytes{ResultBytes: queryResultBytes}) - p.count = len(p.batch) - return nil -} +//func (p *pendingQueryResult) cut() []*pb.QueryResultBytes { +// batch := p.batch +// p.batch = nil +// p.count = 0 +// return batch +//} +// +//func (p *pendingQueryResult) add(queryResult commonledger.QueryResult) error { +// queryResultBytes, err := proto.Marshal(queryResult.(proto.Message)) +// if err != nil { +// log.Errorf("Failed to get encode query result as bytes") +// return err +// } +// p.batch = append(p.batch, &pb.QueryResultBytes{ResultBytes: queryResultBytes}) +// p.count = len(p.batch) +// return nil +//} func (handler *Handler) enterGetSystemConfig(e *fsm.Event) { msg, ok := e.Args[0].(*pb.ChaincodeMessage) @@ -320,38 +319,6 @@ func (handler *Handler) enterGetSystemConfig(e *fsm.Event) { return } chaincodeID := handler.getCCRootName() - - //TODO 通过 keyForSystemConfig 获取相应的系统的配置 - //var payloadBytes []byte - //var err error - //systemConfig := &core.SystemConfig{ - // FoundationAddress: "P1N4hGvGhjzfxmXGGKSFRL2vWZnSCXYojZU", - // DepositAmountForMediator: 2000, - // DepositAmountForJury: 1000, - // DepositAmountForDeveloper: 800, - // DepositRate: 0.02, - // DepositPeriod: 0, - //} - //res, err := txContext.txsimulator.GetState(msg.ContractId, chaincodeID, keyForSystemConfig.Key) - //payloadBytes, err := txContext.txsimulator.GetConfig(keyForSystemConfig.Key) - - //fmt.Println("keyForSystemConfig.Key = ", keyForSystemConfig.Key) - //if strings.Compare("DepositAmountForJury", keyForSystemConfig.Key) == 0 { - // depositAmount := strconv.FormatUint(systemConfig.DepositAmountForJury, 10) - // - // payloadBytes = []byte(depositAmount) - //} else if strings.Compare("FoundationAddress", keyForSystemConfig.Key) == 0 { - // payloadBytes = []byte(systemConfig.FoundationAddress) - //} else if strings.Compare("DepositAmountForMediator", keyForSystemConfig.Key) == 0 { - // depositAmount := strconv.FormatUint(systemConfig.DepositAmountForMediator, 10) - // payloadBytes = []byte(depositAmount) - //} else if strings.Compare("DepositAmountForDeveloper", keyForSystemConfig.Key) == 0 { - // depositAmount := strconv.FormatUint(systemConfig.DepositAmountForDeveloper, 10) - // payloadBytes = []byte(depositAmount) - //} else if strings.Compare("DepositPeriod", keyForSystemConfig.Key) == 0 { - // payloadBytes = []byte(strconv.Itoa(systemConfig.DepositPeriod)) - //} - //chaincodeID := handler.getCCRootName() log.Debugf("[%s] getting state for chaincode %s, channel %s", shorttxid(msg.Txid), chaincodeID, msg.ChannelId) payloadBytes, err := txContext.txsimulator.GetChainParameters() @@ -484,10 +451,10 @@ func (handler *Handler) createTxContext(ctxt context.Context, chainID string, tx return nil, errors.Errorf("txid: %s(%s) exists", txid, chainID) } txctx := &transactionContext{chainID: chainID, signedProp: signedProp, - proposal: prop, responseNotifier: make(chan *pb.ChaincodeMessage, 1), - //glh - //queryIteratorMap: make(map[string]commonledger.ResultsIterator), - pendingQueryResults: make(map[string]*pendingQueryResult)} + proposal: prop, responseNotifier: make(chan *pb.ChaincodeMessage, 1)} + //glh + //queryIteratorMap: make(map[string]commonledger.ResultsIterator), + //pendingQueryResults: make(map[string]*pendingQueryResult)} handler.txCtxs[txCtxID] = txctx log.Debugf("createTxContext, create txCtxID[%s]", txCtxID) //glh @@ -746,9 +713,9 @@ func (handler *Handler) notify(msg *pb.ChaincodeMessage) { tctx.responseNotifier <- msg // clean up queryIteratorMap - for _, v := range tctx.queryIteratorMap { - v.Close() - } + //for _, v := range tctx.queryIteratorMap { + // v.Close() + //} } } @@ -2213,7 +2180,6 @@ func (handler *Handler) sendExecuteMessage(ctxt context.Context, chainID string, log.Debugf("[%s]sendExecuteMsg trigger event %s", shorttxid(msg.Txid), msg.Type) handler.triggerNextState(msg, true) - return txctx.responseNotifier, nil } @@ -2228,57 +2194,57 @@ func (handler *Handler) isRunning() bool { } } -func (handler *Handler) enterGetCertByID(e *fsm.Event) { - msg, ok := e.Args[0].(*pb.ChaincodeMessage) - if !ok { - e.Cancel(errors.New("received unexpected message type")) - return - } - log.Debugf("[%s]Received %s, invoking get state from ledger", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_CERT_STATE) - // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition - // is completed before the next one is triggered. The previous state transition is deemed complete only when - // the afterGetState function is exited. Interesting bug fix!! - go func() { - // Check if this is the unique state request from this chaincode txid - uniqueReq := handler.createTXIDEntry(msg.ChannelId, msg.Txid) - if !uniqueReq { - // Drop this request - log.Error("Another state request pending for this Txid. Cannot process.") - return - } - - var serialSendMsg *pb.ChaincodeMessage - var txContext *transactionContext - txContext, serialSendMsg = handler.isValidTxSim(msg.ChannelId, msg.Txid, - "[%s]No ledger context for GetState. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) - if txContext == nil { - return - } - defer func() { - handler.deleteTXIDEntry(msg.ChannelId, msg.Txid) - log.Debugf("[%s]handleenterGetDepositConfig serial send %s", - shorttxid(serialSendMsg.Txid), serialSendMsg.Type) - handler.serialSendAsync(serialSendMsg, nil) - }() - keyForSystemConfig := &pb.KeyForSystemConfig{} - unmarshalErr := proto.Unmarshal(msg.Payload, keyForSystemConfig) - if unmarshalErr != nil { - serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(unmarshalErr.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} - return - } - chaincodeID := handler.getCCRootName() - contractID := syscontract.DigitalIdentityContractAddress.Bytes() - payloadBytes, err := txContext.txsimulator.GetState(contractID, chaincodeID, keyForSystemConfig.Key) - log.Debugf("[%s] getting cert bytes for chaincode %s, channel %s", shorttxid(msg.Txid), chaincodeID, msg.ChannelId) - if err != nil { - log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) - serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} - return - } - log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_RESPONSE) - serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId} - }() -} +//func (handler *Handler) enterGetCertByID(e *fsm.Event) { +// msg, ok := e.Args[0].(*pb.ChaincodeMessage) +// if !ok { +// e.Cancel(errors.New("received unexpected message type")) +// return +// } +// log.Debugf("[%s]Received %s, invoking get state from ledger", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_CERT_STATE) +// // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition +// // is completed before the next one is triggered. The previous state transition is deemed complete only when +// // the afterGetState function is exited. Interesting bug fix!! +// go func() { +// // Check if this is the unique state request from this chaincode txid +// uniqueReq := handler.createTXIDEntry(msg.ChannelId, msg.Txid) +// if !uniqueReq { +// // Drop this request +// log.Error("Another state request pending for this Txid. Cannot process.") +// return +// } +// +// var serialSendMsg *pb.ChaincodeMessage +// var txContext *transactionContext +// txContext, serialSendMsg = handler.isValidTxSim(msg.ChannelId, msg.Txid, +// "[%s]No ledger context for GetState. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) +// if txContext == nil { +// return +// } +// defer func() { +// handler.deleteTXIDEntry(msg.ChannelId, msg.Txid) +// log.Debugf("[%s]handleenterGetDepositConfig serial send %s", +// shorttxid(serialSendMsg.Txid), serialSendMsg.Type) +// handler.serialSendAsync(serialSendMsg, nil) +// }() +// keyForSystemConfig := &pb.KeyForSystemConfig{} +// unmarshalErr := proto.Unmarshal(msg.Payload, keyForSystemConfig) +// if unmarshalErr != nil { +// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(unmarshalErr.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} +// return +// } +// chaincodeID := handler.getCCRootName() +// contractID := syscontract.DigitalIdentityContractAddress.Bytes() +// payloadBytes, err := txContext.txsimulator.GetState(contractID, chaincodeID, keyForSystemConfig.Key) +// log.Debugf("[%s] getting cert bytes for chaincode %s, channel %s", shorttxid(msg.Txid), chaincodeID, msg.ChannelId) +// if err != nil { +// log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) +// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} +// return +// } +// log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_RESPONSE) +// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId} +// }() +//} //glh /* diff --git a/contracts/manger/ccapi.go b/contracts/manger/ccapi.go index 013bd8bd9..2401b1902 100755 --- a/contracts/manger/ccapi.go +++ b/contracts/manger/ccapi.go @@ -228,6 +228,7 @@ func saveChaincode(dag dag.IDag, contractId common.Address, chaincode *cclist.CC // ccName can be contract Id //func Invoke(chainID string, deployId []byte, txid string, args [][]byte, timeout time.Duration) (*peer.ContractInvokePayload, error) { func Invoke(rwM rwset.TxManager, idag dag.IDag, chainID string, deployId []byte, txid string, args [][]byte, timeout time.Duration) (*md.ContractInvokeResult, error) { + log.Debugf("Invoke enter") log.Info("Invoke enter", "chainID", chainID, "deployId", deployId, "txid", txid, "timeout", timeout) defer log.Info("Invoke exit", "chainID", chainID, "deployId", deployId, "txid", txid, "timeout", timeout) @@ -244,16 +245,17 @@ func Invoke(rwM rwset.TxManager, idag dag.IDag, chainID string, deployId []byte, } } else { cc, err = getChaincode(idag, address) + log.Debugf("get chain code") if err != nil { return nil, err } } startTm := time.Now() es := NewEndorserServer(mksupt) - + log.Debugf("new endorser server") spec := &pb.ChaincodeSpec{ ChaincodeId: &pb.ChaincodeID{Name: cc.Name}, - Type: pb.ChaincodeSpec_GOLANG, + Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value[cc.Language]), Input: &pb.ChaincodeInput{Args: args}, } cid := &pb.ChaincodeID{ @@ -262,11 +264,13 @@ func Invoke(rwM rwset.TxManager, idag dag.IDag, chainID string, deployId []byte, Version: cc.Version, } sprop, prop, err := SignedEndorserProposa(chainID, txid, spec, creator, []byte("msg1")) + log.Debugf("signed endorser proposal") if err != nil { log.Errorf("signedEndorserProposa error[%v]", err) return nil, err } rsp, unit, err := es.ProcessProposal(rwM, idag, deployId, context.Background(), sprop, prop, chainID, cid, timeout) + log.Debugf("process proposal") if err != nil { log.Infof("ProcessProposal error[%v]", err) return nil, err diff --git a/contracts/manger/endorser.go b/contracts/manger/endorser.go index df5bcb6b4..c8ffbe231 100755 --- a/contracts/manger/endorser.go +++ b/contracts/manger/endorser.go @@ -82,6 +82,7 @@ func NewEndorserServer(s Support) pb.EndorserServer { //call specified chaincode (system or user) func (e *Endorser) callChaincode(contractid []byte, ctxt context.Context, chainID string, version string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, cis *pb.ChaincodeInvocationSpec, chaincodeName string, txsim rwset.TxSimulator, timeout time.Duration) (*pb.Response, *pb.ChaincodeEvent, error) { + log.Debugf("call chain code enter") log.Debugf("[%s][%s] Entry chaincode: %s version: %s", chainID, shorttxid(txid), chaincodeName, version) defer log.Debugf("[%s][%s] Exit", chainID, shorttxid(txid)) var err error @@ -94,6 +95,7 @@ func (e *Endorser) callChaincode(contractid []byte, ctxt context.Context, chainI scc := e.s.IsSysCC(chaincodeName) res, ccevent, err = e.s.Execute(contractid, ctxt, chainID, chaincodeName, version, txid, scc, signedProp, prop, cis, timeout) + log.Debugf("execute") if err != nil { return res, nil, err } @@ -139,6 +141,7 @@ func (e *Endorser) simulateProposal(contractid []byte, ctx context.Context, chai var res *pb.Response var ccevent *pb.ChaincodeEvent res, ccevent, err = e.callChaincode(contractid, ctx, chainID, cid.Version, txid, signedProp, prop, cis, cid.Name, txsim, tmout) + log.Debugf("call chain code") if err != nil { log.Errorf("[%s][%s] failed to invoke chaincode %s, error: %+v", chainID, shorttxid(txid), cid, err) return res, nil, nil, err @@ -203,6 +206,7 @@ func (e *Endorser) validateProcess(signedProp *pb.SignedProposal) (*validateResu // ProcessProposal process the Proposal //func (e *Endorser) ProcessProposal(ctx context.Context, signedProp *pb.SignedProposal) (*pb.ProposalResponse, error) { func (e *Endorser) ProcessProposal(rwM rwset.TxManager, idag dag.IDag, deployId []byte, ctx context.Context, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, cid *pb.ChaincodeID, tmout time.Duration) (*pb.ProposalResponse, *modules.ContractInvokeResult, error) { + log.Debugf("process proposal enter") var txsim rwset.TxSimulator //addr := util.ExtractRemoteAddress(ctx) @@ -211,6 +215,7 @@ func (e *Endorser) ProcessProposal(rwM rwset.TxManager, idag dag.IDag, deployId //0 -- check and validate result, err := e.validateProcess(signedProp) + log.Debugf("validate process") if err != nil { log.Debugf("validate signedProp err:%s", err) return nil, nil, err @@ -228,6 +233,7 @@ func (e *Endorser) ProcessProposal(rwM rwset.TxManager, idag dag.IDag, deployId //1 -- simulate res, _, _, err := e.simulateProposal(deployId, ctx, chainID, txid, signedProp, prop, cid, txsim, tmout) + log.Debugf("simulate proposal") if err != nil { return &pb.ProposalResponse{Response: &pb.Response{Status: 500, Message: err.Error()}}, nil, err } diff --git a/contracts/manger/support.go b/contracts/manger/support.go index 36a2c361a..1b76181d0 100755 --- a/contracts/manger/support.go +++ b/contracts/manger/support.go @@ -61,12 +61,15 @@ func (s *SupportImpl) IsSysCC(name string) bool { //Execute - execute proposal, return original response of chaincode func (s *SupportImpl) Execute(contractid []byte, ctxt context.Context, cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal, spec interface{}, timeout time.Duration) (*pb.Response, *pb.ChaincodeEvent, error) { + log.Debugf("execute enter") cccid := ccprovider.NewCCContext(contractid, cid, name, version, txid, syscc, signedProp, prop) switch spec.(type) { case *pb.ChaincodeDeploymentSpec: + log.Debugf("deploy") return chaincode.Execute(ctxt, cccid, spec, timeout) case *pb.ChaincodeInvocationSpec: + log.Debugf("invoke") cis := spec.(*pb.ChaincodeInvocationSpec) //log.Infof("cis:%v", cis) diff --git a/contracts/shim/chaincode.go b/contracts/shim/chaincode.go index b311b1647..b57276bdc 100755 --- a/contracts/shim/chaincode.go +++ b/contracts/shim/chaincode.go @@ -324,6 +324,7 @@ func chatWithPeer(chaincodename string, stream PeerChaincodeStream, cc Chaincode case nsInfo = <-handler.nextState: in = nsInfo.msg if in == nil { + log.Debugf("nil msg") panic("nil msg") } log.Debugf("[%s]Move state message %s", shorttxid(in.Txid), in.Type.String()) diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index 37aa80ae7..2f107a560 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -40,6 +40,7 @@ import ( "github.com/palletone/go-palletone/contracts/syscontract/sysconfigcc" "github.com/palletone/go-palletone/core" "github.com/palletone/go-palletone/core/accounts" + "github.com/palletone/go-palletone/core/vmContractPub/protos/peer" "github.com/palletone/go-palletone/dag/modules" "github.com/palletone/go-palletone/ptnjson" "strings" @@ -142,7 +143,7 @@ func (s *PublicContractAPI) Ccstop(ctx context.Context, contractAddr string) err } //contract tx -func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount, daoFee, tplName, path, version string, addr []string) (*ContractInstallRsp, error) { +func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount, daoFee, tplName, path, version, ccdescription, ccabi, cclanguage string, addr []string) (*ContractInstallRsp, error) { fromAddr, _ := common.StringToAddress(from) toAddr, _ := common.StringToAddress(to) amount, _ := strconv.ParseUint(daoAmount, 10, 64) @@ -157,7 +158,17 @@ func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount log.Debug("-----Ccinstalltx:", "tplName", tplName) log.Debug("-----Ccinstalltx:", "path", path) log.Debug("-----Ccinstalltx:", "version", version) + log.Debug("-----Ccinstalltx:", "description", ccdescription) + log.Debug("-----Ccinstalltx:", "abi", ccabi) + log.Debug("-----Ccinstalltx:", "language", cclanguage) + if strings.ToLower(cclanguage) == "go" { + cclanguage = "golang" + } + language := strings.ToUpper(cclanguage) + if _, ok := peer.ChaincodeSpec_Type_value[language]; !ok { + return nil, errors.New(cclanguage + " language is not supported") + } /* "P1QFTh1Xq2JpfTbu9bfaMfWh2sR1nHrMV8z", "P1NHVBFRkooh8HD9SvtvU3bpbeVmuGKPPuF", "P1PpgjUC7Nkxgi5KdKCGx2tMu6F5wfPGrVX", "P1MBXJypFCsQpafDGi9ivEooR8QiYmxq4qw" @@ -173,7 +184,7 @@ func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount } log.Debug("-----Ccinstalltx:", "addrHash", addrs, "len", len(addrs)) - reqId, tplId, err := s.b.ContractInstallReqTx(fromAddr, toAddr, amount, fee, tplName, path, version, "Description...", "ABI ...", strings.ToUpper("golang"), addrs) + reqId, tplId, err := s.b.ContractInstallReqTx(fromAddr, toAddr, amount, fee, tplName, path, version, ccdescription, ccabi, language, addrs) sReqId := hex.EncodeToString(reqId[:]) sTplId := hex.EncodeToString(tplId) log.Debug("-----Ccinstalltx:", "reqId", sReqId, "tplId", sTplId) diff --git a/internal/web3ext/contractjs.go b/internal/web3ext/contractjs.go index 930f61392..bd1ca0d45 100755 --- a/internal/web3ext/contractjs.go +++ b/internal/web3ext/contractjs.go @@ -32,8 +32,8 @@ web3._extend({ new web3._extend.Method({ name: 'ccinstalltx', call: 'contract_ccinstalltx', - params: 8, //from, to , daoAmount, daoFee , tplName, path, version - inputFormatter: [null, null, null,null, null, null, null, null] + params: 11, //from, to , daoAmount, daoFee , tplName, path, version,description,abi,language + inputFormatter: [null, null, null,null, null, null, null, null, null, null, null] }), new web3._extend.Method({ name: 'ccdeploytx', From a0ea7665b925cc268c11c28e7883582534f436eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Thu, 11 Jul 2019 16:57:59 +0800 Subject: [PATCH 11/44] addTrustedPeer and removeTrustedPeer in adminAPI --- core/node/api.go | 31 +++++++++++++++++++++++++++++++ dag/common/prop_repository.go | 3 ++- dag/storage/statedb_contract.go | 2 +- internal/web3ext/adminjs.go | 10 ++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/core/node/api.go b/core/node/api.go index 8544e2ff4..c43b6c140 100755 --- a/core/node/api.go +++ b/core/node/api.go @@ -75,6 +75,37 @@ func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) { return true, nil } +// AddTrustedPeer allows a remote node to always connect, even if slots are full +func (api *PrivateAdminAPI) AddTrustedPeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + node, err := discover.ParseNode(url) + if err != nil { + return false, fmt.Errorf("invalid pnode: %v", err) + } + server.AddTrustedPeer(node) + return true, nil +} + +// RemoveTrustedPeer removes a remote node from the trusted peer set, but it +// does not disconnect it automatically. +func (api *PrivateAdminAPI) RemoveTrustedPeer(url string) (bool, error) { + // Make sure the server is running, fail otherwise + server := api.node.Server() + if server == nil { + return false, ErrNodeStopped + } + node, err := discover.ParseNode(url) + if err != nil { + return false, fmt.Errorf("invalid enode: %v", err) + } + server.RemoveTrustedPeer(node) + return true, nil +} + // PeerEvents creates an RPC subscription which receives peer events from the // node's p2p.Server func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription, error) { diff --git a/dag/common/prop_repository.go b/dag/common/prop_repository.go index 958c8de45..89147d0fd 100755 --- a/dag/common/prop_repository.go +++ b/dag/common/prop_repository.go @@ -20,9 +20,9 @@ package common import ( + "encoding/binary" "time" - "encoding/binary" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/common/ptndb" @@ -36,6 +36,7 @@ import ( type PropRepository struct { db storage.IPropertyDb } + type IPropRepository interface { StoreGlobalProp(gp *modules.GlobalProperty) error RetrieveGlobalProp() (*modules.GlobalProperty, error) diff --git a/dag/storage/statedb_contract.go b/dag/storage/statedb_contract.go index 3667d54ac..a0cd48054 100755 --- a/dag/storage/statedb_contract.go +++ b/dag/storage/statedb_contract.go @@ -196,7 +196,7 @@ func (statedb *StateDb) GetContractStatesById(id []byte) (map[string]*modules.Co realKey := dbkey[len(key):] if realKey != "" { result[realKey] = &modules.ContractStateValue{Value: state, Version: version} - log.Info("the contract's state get info.", "key", realKey) + log.Debug("the contract's state get info.", "key", realKey) } } return result, err diff --git a/internal/web3ext/adminjs.go b/internal/web3ext/adminjs.go index 282ff7a21..80b938f9e 100644 --- a/internal/web3ext/adminjs.go +++ b/internal/web3ext/adminjs.go @@ -38,6 +38,16 @@ web3._extend({ call: 'admin_removePeer', params: 1 }), + new web3._extend.Method({ + name: 'addTrustedPeer', + call: 'admin_addTrustedPeer', + params: 1 + }), + new web3._extend.Method({ + name: 'removeTrustedPeer', + call: 'admin_removeTrustedPeer', + params: 1 + }), new web3._extend.Method({ name: 'exportChain', call: 'admin_exportChain', From b424d1727185195a511c6915e514cae5df0407c1 Mon Sep 17 00:00:00 2001 From: Devin Date: Thu, 11 Jul 2019 23:54:49 +0800 Subject: [PATCH 12/44] getContractInfoByAddr can query template info --- internal/ptnapi/backend.go | 2 +- internal/ptnapi/contract_api.go | 10 ++++++---- light/api_backend.go | 2 +- ptn/api_backend.go | 14 ++++++++++++-- ptnjson/contractjson.go | 1 + 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/internal/ptnapi/backend.go b/internal/ptnapi/backend.go index d6186b08c..787b28df0 100755 --- a/internal/ptnapi/backend.go +++ b/internal/ptnapi/backend.go @@ -91,7 +91,7 @@ type Backend interface { GetCommonByPrefix(prefix []byte) map[string][]byte SaveCommon(key, val []byte) error // Get Contract Api - GetContract(hex_id string) (*modules.Contract, error) + GetContract(contractAddr common.Address) (*ptnjson.ContractJson, error) //get level db GetUnitByHash(hash common.Hash) *modules.Unit diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index 2f107a560..9d7d166e8 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -406,21 +406,23 @@ func (s *PublicContractAPI) GetAllContractsUsedTemplateId(ctx context.Context, t // 通过合约Id,获取合约的详细信息 func (s *PublicContractAPI) GetContractInfoById(ctx context.Context, contractId string) (*ptnjson.ContractJson, error) { - contract, err := s.b.GetContract(contractId) + id,_:=hex.DecodeString(contractId) + addr:= common.NewAddress(id,common.ContractHash) + contract, err := s.b.GetContract(addr) if err != nil { return nil, err } - return ptnjson.ConvertContract2Json(contract), nil + return contract, nil } // 通过合约地址,获取合约的详细信息 func (s *PublicContractAPI) GetContractInfoByAddr(ctx context.Context, contractAddr string) (*ptnjson.ContractJson, error) { addr, _ := common.StringToAddress(contractAddr) - contract, err := s.b.GetContract(addr.Hex()[2:]) + contract, err := s.b.GetContract(addr) if err != nil { return nil, err } - return ptnjson.ConvertContract2Json(contract), nil + return contract, nil } func (s *PublicContractAPI) DepositContractInvoke(ctx context.Context, from, to, daoAmount, daoFee string, param []string) (string, error) { diff --git a/light/api_backend.go b/light/api_backend.go index bc18a7663..382886f9d 100755 --- a/light/api_backend.go +++ b/light/api_backend.go @@ -285,7 +285,7 @@ func (b *LesApiBackend) GetCommonByPrefix(prefix []byte) map[string][]byte { } // Get Contract Api -func (b *LesApiBackend) GetContract(hex_id string) (*modules.Contract, error) { +func (b *LesApiBackend) GetContract(contractAddr common.Address) (*ptnjson.ContractJson, error){ return nil, nil } diff --git a/ptn/api_backend.go b/ptn/api_backend.go index 3af85fb58..0e1ba5348 100755 --- a/ptn/api_backend.go +++ b/ptn/api_backend.go @@ -246,8 +246,18 @@ func (b *PtnApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma //} // GetContract -func (b *PtnApiBackend) GetContract(id string) (*modules.Contract, error) { - return b.ptn.dag.GetContract(common.Hex2Bytes(id)) +func (b *PtnApiBackend) GetContract(addr common.Address) (*ptnjson.ContractJson, error) { + contract,err:= b.ptn.dag.GetContract(addr.Bytes()) + if err!=nil{ + return nil,err + } + cjson:= ptnjson.ConvertContract2Json(contract) + tpl,err:= b.ptn.dag.GetContractTpl(contract.TemplateId) + if err!=nil{ + return cjson,nil + } + cjson.Template= ptnjson.ConvertContractTemplate2Json(tpl) + return cjson,nil } func (b *PtnApiBackend) QueryDbByKey(key []byte) *ptnjson.DbRowJson { val, err := b.ptn.dag.QueryDbByKey(key) diff --git a/ptnjson/contractjson.go b/ptnjson/contractjson.go index c6cf39781..c17feafbb 100755 --- a/ptnjson/contractjson.go +++ b/ptnjson/contractjson.go @@ -38,6 +38,7 @@ type ContractJson struct { Status byte `json:"status"` // 合约状态 Creator string `json:"creator"` CreationTime time.Time `json:"creation_time"` // creation date + Template *ContractTemplateJson `json:"template"` } func ConvertContract2Json(contract *modules.Contract) *ContractJson { From 6ff9b67714e65b2512a90c1ebc7eb3ea47520248 Mon Sep 17 00:00:00 2001 From: etying Date: Thu, 11 Jul 2019 19:43:00 -0700 Subject: [PATCH 13/44] modify Full protocal fetcher UT --- ptn/fetcher/fetcher_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ptn/fetcher/fetcher_test.go b/ptn/fetcher/fetcher_test.go index 104598115..5e75c6a0f 100755 --- a/ptn/fetcher/fetcher_test.go +++ b/ptn/fetcher/fetcher_test.go @@ -459,7 +459,7 @@ func testConcurrentAnnouncements(t *testing.T, protocol int) { // Tests that announcements retrieved in a random order are cached and eventually // imported when all the gaps are filled in. -func TestRandomArrivalImport1(t *testing.T) { testRandomArrivalImport(t, 1) } +//func TestRandomArrivalImport1(t *testing.T) { testRandomArrivalImport(t, 1) } func testRandomArrivalImport(t *testing.T, protocol int) { // Create a chain of blocks to import, and choose one to delay targetunits := maxQueueDist @@ -496,7 +496,7 @@ func testRandomArrivalImport(t *testing.T, protocol int) { // Tests that direct block enqueues (due to block propagation vs. hash announce) // are correctly schedule, filling and import queue gaps. -func TestQueueGapFill1(t *testing.T) { testQueueGapFill(t, 1) } +//func TestQueueGapFill1(t *testing.T) { testQueueGapFill(t, 1) } func testQueueGapFill(t *testing.T, protocol int) { // Create a chain of blocks to import, and choose one to not announce at all targetunits := maxQueueDist From 5c5525d3bcf7748ece0ce6b7cb0054dd741c4ab4 Mon Sep 17 00:00:00 2001 From: Devin Date: Fri, 12 Jul 2019 11:18:20 +0800 Subject: [PATCH 14/44] Fix pledge withdraw bug. --- .../syscontract/deposit/pledge_operation.go | 27 ++++++++++++++++++- contracts/syscontract/deposit/pledge_rep.go | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/contracts/syscontract/deposit/pledge_operation.go b/contracts/syscontract/deposit/pledge_operation.go index e12a3c910..3d2e21106 100755 --- a/contracts/syscontract/deposit/pledge_operation.go +++ b/contracts/syscontract/deposit/pledge_operation.go @@ -25,6 +25,8 @@ import ( "encoding/json" "github.com/palletone/go-palletone/contracts/shim" pb "github.com/palletone/go-palletone/core/vmContractPub/protos/peer" + "github.com/palletone/go-palletone/dag/modules" + "github.com/shopspring/decimal" ) // 质押PTN @@ -117,9 +119,32 @@ func queryPledgeStatusByAddr(stub shim.ChaincodeStubInterface, args []string) pb if err != nil { return shim.Error(err.Error()) } - data, _ := json.Marshal(status) + pjson := convertPledgeStatus2Json(status) + data, _ := json.Marshal(pjson) return shim.Success(data) } + +type pledgeStatusJson struct { + NewDepositAmount decimal.Decimal + PledgeAmount decimal.Decimal + WithdrawApplyAmount string + OtherAmount decimal.Decimal +} + +func convertPledgeStatus2Json(p *modules.PledgeStatus) *pledgeStatusJson { + data := &pledgeStatusJson{} + gasToken := dagconfig.DagConfig.GetGasToken().ToAsset() + data.NewDepositAmount = gasToken.DisplayAmount(p.NewDepositAmount) + data.PledgeAmount = gasToken.DisplayAmount(p.PledgeAmount) + data.OtherAmount = gasToken.DisplayAmount(p.OtherAmount) + if p.WithdrawApplyAmount == math.MaxUint64 { + data.WithdrawApplyAmount = "all" + } else { + data.WithdrawApplyAmount = gasToken.DisplayAmount(p.WithdrawApplyAmount).String() + } + return data +} + func queryAllPledgeHistory(stub shim.ChaincodeStubInterface, args []string) pb.Response { history, err := getAllPledgeRewardHistory(stub) diff --git a/contracts/syscontract/deposit/pledge_rep.go b/contracts/syscontract/deposit/pledge_rep.go index 4f5ab5e10..b24761f55 100755 --- a/contracts/syscontract/deposit/pledge_rep.go +++ b/contracts/syscontract/deposit/pledge_rep.go @@ -118,7 +118,7 @@ func handleRewardAllocation(stub shim.ChaincodeStubInterface, depositDailyReward for _, withdraw := range withdrawList { withdrawAmt, _ := allM.Reduce(withdraw.Address, withdraw.Amount) if withdrawAmt > 0 { - err := stub.PayOutToken(withdraw.Address, modules.NewAmountAsset(withdraw.Amount, gasToken), 0) + err := stub.PayOutToken(withdraw.Address, modules.NewAmountAsset(withdrawAmt, gasToken), 0) if err != nil { return err } From be604c86b8625a8d19cc41c666ac62a8a82a4292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Fri, 12 Jul 2019 11:28:04 +0800 Subject: [PATCH 15/44] Update prop_repository_test.go --- dag/common/prop_repository_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dag/common/prop_repository_test.go b/dag/common/prop_repository_test.go index 0f82a8073..e2ab9f1cc 100755 --- a/dag/common/prop_repository_test.go +++ b/dag/common/prop_repository_test.go @@ -69,6 +69,7 @@ func BenchmarkPropRepository_RetrieveDynGlobalProp(b *testing.B) { rep.RetrieveDynGlobalProp() } } + func TestShuffle(t *testing.T) { addr1 := common.NewAddress(crypto.Hash160([]byte("1")), common.PublicKeyHash) addr2 := common.NewAddress(crypto.Hash160([]byte("2")), common.PublicKeyHash) @@ -78,7 +79,7 @@ func TestShuffle(t *testing.T) { for i := 0; i < 10; i++ { addrs := []common.Address{addr1, addr2, addr3, addr4, addr5} - Shuffle(addrs, uint64(i)) + shuffleMediators(addrs, uint64(i)) addrJs, _ := json.Marshal(addrs) t.Logf("i:%d,addr:%s", i, addrJs) } From f1d7d25a9d7fdc0e8dfc34379615ac8ee22afcac Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Fri, 12 Jul 2019 11:30:00 +0800 Subject: [PATCH 16/44] Fix parameter issue in initialize the contract --- internal/ptnapi/contract_api.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index 9d7d166e8..da856dece 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -214,7 +214,9 @@ func (s *PublicContractAPI) Ccdeploytx(ctx context.Context, from, to, daoAmount, args[i] = []byte(arg) fmt.Printf("index[%d], value[%s]\n", i, arg) } - reqId, _, err := s.b.ContractDeployReqTx(fromAddr, toAddr, amount, fee, templateId, args, 0) + fullArgs := [][]byte{defaultMsg0, defaultMsg1} + fullArgs = append(fullArgs, args...) + reqId, _, err := s.b.ContractDeployReqTx(fromAddr, toAddr, amount, fee, templateId, fullArgs, 0) contractAddr := crypto.RequestIdToContractAddress(reqId) sReqId := hex.EncodeToString(reqId[:]) log.Debug("-----Ccdeploytx:", "reqId", sReqId, "depId", contractAddr.String()) @@ -406,8 +408,8 @@ func (s *PublicContractAPI) GetAllContractsUsedTemplateId(ctx context.Context, t // 通过合约Id,获取合约的详细信息 func (s *PublicContractAPI) GetContractInfoById(ctx context.Context, contractId string) (*ptnjson.ContractJson, error) { - id,_:=hex.DecodeString(contractId) - addr:= common.NewAddress(id,common.ContractHash) + id, _ := hex.DecodeString(contractId) + addr := common.NewAddress(id, common.ContractHash) contract, err := s.b.GetContract(addr) if err != nil { return nil, err From fe81efa827d3f76a166f2774d0ccc34ec7787e00 Mon Sep 17 00:00:00 2001 From: lk Date: Fri, 12 Jul 2019 15:22:45 +0800 Subject: [PATCH 17/44] Add GetAssetReference --- dag/common/unit_repository.go | 35 ++++++++++++++++++++--------------- dag/constants/prefix_info.go | 1 + dag/dag.go | 4 ++++ dag/interface.go | 1 + dag/storage/indexdb.go | 24 ++++++++++++++++++++++++ dag/storage/indexdb_test.go | 26 ++++++++++++++++++++++++++ internal/ptnapi/backend.go | 1 + internal/ptnapi/ptn_api.go | 11 +++++++++++ internal/ptnapi/walletapi.go | 9 +++++++++ internal/web3ext/walletjs.go | 5 +++++ light/api_backend.go | 3 +++ ptn/api_backend.go | 13 +++++++++++++ 12 files changed, 118 insertions(+), 15 deletions(-) diff --git a/dag/common/unit_repository.go b/dag/common/unit_repository.go index 468ec97e1..043f91fb9 100755 --- a/dag/common/unit_repository.go +++ b/dag/common/unit_repository.go @@ -99,6 +99,7 @@ type IUnitRepository interface { GetTxRequesterAddress(tx *modules.Transaction) (common.Address, error) //根据现有Tx数据,重新构建地址和Tx的关系索引 RefreshAddrTxIndex() error + GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) SubscribeSysContractStateChangeEvent(ob AfterSysContractStateChangeEventFunc) SaveCommon(key, val []byte) error @@ -1028,7 +1029,7 @@ func (rep *UnitRepository) saveTx4Unit(unit *modules.Unit, txIndex int, tx *modu return fmt.Errorf("save contract of signature failed.") } case modules.APP_DATA: - if ok := rep.saveDataPayload(requester, unitHash, unitTime, txHash, msg.Payload.(*modules.DataPayload)); ok != true { + if ok := rep.saveDataPayload(requester, unitHash, unitTime, txHash, msg.Payload.(*modules.DataPayload), msg.Payload.(*modules.PaymentPayload)); ok != true { return fmt.Errorf("save data payload faild.") } default: @@ -1058,8 +1059,8 @@ func (rep *UnitRepository) saveAddrTxIndex(txHash common.Hash, tx *modules.Trans for _, addr := range fromAddrs { rep.idxdb.SaveAddressTxId(addr, txHash) } + } -} func getPayToAddresses(tx *modules.Transaction) []common.Address { resultMap := map[common.Address]int{} for _, msg := range tx.TxMessages { @@ -1169,7 +1170,7 @@ func (rep *UnitRepository) savePaymentPayload(unitTime int64, txHash common.Hash save DataPayload data */ -func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash common.Hash, timestamp int64, txHash common.Hash, dataPayload *modules.DataPayload) bool { +func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash common.Hash, timestamp int64, txHash common.Hash, dataPayload *modules.DataPayload, msg *modules.PaymentPayload) bool { if dagconfig.DagConfig.TextFileHashIndex { @@ -1193,6 +1194,16 @@ func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash co log.Error("error SaveProofOfExistence", "err", err) return false } + for _, output := range msg.Outputs { + asset := output.Asset + if asset.AssetId.GetAssetType() == modules.AssetType_NonFungibleToken { + if err = rep.idxdb.SaveTokenExistence(asset, poe); err != nil { + log.Errorf("Save token and ProofOfExistence index data error:%s", err.Error()) + } + } + + } + //err = rep.idxdb.SaveTokenExistence() } return true } @@ -1649,18 +1660,7 @@ func (rep *UnitRepository) GetFileInfoByHash(hashs []common.Hash) ([]*modules.Fi var mds []*modules.FileInfo for _, hash := range hashs { var md modules.FileInfo - //txlookup, err := rep.dagdb.GetTxLookupEntry(hash) - //if err != nil { - // return nil, err - //} - // - //header, err := rep.dagdb.GetHeaderByHash(unithash) - //if err != nil { - // return nil, err - //} - //for _, v := range header.ParentsHash { - // md.ParentsHash = v - //} + tx, err := rep.GetTransaction(hash) if err != nil { return nil, err @@ -1726,6 +1726,11 @@ func (rep *UnitRepository) RefreshAddrTxIndex() error { } return nil } + +func (rep *UnitRepository) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { + return rep.idxdb.GetTokenExistence(asset) +} + func (rep *UnitRepository) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) { return rep.idxdb.QueryProofOfExistenceByReference(ref) } diff --git a/dag/constants/prefix_info.go b/dag/constants/prefix_info.go index f5c209dcd..9ad4465db 100755 --- a/dag/constants/prefix_info.go +++ b/dag/constants/prefix_info.go @@ -55,6 +55,7 @@ var ( ACCOUNT_INFO_PREFIX = []byte("ai") ACCOUNT_PTN_BALANCE_PREFIX = []byte("ab") TOKEN_TXID_PREFIX = []byte("tt") //IndexDB中存储一个Token关联的TxId + TOKEN_EX_PREFIX = []byte("te") //IndexDB中存储一个Token关联的ProofOfExistence // lookup LOOKUP_PREFIX = []byte("lu") UTXO_PREFIX = []byte("uo") diff --git a/dag/dag.go b/dag/dag.go index 910b3220c..a95a38eb2 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -1190,3 +1190,7 @@ func (dag *Dag) GetDataVersion() (*modules.DataVersion, error) { func (dag *Dag) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) { return dag.stableUnitRep.QueryProofOfExistenceByReference(ref) } + +func (dag *Dag) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { + return dag.stableUnitRep.GetAssetReference(asset) +} diff --git a/dag/interface.go b/dag/interface.go index 6e47862ec..99685bc42 100644 --- a/dag/interface.go +++ b/dag/interface.go @@ -181,4 +181,5 @@ type IDag interface { GetDataVersion() (*modules.DataVersion, error) StoreDataVersion(dv *modules.DataVersion) error QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) + GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) } diff --git a/dag/storage/indexdb.go b/dag/storage/indexdb.go index 28e2fa763..582945f6e 100755 --- a/dag/storage/indexdb.go +++ b/dag/storage/indexdb.go @@ -42,6 +42,8 @@ type IIndexDb interface { SaveTokenTxId(asset *modules.Asset, txid common.Hash) error GetTokenTxIds(asset *modules.Asset) ([]common.Hash, error) + SaveTokenExistence(asset *modules.Asset, poe *modules.ProofOfExistence) error + GetTokenExistence(asset *modules.Asset) ([]*modules.ProofOfExistence, error) SaveMainDataTxId(maindata []byte, txid common.Hash) error GetMainDataTxIds(maindata []byte) ([]common.Hash, error) @@ -83,6 +85,28 @@ func (db *IndexDb) GetTokenTxIds(asset *modules.Asset) ([]common.Hash, error) { return result, nil } +func (db *IndexDb) SaveTokenExistence(asset *modules.Asset, poe *modules.ProofOfExistence) error { + key := append(constants.TOKEN_EX_PREFIX, asset.Bytes()...) + key = append(key, poe.Reference...) + return StoreToRlpBytes(db.db, key, poe) +} + +func (db *IndexDb) GetTokenExistence(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { + prefix := append(constants.TOKEN_EX_PREFIX, asset.Bytes()...) + iter := db.db.NewIteratorWithPrefix(prefix) + result := []*modules.ProofOfExistence{} + for iter.Next() { + value := iter.Value() + poe := &modules.ProofOfExistence{} + err := rlp.DecodeBytes(value, poe) + if err != nil { + return nil, err + } + result = append(result, poe) + } + return result, nil +} + //save filehash key:IDX_MAIN_DATA_TXID value:Txid func (db *IndexDb) SaveMainDataTxId(filehash []byte, txid common.Hash) error { key := append(constants.IDX_MAIN_DATA_TXID, []byte(filehash)...) diff --git a/dag/storage/indexdb_test.go b/dag/storage/indexdb_test.go index 67d306bdd..b97903116 100644 --- a/dag/storage/indexdb_test.go +++ b/dag/storage/indexdb_test.go @@ -48,3 +48,29 @@ func TestIndexDb_QueryProofOfExistenceByReference(t *testing.T) { t.Logf("%v", poe) } } + +func TestIndexDb_GetAssetReference(t *testing.T) { + uid := modules.UniqueId{0x28, 0x5a, 0x59, 0x29} + PTNCOIN := modules.AssetId{0x40, 0x00, 0x82, 0xBB, 0x08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00} + t.Log(uid) + t.Log(PTNCOIN) + asset := &modules.Asset{} + asset.AssetId = PTNCOIN + asset.UniqueId = uid + t.Log(asset) + ref := []byte("APP1-News-123") + poe1 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News metadata json1"), Reference: ref, TxId: common.BytesToHash([]byte("txid")), UnitHash: common.Hash{}, Timestamp: 123} + poe2 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News op1"), Reference: ref, TxId: common.BytesToHash([]byte("txid1")), UnitHash: common.Hash{}, Timestamp: 333} + poe3 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News op2"), Reference: ref, TxId: common.BytesToHash([]byte("txid2")), UnitHash: common.Hash{}, Timestamp: 222} + db, _ := ptndb.NewMemDatabase() + idxdb := NewIndexDb(db) + err := idxdb.SaveTokenExistence(asset, poe1) + assert.Nil(t, err) + err = idxdb.SaveTokenExistence(asset, poe2) + err = idxdb.SaveTokenExistence(asset, poe3) + result, err := idxdb.GetTokenExistence(asset) + assert.Nil(t, err) + for _, poe := range result { + t.Logf("%s", poe.Reference) + } +} diff --git a/internal/ptnapi/backend.go b/internal/ptnapi/backend.go index 787b28df0..8d558214b 100755 --- a/internal/ptnapi/backend.go +++ b/internal/ptnapi/backend.go @@ -129,6 +129,7 @@ type Backend interface { GetAddressBalanceStatistics(token string, topN int) (*statistics.TokenAddressBalanceJson, error) GetAddrTxHistory(addr string) ([]*ptnjson.TxHistoryJson, error) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHistoryJson, error) + GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) //contract control ContractInstall(ccName string, ccPath string, ccVersion string, ccDescription, ccAbi, ccLanguage string) (TemplateId []byte, err error) ContractDeploy(templateId []byte, txid string, args [][]byte, timeout time.Duration) (deployId []byte, err error) diff --git a/internal/ptnapi/ptn_api.go b/internal/ptnapi/ptn_api.go index 624c30a89..6623b11a9 100755 --- a/internal/ptnapi/ptn_api.go +++ b/internal/ptnapi/ptn_api.go @@ -133,6 +133,17 @@ func (s *PublicBlockChainAPI) GetTokenTxHistory(ctx context.Context, assetStr st return result, err } +func (s *PublicBlockChainAPI) GetAssetExistence(ctx context.Context, assetStr string) ([]*ptnjson.ProofOfExistenceJson, error) { + asset := &modules.Asset{} + err := asset.SetString(assetStr) + if err != nil { + return nil, errors.New("Invalid asset string") + } + result, err := s.b.GetAssetExistence(asset) + + return result, err +} + func (s *PublicBlockChainAPI) ListSysConfig() ([]*ptnjson.ConfigJson, error) { cp := s.b.GetChainParameters() diff --git a/internal/ptnapi/walletapi.go b/internal/ptnapi/walletapi.go index 190b2f858..55cfbf343 100755 --- a/internal/ptnapi/walletapi.go +++ b/internal/ptnapi/walletapi.go @@ -1216,6 +1216,15 @@ func (s *PublicWalletAPI) GetProofOfExistencesByRef(ctx context.Context, referen return s.b.QueryProofOfExistenceByReference(reference) } +func (s *PublicWalletAPI) GetProofOfExistencesByAsset(ctx context.Context, ass string) ([]*ptnjson.ProofOfExistenceJson, error) { + asset := &modules.Asset{} + err := asset.SetString(ass) + if err != nil { + return nil, errors.New("Invalid asset string") + } + return s.b.GetAssetExistence(asset) +} + //好像某个UTXO是被那个交易花费的 func (s *PublicWalletAPI) GetStxo(ctx context.Context, txid string, msgIdx int, outIdx int) (*ptnjson.StxoJson, error) { outpoint := modules.NewOutPoint(common.HexToHash(txid), uint32(msgIdx), uint32(outIdx)) diff --git a/internal/web3ext/walletjs.go b/internal/web3ext/walletjs.go index 2ed985b9b..01061084c 100644 --- a/internal/web3ext/walletjs.go +++ b/internal/web3ext/walletjs.go @@ -96,6 +96,11 @@ const Wallet_JS = ` call: 'wallet_getProofOfExistencesByRef', params: 1 }), + new web3._extend.Method({ + name: 'getProofOfExistencesByAsset', + call: 'wallet_getProofOfExistencesByAsset', + params: 1 + }), new web3._extend.Method({ name: 'getFileInfoByTxid', call: 'wallet_getFileInfoByTxid', diff --git a/light/api_backend.go b/light/api_backend.go index 382886f9d..aa0eebdf5 100755 --- a/light/api_backend.go +++ b/light/api_backend.go @@ -416,6 +416,9 @@ func (b *LesApiBackend) GetAddrTxHistory(addr string) ([]*ptnjson.TxHistoryJson, func (b *LesApiBackend) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHistoryJson, error) { return nil, nil } +func (b *LesApiBackend) GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) { + return nil, nil +} //contract control func (b *LesApiBackend) ContractInstall(ccName string, ccPath string, ccVersion string, ccDescription, ccAbi, ccLanguage string) (TemplateId []byte, err error) { diff --git a/ptn/api_backend.go b/ptn/api_backend.go index 0e1ba5348..027975364 100755 --- a/ptn/api_backend.go +++ b/ptn/api_backend.go @@ -316,6 +316,19 @@ func (b *PtnApiBackend) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHi return txjs, nil } +func (b *PtnApiBackend) GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) { + poes, err := b.ptn.dag.GetAssetReference(asset) + if err != nil { + return nil, err + } + result := []*ptnjson.ProofOfExistenceJson{} + for _, poe := range poes { + j := ptnjson.ConvertProofOfExistence2Json(poe) + result = append(result, j) + } + return result, nil +} + // Get state //func (b *PtnApiBackend) GetHeadHeaderHash() (common.Hash, error) { // return b.ptn.dag.GetHeadHeaderHash() From 7bef2cda55f50b808109d466dc0a48450cb1006b Mon Sep 17 00:00:00 2001 From: Devin Date: Thu, 11 Jul 2019 16:13:54 +0800 Subject: [PATCH 18/44] Fix rlphash test bug. --- common/util/rlphash_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/util/rlphash_test.go b/common/util/rlphash_test.go index 703fc5bb4..1f5607a69 100644 --- a/common/util/rlphash_test.go +++ b/common/util/rlphash_test.go @@ -3,12 +3,12 @@ package util import "testing" type A struct { - Data int + Data uint32 } func TestRlpHash(t *testing.T) { for i := 0; i < 10; i++ { - a := &A{Data: i} + a := &A{Data: uint32(i)} hash := RlpHash(a) t.Logf("Number:%d,Hash:%x,Hash2:%x", i, hash, RlpHash(i)) } From 874e33aa0c274d256e1523a77d39a82ea05cf7f4 Mon Sep 17 00:00:00 2001 From: lk Date: Fri, 12 Jul 2019 16:04:48 +0800 Subject: [PATCH 19/44] Fix init error --- dag/common/unit_repository.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dag/common/unit_repository.go b/dag/common/unit_repository.go index 043f91fb9..5143206e0 100755 --- a/dag/common/unit_repository.go +++ b/dag/common/unit_repository.go @@ -1029,7 +1029,7 @@ func (rep *UnitRepository) saveTx4Unit(unit *modules.Unit, txIndex int, tx *modu return fmt.Errorf("save contract of signature failed.") } case modules.APP_DATA: - if ok := rep.saveDataPayload(requester, unitHash, unitTime, txHash, msg.Payload.(*modules.DataPayload), msg.Payload.(*modules.PaymentPayload)); ok != true { + if ok := rep.saveDataPayload(requester, unitHash, unitTime, txHash, msg.Payload.(*modules.DataPayload)); ok != true { return fmt.Errorf("save data payload faild.") } default: @@ -1170,7 +1170,7 @@ func (rep *UnitRepository) savePaymentPayload(unitTime int64, txHash common.Hash save DataPayload data */ -func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash common.Hash, timestamp int64, txHash common.Hash, dataPayload *modules.DataPayload, msg *modules.PaymentPayload) bool { +func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash common.Hash, timestamp int64, txHash common.Hash, dataPayload *modules.DataPayload) bool { if dagconfig.DagConfig.TextFileHashIndex { @@ -1194,15 +1194,15 @@ func (rep *UnitRepository) saveDataPayload(requester common.Address, unitHash co log.Error("error SaveProofOfExistence", "err", err) return false } - for _, output := range msg.Outputs { - asset := output.Asset - if asset.AssetId.GetAssetType() == modules.AssetType_NonFungibleToken { - if err = rep.idxdb.SaveTokenExistence(asset, poe); err != nil { - log.Errorf("Save token and ProofOfExistence index data error:%s", err.Error()) - } - } - - } + //for _, output := range msg.Outputs { + // asset := output.Asset + // if asset.AssetId.GetAssetType() == modules.AssetType_NonFungibleToken { + // if err = rep.idxdb.SaveTokenExistence(asset, poe); err != nil { + // log.Errorf("Save token and ProofOfExistence index data error:%s", err.Error()) + // } + // } + // + //} //err = rep.idxdb.SaveTokenExistence() } return true From 3150c65dd6e29ad42cef3fbfff4f8ae6eb2b7e26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E7=AB=8B=E5=8D=8E?= Date: Fri, 12 Jul 2019 16:24:18 +0800 Subject: [PATCH 20/44] stable jury number --- consensus/jury/common.go | 14 ++++++- consensus/jury/contractEvent.go | 5 ++- consensus/jury/election.go | 73 +++++++++++++++++++++++---------- consensus/jury/event.go | 33 ++++++++------- consensus/jury/service.go | 44 ++++++++++---------- contracts/ucc/usrccapi.go | 3 +- dag/getter_saver.go | 4 +- 7 files changed, 111 insertions(+), 65 deletions(-) diff --git a/consensus/jury/common.go b/consensus/jury/common.go index 282feed48..24a21c781 100644 --- a/consensus/jury/common.go +++ b/consensus/jury/common.go @@ -350,7 +350,7 @@ func runContractCmd(rwM rwset.TxManager, dag iDag, contract *contracts.Contract, return nil, errors.New(fmt.Sprintf("[%s]runContractCmd APP_CONTRACT_INVOKE txid(%s) rans err:%s", shortId(reqId.String()), req.txid, err)) } result := invokeResult.(*modules.ContractInvokeResult) - payload := modules.NewContractInvokePayload(result.ContractId, result.Args, 0 /*result.ExecutionTime*/, result.ReadSet, result.WriteSet, result.Payload, modules.ContractError{}) + payload := modules.NewContractInvokePayload(result.ContractId, result.Args, 0 /*result.ExecutionTime*/ , result.ReadSet, result.WriteSet, result.Payload, modules.ContractError{}) if payload != nil { msgs = append(msgs, modules.NewMessage(modules.APP_CONTRACT_INVOKE, payload)) } @@ -794,3 +794,15 @@ func getValidAddress(addrs []common.Address) []common.Address { } return result } + +func checkJuryCountValid(numIn, numLocal uint64) bool { + if numLocal <= 0 { + log.Error("checkJuryCountValid, numLocal is 0") + return false + } + if int(math.Abs(float64(numIn-numLocal))*100/float64(numLocal)) <= 10 { + return true + } + log.Error("checkJuryCountValid", "numIn", numIn, "numLocal", numLocal) + return false +} diff --git a/consensus/jury/contractEvent.go b/consensus/jury/contractEvent.go index 3392b577e..d47b211bf 100755 --- a/consensus/jury/contractEvent.go +++ b/consensus/jury/contractEvent.go @@ -53,7 +53,7 @@ func (p *Processor) ProcessContractEvent(event *ContractEvent) error { err := fmt.Sprintf("[%s]ProcessContractEvent, event Tx addr is invalid, txId:%s", shortId(reqId.String()), event.Tx.Hash().String()) return errors.New(err) } - if !p.contractEventExecutable(event.CType, event.Tx, event.Ele) { + if !p.contractEventExecutable(event.CType, event.Tx, event.Ele, event.JuryCount) { log.Debugf("[%s]ProcessContractEvent, contractEventExecutable is false", shortId(reqId.String())) return nil } @@ -113,7 +113,8 @@ func (p *Processor) contractEleEvent(tx *modules.Transaction) error { } if elesLen < p.electionNum { reqEvent := &ElectionRequestEvent{ - ReqId: reqId, + ReqId: reqId, + JuryCount: uint64(p.dag.JuryCount()), } go p.ptn.ElectionBroadcast(ElectionEvent{EType: ELECTION_EVENT_VRF_REQUEST, Event: reqEvent}, true) } diff --git a/consensus/jury/election.go b/consensus/jury/election.go index 46e98191a..4e5256c2e 100755 --- a/consensus/jury/election.go +++ b/consensus/jury/election.go @@ -148,26 +148,49 @@ func (p *Processor) electionEventIsProcess(event *ElectionEvent) (common.Hash, b return common.Hash{}, false } reqId := common.Hash{} + jCnt := uint64(p.dag.JuryCount()) haveJ := p.localHaveActiveJury() haveM := p.ptn.LocalHaveActiveMediator() switch event.EType { case ELECTION_EVENT_VRF_REQUEST: - reqId = event.Event.(*ElectionRequestEvent).ReqId + evt := event.Event.(*ElectionRequestEvent) + reqId = evt.ReqId + if !checkJuryCountValid(evt.JuryCount, jCnt) { + return reqId, false + } if haveJ { //localHaveActiveJury() return reqId, true } case ELECTION_EVENT_VRF_RESULT: - reqId = event.Event.(*ElectionResultEvent).ReqId + evt := event.Event.(*ElectionResultEvent) + reqId = evt.ReqId + if evt.Ele.Etype != 1 { + if !checkJuryCountValid(evt.JuryCount, jCnt) { + return reqId, false + } + } if haveJ { //localHaveActiveJury() return reqId, true } case ELECTION_EVENT_SIG_REQUEST: - reqId = event.Event.(*ElectionSigRequestEvent).ReqId + evt := event.Event.(*ElectionSigRequestEvent) + reqId = evt.ReqId + for _, e := range evt.Ele { + if e.Etype != 1 { + if !checkJuryCountValid(evt.JuryCount, jCnt) { + return reqId, false + } + } + } if haveM { return reqId, true } case ELECTION_EVENT_SIG_RESULT: - reqId = event.Event.(*ElectionSigResultEvent).ReqId + evt := event.Event.(*ElectionSigResultEvent) + reqId = evt.ReqId + if !checkJuryCountValid(evt.JuryCount, jCnt) { + return reqId, false + } if haveM { return reqId, true } @@ -246,12 +269,12 @@ func (p *Processor) checkElectionSigRequestEventValid(evt *ElectionSigRequestEve } etor := &elector{ num: uint(p.electionNum), - total: uint64(p.dag.JuryCount()), //需要固定 + total: evt.JuryCount, } etor.weight = electionWeightValue(etor.total) //jjhAd, _, err := p.dag.GetConfig(modules.FoundationAddress) for i, e := range evt.Ele { - if e.Etype == 1 { + if e.Etype == 1 { //todo //if err == nil && bytes.Equal(reqAddr[:], jjhAd) { // log.Debugf("[%s]checkElectionSigRequestEventValid, e.Etype == 1, ok, contractId[%s]", shortId(reqId.String()), string(contractId)) // continue @@ -263,7 +286,6 @@ func (p *Processor) checkElectionSigRequestEventValid(evt *ElectionSigRequestEve //} continue } - //验证proof是否通过 isVerify, err := etor.verifyVrf(e.Proof, getElectionSeedData(reqId), e.PublicKey) if err != nil || !isVerify { @@ -288,8 +310,9 @@ func (p *Processor) checkElectionSigResultEventValid(evt *ElectionSigResultEvent } ele := p.mtx[reqId].eleInf reqEvt := &ElectionSigRequestEvent{ - ReqId: reqId, - Ele: ele, + ReqId: reqId, + JuryCount: evt.JuryCount, + Ele: ele, } hash := util.RlpHash(reqEvt) if !crypto.VerifySignature(evt.Sig.PubKey, hash.Bytes(), evt.Sig.Signature) { @@ -320,7 +343,7 @@ func (p *Processor) processElectionRequestEvent(reqEvt *ElectionRequestEvent) (e } elr := &elector{ num: uint(p.electionNum), - total: uint64(p.dag.JuryCount()), // 100 todo dynamic acquisition + total: reqEvt.JuryCount, addr: account.Address, password: account.Password, ks: p.ptn.GetKeyStore(), @@ -340,8 +363,9 @@ func (p *Processor) processElectionRequestEvent(reqEvt *ElectionRequestEvent) (e } if proof != nil { rstEvt := &ElectionResultEvent{ - ReqId: reqEvt.ReqId, - Ele: modules.ElectionInf{AddrHash: addrHash, Proof: proof, PublicKey: pubKey}, + ReqId: reqEvt.ReqId, + JuryCount: reqEvt.JuryCount, + Ele: modules.ElectionInf{AddrHash: addrHash, Proof: proof, PublicKey: pubKey}, } log.Debugf("[%s]processElectionRequestEvent, ok", shortId(reqId.String())) go p.ptn.ElectionBroadcast(ElectionEvent{EType: ELECTION_EVENT_VRF_RESULT, Event: rstEvt}, true) @@ -383,7 +407,7 @@ func (p *Processor) processElectionResultEvent(rstEvt *ElectionResultEvent) erro //验证vrf elr := &elector{ num: uint(p.electionNum), - total: uint64(p.dag.JuryCount()), // 100 todo dynamic acquisition + total: rstEvt.JuryCount, ks: p.ptn.GetKeyStore(), } elr.weight = electionWeightValue(elr.total) @@ -396,6 +420,7 @@ func (p *Processor) processElectionResultEvent(rstEvt *ElectionResultEvent) erro //接收vrf if ok { log.Debugf("[%s]processElectionResultEvent, add ele, addHash[%s]", shortId(reqId.String()), rstEvt.Ele.AddrHash.String()) + mel.juryCnt = rstEvt.JuryCount mel.rcvEle = append(mel.rcvEle, rstEvt.Ele) } return nil @@ -432,19 +457,23 @@ func (p *Processor) processElectionSigRequestEvent(evt *ElectionSigRequestEvent) log.Debugf("[%s]processElectionSigRequestEvent, SigData fail", shortId(reqId.String())) return nil } - //todo + + ////////todo del //hash := util.RlpHash(evt) //if !crypto.VerifySignature(pk, hash.Bytes(), sig) { // log.Debugf("[%s]processElectionSigRequestEvent, VerifySignature fail", shortId(reqId.String())) //} //log.Debug("processElectionSigRequestEvent", "reqId", shortId(reqId.String()), "evt", evt, "PubKey", pk, "Signature", sig, "hash", hash) + //////// + if e, ok := p.mel[reqId]; ok { e.brded = true //关闭签名广播请求 e.sigReqEd = true } resultEvt := &ElectionSigResultEvent{ - ReqId: reqId, - Sig: modules.SignatureSet{PubKey: pk, Signature: sig}, + ReqId: reqId, + JuryCount: evt.JuryCount, + Sig: modules.SignatureSet{PubKey: pk, Signature: sig}, } //广播resultEvt go p.ptn.ElectionBroadcast(ElectionEvent{EType: ELECTION_EVENT_SIG_RESULT, Event: resultEvt}, true) @@ -516,8 +545,9 @@ func (p *Processor) BroadcastElectionSigRequestEvent() { se := p.selectElectionInf(mtx.eleInf, ele.rcvEle, p.electionNum) mtx.eleInf = se event := &ElectionSigRequestEvent{ - ReqId: reqId, - Ele: se, + ReqId: reqId, + JuryCount: ele.juryCnt, + Ele: se, } ele.brded = true ele.nType = 1 @@ -537,14 +567,13 @@ func (p *Processor) ProcessElectionEvent(event *ElectionEvent) (result *Election log.Infof("[%s]ProcessElectionEvent, electionEventIsProcess is false, event type[%v]", shortId(reqId.String()), event.EType) return nil, nil } - recved, invalid, err := p.electionEventBroadcast(event) + received, invalid, err := p.electionEventBroadcast(event) if err != nil { return nil, err - } else if recved || invalid { - log.Debugf("[%s]ProcessElectionEvent, recved=%v, invalid=%v", shortId(reqId.String()), recved, invalid) + } else if received || invalid { + log.Debugf("[%s]ProcessElectionEvent, received=%v, invalid=%v", shortId(reqId.String()), received, invalid) return nil, nil } - log.Infof("[%s]ProcessElectionEvent, event type[%v] ", shortId(reqId.String()), event.EType) if event.EType == ELECTION_EVENT_VRF_REQUEST { diff --git a/consensus/jury/event.go b/consensus/jury/event.go index b7a1d6c7b..35ffbe8e7 100755 --- a/consensus/jury/event.go +++ b/consensus/jury/event.go @@ -63,33 +63,38 @@ type JuryMsgAddr struct { //contract type ContractEvent struct { - CType ContractEventType - Ele []modules.ElectionInf - Tx *modules.Transaction + CType ContractEventType + JuryCount uint64 + Ele []modules.ElectionInf + Tx *modules.Transaction } -func (ce *ContractEvent) Hash() common.Hash{ +func (ce *ContractEvent) Hash() common.Hash { return util.RlpHash(ce) } //Election type ElectionRequestEvent struct { - ReqId common.Hash + ReqId common.Hash + JuryCount uint64 //Data []byte //election data, input as vrf. use reqId } type ElectionResultEvent struct { - ReqId common.Hash - Ele modules.ElectionInf + ReqId common.Hash + JuryCount uint64 + Ele modules.ElectionInf } //sig type ElectionSigRequestEvent struct { - ReqId common.Hash - Ele []modules.ElectionInf + ReqId common.Hash + JuryCount uint64 + Ele []modules.ElectionInf } type ElectionSigResultEvent struct { - ReqId common.Hash - Sig modules.SignatureSet + ReqId common.Hash + JuryCount uint64 + Sig modules.SignatureSet } type ElectionEvent struct { @@ -101,7 +106,7 @@ type ElectionEventBytes struct { Event []byte `json:"event"` } -func (es *ElectionEventBytes) Hash() common.Hash{ +func (es *ElectionEventBytes) Hash() common.Hash { return util.RlpHash(es) } @@ -123,14 +128,14 @@ func (es *ElectionEventBytes) ToElectionEvent() (*ElectionEvent, error) { return nil, err } event.Event = &evt - } else if es.EType == ELECTION_EVENT_SIG_REQUEST{ + } else if es.EType == ELECTION_EVENT_SIG_REQUEST { var evt ElectionSigRequestEvent err = json.Unmarshal(es.Event, &evt) if err != nil { return nil, err } event.Event = &evt - }else if es.EType == ELECTION_EVENT_SIG_RESULT{ + } else if es.EType == ELECTION_EVENT_SIG_RESULT { var evt ElectionSigResultEvent err = json.Unmarshal(es.Event, &evt) if err != nil { diff --git a/consensus/jury/service.go b/consensus/jury/service.go index b07c348f2..688ff4464 100755 --- a/consensus/jury/service.go +++ b/consensus/jury/service.go @@ -26,7 +26,7 @@ import ( "time" "encoding/json" - + "go.dedis.ch/kyber/v3" "github.com/coocood/freecache" "github.com/ethereum/go-ethereum/rlp" "github.com/palletone/go-palletone/common" @@ -46,7 +46,6 @@ import ( "github.com/palletone/go-palletone/dag/txspool" "github.com/palletone/go-palletone/tokenengine" "github.com/palletone/go-palletone/validator" - "go.dedis.ch/kyber/v3" ) type PalletOne interface { @@ -70,7 +69,7 @@ type iDag interface { GetActiveMediators() []common.Address GetTxHashByReqId(reqid common.Hash) (common.Hash, error) IsActiveJury(addr common.Address) bool - JuryCount() int + JuryCount() uint GetContractDevelopers() ([]common.Address, error) IsContractDeveloper(addr common.Address) bool GetStxoEntry(outpoint *modules.OutPoint) (*modules.Stxo, error) @@ -112,8 +111,9 @@ type nodeInfo struct { } type electionVrf struct { - brded bool //broadcasted - nType byte //ele type ? node type, 1:election sig requester. 0:receiver,not process election sig result event + brded bool //broadcasted + nType byte //ele type ? node type, 1:election sig requester. 0:receiver,not process election sig result event + juryCnt uint64 rcvEle []modules.ElectionInf //receive sigs []modules.SignatureSet @@ -515,7 +515,7 @@ func (p *Processor) AddContractLoop(rwM rwset.TxManager, txpool txspool.ITxPool, if !ctx.reqTx.IsSystemContract() { defer rwM.CloseTxSimulator(setChainId, reqId.String()) } - if ctx.reqTx.IsSystemContract() && p.contractEventExecutable(CONTRACT_EVENT_EXEC, ctx.reqTx, nil) { + if ctx.reqTx.IsSystemContract() && p.contractEventExecutable(CONTRACT_EVENT_EXEC, ctx.reqTx, nil,0) { if cType, err := getContractTxType(ctx.reqTx); err == nil && cType != modules.APP_CONTRACT_TPL_REQUEST { ctx.valid = false log.Debugf("[%s]AddContractLoop, A enter mtx, addr[%s]", shortId(reqId.String()), addr.String()) @@ -532,14 +532,14 @@ func (p *Processor) AddContractLoop(rwM rwset.TxManager, txpool txspool.ITxPool, continue } ctx.valid = false - reqId = ctx.rstTx.RequestHash() + + tx := ctx.rstTx + reqId = tx.RequestHash() if p.checkTxReqIdIsExist(reqId) { log.Debugf("[%s]AddContractLoop ,ReqId is exist, rst reqId[%s]", shortId(reqId.String()), reqId.String()) continue } log.Debugf("[%s]AddContractLoop, B enter mtx, addr[%s]", shortId(reqId.String()), addr.String()) - - tx := ctx.rstTx if tx.IsSystemContract() { sigTx, err := p.GenContractSigTransaction(addr, "", ctx.rstTx, ks) if err != nil { @@ -587,7 +587,7 @@ func (p *Processor) CheckContractTxValid(rwM rwset.TxManager, tx *modules.Transa } } //检查本阶段时候有合约执行权限 - if !p.contractEventExecutable(CONTRACT_EVENT_EXEC, tx, nil) { + if !p.contractEventExecutable(CONTRACT_EVENT_EXEC, tx, nil, 0) { log.Errorf("[%s]CheckContractTxValid, nodeContractExecutable false", shortId(reqId.String())) return false } @@ -617,7 +617,7 @@ func (p *Processor) isInLocalAddr(addrHash []common.Hash) bool { return false } -func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.ElectionInf, checkExit bool) bool { +func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.ElectionInf, juryCnt uint64, checkExit bool) bool { reqId := tx.RequestHash() if len(ele) < p.electionNum { log.Infof("[%s]isValidateElection, ElectionInf number not enough ,len(ele)[%d], set electionNum[%d]", shortId(reqId.String()), len(ele), p.electionNum) @@ -632,7 +632,7 @@ func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.El isExit := false etor := &elector{ num: uint(p.electionNum), - total: uint64(p.dag.JuryCount()), //todo from dag + total: juryCnt, } etor.weight = electionWeightValue(etor.total) for i, e := range ele { @@ -652,19 +652,12 @@ func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.El if e.Etype == 1 { jjhAd := p.dag.GetChainParameters().FoundationAddress if jjhAd == reqAddr.Str() { - //jjhAd, err := p.dag.GetConfig(modules.FoundationAddress) - //if err == nil && string(jjhAd) == reqAddr.Str() { - //if err == nil && bytes.Equal(reqAddr[:], jjhAd) { log.Debugf("[%s]isValidateElection, e.Etype == 1, ok, contractId[%s]", shortId(reqId.String()), string(contractId)) continue } else { log.Debugf("[%s]isValidateElection, e.Etype == 1, but not jjh request addr, contractId[%s]", shortId(reqId.String()), string(contractId)) - //log.Debugf("[%s]isValidateElection, reqAddr[%s], jjh[%s]", shortId(reqId.String()), string(reqAddr[:]), string(jjhAd)) - //log.Debugf("[%s]isValidateElection, reqAddr[%s], jjh[%s]", shortId(reqId.String()), reqAddr.Str(), string(jjhAd)) log.Debugf("[%s]isValidateElection, reqAddr[%s], jjh[%s]", shortId(reqId.String()), reqAddr.Str(), jjhAd) - - //continue //todo test return false } } @@ -680,6 +673,11 @@ func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.El return false } //验证proof是否通过 + localJuryNum := uint64(p.dag.JuryCount()) + if !checkJuryCountValid(juryCnt, uint64(localJuryNum)) { + log.Errorf("[%s]isValidateElection, index[%d],checkJuryCountValid fail, tx jury num[%d]--dag[%d]", shortId(reqId.String()), i, juryCnt, localJuryNum) + return false + } isVerify, err := etor.verifyVrf(e.Proof, conversionElectionSeedData(contractId), e.PublicKey) if err != nil || !isVerify { log.Infof("[%s]isValidateElection, index[%d],verifyVrf fail, contractId[%s]", shortId(reqId.String()), i, string(contractId)) @@ -695,7 +693,7 @@ func (p *Processor) isValidateElection(tx *modules.Transaction, ele []modules.El return true } -func (p *Processor) contractEventExecutable(event ContractEventType, tx *modules.Transaction, ele []modules.ElectionInf) bool { +func (p *Processor) contractEventExecutable(event ContractEventType, tx *modules.Transaction, ele []modules.ElectionInf, juryCnt uint64) bool { if tx == nil { log.Errorf("tx is nil") return false @@ -716,7 +714,7 @@ func (p *Processor) contractEventExecutable(event ContractEventType, tx *modules log.Debugf("[%s]contractEventExecutable, CONTRACT_EVENT_EXEC, Mediator, true", shortId(reqId.String())) return true } else if !isSysContract && isJury { - if p.isValidateElection(tx, ele, true) { + if p.isValidateElection(tx, ele, juryCnt, true) { log.Debugf("[%s]contractEventExecutable, CONTRACT_EVENT_EXEC, Jury, true", shortId(reqId.String())) return true } else { @@ -725,7 +723,7 @@ func (p *Processor) contractEventExecutable(event ContractEventType, tx *modules } case CONTRACT_EVENT_SIG: if !isSysContract && isJury { - if p.isValidateElection(tx, ele, false) { + if p.isValidateElection(tx, ele, juryCnt, false) { log.Debugf("[%s]contractEventExecutable, CONTRACT_EVENT_SIG, Jury, true", shortId(reqId.String())) return true } else { @@ -737,7 +735,7 @@ func (p *Processor) contractEventExecutable(event ContractEventType, tx *modules if isSysContract { log.Debugf("[%s]contractEventExecutable, CONTRACT_EVENT_COMMIT, Mediator, sysContract, true", shortId(reqId.String())) return true - } else if !isSysContract && p.isValidateElection(tx, ele, false) { + } else if !isSysContract && p.isValidateElection(tx, ele, juryCnt, false) { log.Debugf("[%s]contractEventExecutable, CONTRACT_EVENT_COMMIT, Mediator, userContract, true", shortId(reqId.String())) return true } else { diff --git a/contracts/ucc/usrccapi.go b/contracts/ucc/usrccapi.go index 73d501526..cd551d86a 100755 --- a/contracts/ucc/usrccapi.go +++ b/contracts/ucc/usrccapi.go @@ -53,10 +53,11 @@ func mockerDeployUserCC() error { } func DeployUserCC(contractId []byte, chaincodeData []byte, spec *pb.ChaincodeSpec, chainID string, txid string, txsim rwset.TxSimulator, timeout time.Duration) error { + //return mockerDeployUserCC() + cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{} var err error if cfg.DebugTest { - //return mockerDeployUserCC() cdDeploymentSpec, err = getDeploymentSpec(nil, spec) if err != nil { return err diff --git a/dag/getter_saver.go b/dag/getter_saver.go index d5d408ddc..477929ec9 100644 --- a/dag/getter_saver.go +++ b/dag/getter_saver.go @@ -236,12 +236,12 @@ func (d *Dag) GetMediatorInfo(address common.Address) *modules.MediatorInfo { return mi } -func (d *Dag) JuryCount() int { +func (d *Dag) JuryCount() uint { return 20 //todo test juryList, err := d.unstableStateRep.GetJuryCandidateList() if err != nil { - return len(juryList) + return uint(len(juryList)) } return 0 } From 03f605ef465fa7517cacd9e1216defd959a7404f Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Fri, 12 Jul 2019 18:35:45 +0800 Subject: [PATCH 21/44] Fix bug when deploying user contract --- consensus/jury/common.go | 5 +++++ contracts/core/chaincode_support.go | 4 ++-- contracts/core/handler.go | 1 + contracts/ucc/usrccapi.go | 1 + internal/ptnapi/contract_api.go | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) mode change 100644 => 100755 consensus/jury/common.go diff --git a/consensus/jury/common.go b/consensus/jury/common.go old mode 100644 new mode 100755 index 282feed48..2f152a92f --- a/consensus/jury/common.go +++ b/consensus/jury/common.go @@ -295,6 +295,11 @@ func runContractCmd(rwM rwset.TxManager, dag iDag, contract *contracts.Contract, args: reqPay.Args, timeout: time.Duration(reqPay.Timeout) * time.Second, } + fullArgs, err := handleMsg0(tx, dag, req.args) + if err != nil { + return nil, err + } + req.args = fullArgs deployResult, err := ContractProcess(rwM, contract, req) if err != nil { log.Error("runContractCmd ContractProcess ", "error", err.Error()) diff --git a/contracts/core/chaincode_support.go b/contracts/core/chaincode_support.go index cc518506f..b93b7cf5e 100755 --- a/contracts/core/chaincode_support.go +++ b/contracts/core/chaincode_support.go @@ -594,7 +594,7 @@ func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context. } if err != nil { log.Debugf("stopping due to error while launching: %+v", err) - errIgnore := chaincodeSupport.Stop(ctxt, cccid, cds, true) + errIgnore := chaincodeSupport.Stop(ctxt, cccid, cds, false) if errIgnore != nil { log.Debugf("stop failed: %+v", errIgnore) } @@ -805,7 +805,7 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, cccid if err != nil { err = errors.WithMessage(err, "failed to init chaincode") log.Errorf("%+v", err) - errIgnore := chaincodeSupport.Stop(context, cccid, cds, true) + errIgnore := chaincodeSupport.Stop(context, cccid, cds, false) if errIgnore != nil { log.Errorf("stop failed: %+v", errIgnore) } diff --git a/contracts/core/handler.go b/contracts/core/handler.go index ea65fd2c2..af001a32b 100755 --- a/contracts/core/handler.go +++ b/contracts/core/handler.go @@ -557,6 +557,7 @@ func (handler *Handler) processStream() error { log.Debugf("[%s]Received message %s from shim", shorttxid(in.Txid), in.Type.String()) if in.Type.String() == pb.ChaincodeMessage_ERROR.String() { log.Errorf("Got error: %s", string(in.Payload)) + } // we can spin off another Recv again diff --git a/contracts/ucc/usrccapi.go b/contracts/ucc/usrccapi.go index 73d501526..caebfda4b 100755 --- a/contracts/ucc/usrccapi.go +++ b/contracts/ucc/usrccapi.go @@ -74,6 +74,7 @@ func DeployUserCC(contractId []byte, chaincodeData []byte, spec *pb.ChaincodeSpe _, _, err = ccprov.ExecuteWithErrorFilter(ctxt, cccid, cdDeploymentSpec, timeout) if err != nil { log.Errorf("ExecuteWithErrorFilter with usercc.Name[%s] chainId[%s] err !!", cdDeploymentSpec.ChaincodeSpec.ChaincodeId.Name, chainID) + ccprov.Stop(ctxt, cccid, cdDeploymentSpec, false) return err } log.Debugf("user chaincode chainID[%s]-name[%s]-path[%s]-version[%s] deployed", chainID, cdDeploymentSpec.ChaincodeSpec.ChaincodeId.Name, cdDeploymentSpec.ChaincodeSpec.ChaincodeId.Path, cdDeploymentSpec.ChaincodeSpec.ChaincodeId.Version) diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index da856dece..3f017ba25 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -214,7 +214,7 @@ func (s *PublicContractAPI) Ccdeploytx(ctx context.Context, from, to, daoAmount, args[i] = []byte(arg) fmt.Printf("index[%d], value[%s]\n", i, arg) } - fullArgs := [][]byte{defaultMsg0, defaultMsg1} + fullArgs := [][]byte{defaultMsg0} fullArgs = append(fullArgs, args...) reqId, _, err := s.b.ContractDeployReqTx(fromAddr, toAddr, amount, fee, templateId, fullArgs, 0) contractAddr := crypto.RequestIdToContractAddress(reqId) From 814dfbd8cc76710a6784f97e3b6d94c6d30498db Mon Sep 17 00:00:00 2001 From: lk Date: Fri, 12 Jul 2019 18:45:42 +0800 Subject: [PATCH 22/44] Modify getAssetReference --- dag/common/unit_repository.go | 14 +++++++++++++- dag/storage/indexdb.go | 24 ------------------------ dag/storage/indexdb_test.go | 26 +------------------------- internal/ptnapi/walletapi.go | 4 ++-- 4 files changed, 16 insertions(+), 52 deletions(-) diff --git a/dag/common/unit_repository.go b/dag/common/unit_repository.go index 5143206e0..892ff3df6 100755 --- a/dag/common/unit_repository.go +++ b/dag/common/unit_repository.go @@ -1728,7 +1728,19 @@ func (rep *UnitRepository) RefreshAddrTxIndex() error { } func (rep *UnitRepository) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { - return rep.idxdb.GetTokenExistence(asset) + + txInfor, err := rep.GetAssetTxHistory(asset) + if err != nil { + return nil, err + } + for _, tx := range txInfor { + for _, msg := range tx.TxMessages { + pay := msg.Payload.(*modules.DataPayload) + ref := pay.Reference + return rep.idxdb.QueryProofOfExistenceByReference(ref) + } + } + return nil,nil } func (rep *UnitRepository) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) { diff --git a/dag/storage/indexdb.go b/dag/storage/indexdb.go index 582945f6e..28e2fa763 100755 --- a/dag/storage/indexdb.go +++ b/dag/storage/indexdb.go @@ -42,8 +42,6 @@ type IIndexDb interface { SaveTokenTxId(asset *modules.Asset, txid common.Hash) error GetTokenTxIds(asset *modules.Asset) ([]common.Hash, error) - SaveTokenExistence(asset *modules.Asset, poe *modules.ProofOfExistence) error - GetTokenExistence(asset *modules.Asset) ([]*modules.ProofOfExistence, error) SaveMainDataTxId(maindata []byte, txid common.Hash) error GetMainDataTxIds(maindata []byte) ([]common.Hash, error) @@ -85,28 +83,6 @@ func (db *IndexDb) GetTokenTxIds(asset *modules.Asset) ([]common.Hash, error) { return result, nil } -func (db *IndexDb) SaveTokenExistence(asset *modules.Asset, poe *modules.ProofOfExistence) error { - key := append(constants.TOKEN_EX_PREFIX, asset.Bytes()...) - key = append(key, poe.Reference...) - return StoreToRlpBytes(db.db, key, poe) -} - -func (db *IndexDb) GetTokenExistence(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { - prefix := append(constants.TOKEN_EX_PREFIX, asset.Bytes()...) - iter := db.db.NewIteratorWithPrefix(prefix) - result := []*modules.ProofOfExistence{} - for iter.Next() { - value := iter.Value() - poe := &modules.ProofOfExistence{} - err := rlp.DecodeBytes(value, poe) - if err != nil { - return nil, err - } - result = append(result, poe) - } - return result, nil -} - //save filehash key:IDX_MAIN_DATA_TXID value:Txid func (db *IndexDb) SaveMainDataTxId(filehash []byte, txid common.Hash) error { key := append(constants.IDX_MAIN_DATA_TXID, []byte(filehash)...) diff --git a/dag/storage/indexdb_test.go b/dag/storage/indexdb_test.go index b97903116..04e5cfa69 100644 --- a/dag/storage/indexdb_test.go +++ b/dag/storage/indexdb_test.go @@ -49,28 +49,4 @@ func TestIndexDb_QueryProofOfExistenceByReference(t *testing.T) { } } -func TestIndexDb_GetAssetReference(t *testing.T) { - uid := modules.UniqueId{0x28, 0x5a, 0x59, 0x29} - PTNCOIN := modules.AssetId{0x40, 0x00, 0x82, 0xBB, 0x08, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00} - t.Log(uid) - t.Log(PTNCOIN) - asset := &modules.Asset{} - asset.AssetId = PTNCOIN - asset.UniqueId = uid - t.Log(asset) - ref := []byte("APP1-News-123") - poe1 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News metadata json1"), Reference: ref, TxId: common.BytesToHash([]byte("txid")), UnitHash: common.Hash{}, Timestamp: 123} - poe2 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News op1"), Reference: ref, TxId: common.BytesToHash([]byte("txid1")), UnitHash: common.Hash{}, Timestamp: 333} - poe3 := &modules.ProofOfExistence{MainData: []byte("News Hash1"), ExtraData: []byte("News op2"), Reference: ref, TxId: common.BytesToHash([]byte("txid2")), UnitHash: common.Hash{}, Timestamp: 222} - db, _ := ptndb.NewMemDatabase() - idxdb := NewIndexDb(db) - err := idxdb.SaveTokenExistence(asset, poe1) - assert.Nil(t, err) - err = idxdb.SaveTokenExistence(asset, poe2) - err = idxdb.SaveTokenExistence(asset, poe3) - result, err := idxdb.GetTokenExistence(asset) - assert.Nil(t, err) - for _, poe := range result { - t.Logf("%s", poe.Reference) - } -} + diff --git a/internal/ptnapi/walletapi.go b/internal/ptnapi/walletapi.go index 55cfbf343..e8cbd6b2e 100755 --- a/internal/ptnapi/walletapi.go +++ b/internal/ptnapi/walletapi.go @@ -1060,8 +1060,8 @@ func (s *PrivateWalletAPI) TransferToken(ctx context.Context, asset string, from } if Extra != "" { textPayload := new(modules.DataPayload) - textPayload.MainData = []byte(asset) - textPayload.ExtraData = []byte(Extra) + textPayload.Reference = []byte(asset) + textPayload.MainData = []byte(Extra) rawTx.TxMessages = append(rawTx.TxMessages, modules.NewMessage(modules.APP_DATA, textPayload)) } //lockscript From 6f5b43583e30cc3ccafeead3202947d77ff41b41 Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Fri, 12 Jul 2019 20:56:53 +0800 Subject: [PATCH 23/44] Fix dag Mock UT --- dag/dag_mock.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dag/dag_mock.go b/dag/dag_mock.go index de1cbf2ca..4f9da7971 100644 --- a/dag/dag_mock.go +++ b/dag/dag_mock.go @@ -1651,3 +1651,18 @@ func (mr *MockIDagMockRecorder) QueryProofOfExistenceByReference(ref interface{} mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryProofOfExistenceByReference", reflect.TypeOf((*MockIDag)(nil).QueryProofOfExistenceByReference), ref) } + +// GetAssetReference mocks base method +func (m *MockIDag) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetAssetReference", asset) + ret0, _ := ret[0].([]*modules.ProofOfExistence) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetAssetReference indicates an expected call of GetAssetReference +func (mr *MockIDagMockRecorder) GetAssetReference(asset interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAssetReference", reflect.TypeOf((*MockIDag)(nil).GetAssetReference), asset) +} From 58d064ab28983af80bf945e26a025479302d92ca Mon Sep 17 00:00:00 2001 From: Devin Date: Sat, 13 Jul 2019 00:36:41 +0800 Subject: [PATCH 24/44] Add CryptoLib config to Ptn node. --- cmd/gptn/config.go | 7 ++++++- cmd/gptn/genesis_json.go | 1 + cmd/gptn/main.go | 2 +- cmd/utils/flags.go | 22 ++++++++++++---------- ptn/backend.go | 4 ++-- ptn/config.go | 7 ++----- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/cmd/gptn/config.go b/cmd/gptn/config.go index 99b1a32ec..0d29100b4 100755 --- a/cmd/gptn/config.go +++ b/cmd/gptn/config.go @@ -45,6 +45,8 @@ import ( "github.com/palletone/go-palletone/ptnjson" "github.com/palletone/go-palletone/statistics/dashboard" "gopkg.in/urfave/cli.v1" + "bytes" + "github.com/palletone/go-palletone/common/crypto" ) const defaultConfigPath = "./ptn-config.toml" @@ -256,7 +258,10 @@ func makeConfigNode(ctx *cli.Context, isInConsole bool) (*node.Node, FullConfig) adaptorPtnConfig(&cfg) utils.SetPtnConfig(ctx, stack, &cfg.Ptn) - + if bytes.Equal( cfg.Ptn.CryptoLib,[]byte{1,1}){ + fmt.Println("Use GM crypto lib") + crypto.MyCryptoLib=&crypto.CryptoGm{} + } if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) { cfg.Ptnstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name) } diff --git a/cmd/gptn/genesis_json.go b/cmd/gptn/genesis_json.go index 3afd10731..c11af7703 100755 --- a/cmd/gptn/genesis_json.go +++ b/cmd/gptn/genesis_json.go @@ -63,6 +63,7 @@ var ( ArgsUsage: " ", Flags: []cli.Flag{ GenesisJsonPathFlag, + utils.CryptoLibFlag, }, Category: "BLOCKCHAIN COMMANDS", Description: ` diff --git a/cmd/gptn/main.go b/cmd/gptn/main.go index 942d0aec2..a21f1eaf0 100755 --- a/cmd/gptn/main.go +++ b/cmd/gptn/main.go @@ -87,7 +87,7 @@ var ( utils.MaxPeersFlag, utils.MaxPendingPeersFlag, utils.EtherbaseFlag, - utils.GasPriceFlag, + utils.CryptoLibFlag, utils.MinerThreadsFlag, utils.MiningEnabledFlag, //utils.TargetGasLimitFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d3d464b7d..083d7b815 100755 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -21,7 +21,7 @@ import ( "crypto/ecdsa" "fmt" "io/ioutil" - "math/big" + "os" "path/filepath" "runtime" @@ -54,6 +54,7 @@ import ( "github.com/palletone/go-palletone/statistics/metrics" "github.com/palletone/go-palletone/statistics/ptnstats" "gopkg.in/urfave/cli.v1" + "encoding/hex" ) var ( @@ -295,10 +296,10 @@ var ( Usage: "Public address for block mining rewards (default = first account created)", Value: "0", } - GasPriceFlag = BigFlag{ - Name: "gasprice", - Usage: "Minimal gas price to accept for mining a transactions", - Value: ptn.DefaultConfig.GasPrice, + CryptoLibFlag = cli.StringFlag{ + Name: "cryptolib", + Usage: "set crypto lib,1st byte sign algorithm: 0,ECDSA-S256;1,GM-SM2 2ed byte hash algorithm: 0,SHA3;1,GM-SM3", + Value: hex.EncodeToString( ptn.DefaultConfig.CryptoLib), } ExtraDataFlag = cli.StringFlag{ Name: "extradata", @@ -1125,8 +1126,9 @@ func SetPtnConfig(ctx *cli.Context, stack *node.Node, cfg *ptn.Config) { if ctx.GlobalIsSet(ExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.GlobalString(ExtraDataFlag.Name)) } - if ctx.GlobalIsSet(GasPriceFlag.Name) { - cfg.GasPrice = GlobalBig(ctx, GasPriceFlag.Name) + if ctx.GlobalIsSet(CryptoLibFlag.Name) { + t:= ctx.GlobalString(CryptoLibFlag.Name) + cfg.CryptoLib,_ =hex.DecodeString(t) } if ctx.GlobalIsSet(VMEnableDebugFlag.Name) { // TODO(fjl): force-enable this in --dev mode @@ -1159,9 +1161,9 @@ func SetPtnConfig(ctx *cli.Context, stack *node.Node, cfg *ptn.Config) { } log.Info("Using developer account", "address", developer.Address) - if !ctx.GlobalIsSet(GasPriceFlag.Name) { - cfg.GasPrice = big.NewInt(1) - } + //if !ctx.GlobalIsSet(GasPriceFlag.Name) { + // cfg.GasPrice = big.NewInt(1) + //} } // TODO(fjl): move trie cache generations into config if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 { diff --git a/ptn/backend.go b/ptn/backend.go index 8a59d3fcc..04408228b 100755 --- a/ptn/backend.go +++ b/ptn/backend.go @@ -358,7 +358,7 @@ func (s *PalletOne) Stop() error { // append by Albert·Gou s.mediatorPlugin.Stop() - s.dag.Close() + if s.lesServer != nil { s.lesServer.Stop() } @@ -366,7 +366,7 @@ func (s *PalletOne) Stop() error { if s.corsServer != nil { s.corsServer.Stop() } - + s.dag.Close() return nil } diff --git a/ptn/config.go b/ptn/config.go index 662ab7ddf..213a15b0c 100755 --- a/ptn/config.go +++ b/ptn/config.go @@ -17,7 +17,6 @@ package ptn import ( - "math/big" "os" "os/user" @@ -26,8 +25,6 @@ import ( "time" "github.com/palletone/go-palletone/common/hexutil" - "github.com/palletone/go-palletone/configure" - //"github.com/palletone/go-palletone/consensus/consensusconfig" "github.com/palletone/go-palletone/consensus/jury" "github.com/palletone/go-palletone/consensus/mediatorplugin" @@ -48,7 +45,7 @@ var DefaultConfig = Config{ DatabaseCache: 768, TrieCache: 256, TrieTimeout: 5 * time.Minute, - GasPrice: big.NewInt(0.01 * configure.PalletOne), + CryptoLib: []byte{0,0}, TxPool: txspool.DefaultTxPoolConfig, Dag: dagconfig.DagConfig, @@ -103,7 +100,7 @@ type Config struct { //Etherbase common.Address `toml:",omitempty"` MinerThreads int `toml:",omitempty"` ExtraData []byte `toml:",omitempty"` - GasPrice *big.Int + CryptoLib []byte // Transaction pool options TxPool txspool.TxPoolConfig `toml:"-"` From ae0324e1edd36a432a13e43744f6675137dff961 Mon Sep 17 00:00:00 2001 From: Yang Jay Date: Mon, 15 Jul 2019 01:40:36 +0800 Subject: [PATCH 25/44] modified memdag && fixed UT errors --- dag/common/prop_repository_test.go | 2 +- dag/common/unit_produce_repository.go | 13 +- dag/common/unit_repository.go | 9 +- dag/dag.go | 52 ++++- dag/dag_unit.go | 15 +- dag/getter_saver.go | 20 +- dag/memunit/chain_tempdb.go | 64 ++++++ dag/memunit/interface.go | 2 +- dag/memunit/memdag.go | 302 ++++++++++++++------------ dag/memunit/memdag_test.go | 80 +++---- dag/memunit/tempdb.go | 7 - ptn/fetcher/fetcher.go | 24 +- ptn/handler.go | 16 +- 13 files changed, 377 insertions(+), 229 deletions(-) create mode 100644 dag/memunit/chain_tempdb.go diff --git a/dag/common/prop_repository_test.go b/dag/common/prop_repository_test.go index 0f82a8073..856cbff8f 100755 --- a/dag/common/prop_repository_test.go +++ b/dag/common/prop_repository_test.go @@ -78,7 +78,7 @@ func TestShuffle(t *testing.T) { for i := 0; i < 10; i++ { addrs := []common.Address{addr1, addr2, addr3, addr4, addr5} - Shuffle(addrs, uint64(i)) + //Shuffle(addrs, uint64(i)) addrJs, _ := json.Marshal(addrs) t.Logf("i:%d,addr:%s", i, addrJs) } diff --git a/dag/common/unit_produce_repository.go b/dag/common/unit_produce_repository.go index f4c9c8559..3cc6c6ef5 100644 --- a/dag/common/unit_produce_repository.go +++ b/dag/common/unit_produce_repository.go @@ -546,8 +546,9 @@ func (dag *UnitProduceRepository) updateActiveMediators() bool { // 2. 根据每个mediator的得票数,排序出前n个 active mediator log.Debugf("In this round, The active mediator's count is %v", mediatorCount) - sort.PartialSort(dag.mediatorVoteTally, mediatorCount) - + if dag.mediatorVoteTally.Len() > 0 { + sort.PartialSort(dag.mediatorVoteTally, mediatorCount) + } // 3. 更新每个mediator的得票数 for _, voteTally := range dag.mediatorVoteTally { med := dag.GetMediator(voteTally.candidate) @@ -562,9 +563,11 @@ func (dag *UnitProduceRepository) updateActiveMediators() bool { gp.PrecedingMediators = gp.ActiveMediators gp.ActiveMediators = make(map[common.Address]bool, mediatorCount) gp.ChainParameters.ActiveMediatorCount = uint8(mediatorCount) - for index := 0; index < mediatorCount; index++ { - voteTally := dag.mediatorVoteTally[index] - gp.ActiveMediators[voteTally.candidate] = true + if dag.mediatorVoteTally.Len() > 0 { + for index := 0; index < mediatorCount; index++ { + voteTally := dag.mediatorVoteTally[index] + gp.ActiveMediators[voteTally.candidate] = true + } } dag.propRep.StoreGlobalProp(gp) diff --git a/dag/common/unit_repository.go b/dag/common/unit_repository.go index 468ec97e1..ad1946bcc 100755 --- a/dag/common/unit_repository.go +++ b/dag/common/unit_repository.go @@ -53,7 +53,7 @@ type IUnitRepository interface { GetGenesisUnit() (*modules.Unit, error) //GenesisHeight() modules.ChainIndex SaveUnit(unit *modules.Unit, isGenesis bool) error - CreateUnit(mAddr common.Address, txpool txspool.ITxPool, t time.Time) (*modules.Unit, error) + CreateUnit(mAddr common.Address, txpool txspool.ITxPool, propdb IPropRepository, t time.Time) (*modules.Unit, error) IsGenesis(hash common.Hash) bool GetAddrTransactions(addr common.Address) ([]*modules.TransactionWithUnitInfo, error) GetHeaderByHash(hash common.Hash) (*modules.Header, error) @@ -406,7 +406,7 @@ create common unit @param mAddr is minner addr return: correct if error is nil, and otherwise is incorrect */ -func (rep *UnitRepository) CreateUnit(mAddr common.Address, txpool txspool.ITxPool, t time.Time) (*modules.Unit, error) { +func (rep *UnitRepository) CreateUnit(mAddr common.Address, txpool txspool.ITxPool, propdb IPropRepository, t time.Time) (*modules.Unit, error) { rep.lock.RLock() begin := time.Now() @@ -422,7 +422,8 @@ func (rep *UnitRepository) CreateUnit(mAddr common.Address, txpool txspool.ITxPo // get current world_state index. index := uint64(1) //isMain := true - phash, chainIndex, _, err := rep.propdb.GetNewestUnit(assetId) + phash, chainIndex, err := propdb.GetNewestUnit(assetId) + // phash, chainIndex, _, err := rep.propdb.GetNewestUnit(assetId) if err != nil { chainIndex = &modules.ChainIndex{AssetID: assetId, Index: index + 1} log.Error("GetCurrentChainIndex is failed.", "error", err) @@ -437,7 +438,7 @@ func (rep *UnitRepository) CreateUnit(mAddr common.Address, txpool txspool.ITxPo } header.ParentsHash = append(header.ParentsHash, phash) h_hash := header.HashWithOutTxRoot() - log.Debugf("Start txpool.GetSortedTxs..., parent hash:%s", phash.String()) + log.Infof("Start txpool.GetSortedTxs..., parent hash:%s", phash.String()) // step4. get transactions from txspool poolTxs, _ := txpool.GetSortedTxs(h_hash, chainIndex.Index) diff --git a/dag/dag.go b/dag/dag.go index 910b3220c..6aa1e3e39 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -27,6 +27,7 @@ import ( "sync/atomic" "time" + "github.com/coocood/freecache" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/event" "github.com/palletone/go-palletone/common/log" @@ -41,6 +42,7 @@ import ( "github.com/palletone/go-palletone/dag/memunit" "github.com/palletone/go-palletone/dag/migration" "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/dag/storage" "github.com/palletone/go-palletone/dag/txspool" "github.com/palletone/go-palletone/tokenengine" @@ -82,7 +84,9 @@ type Dag struct { } //type MemUtxos map[modules.OutPoint]*modules.Utxo - +func cache() palletcache.ICache { + return freecache.NewCache(1000 * 1024) +} func (d *Dag) IsEmpty() bool { it := d.Db.NewIterator() return !it.Next() @@ -268,10 +272,18 @@ func (d *Dag) InsertDag(units modules.Units, txpool txspool.ITxPool) (int, error u.NumberU64(), u.ParentHash()[0].TerminalString(), timestamp.Format("2006-01-02 15:04:05"), u.Author().Str()) - if err := d.Memdag.AddUnit(u, txpool); err != nil { + if a, b, c, dd, e, err := d.Memdag.AddUnit(u, txpool); err != nil { //return count, err log.Errorf("Memdag addUnit[%s] error:%s", u.UnitHash.String(), err.Error()) return count, nil + } else { + if a != nil { + d.unstableUnitRep = a + d.unstableUtxoRep = b + d.unstableStateRep = c + d.unstablePropRep = dd + d.unstableUnitProduceRep = e + } } log.Debugf("InsertDag[%s] #%d spent time:%s", u.UnitHash.String(), u.NumberU64(), time.Since(t1)) count += 1 @@ -464,7 +476,7 @@ func (d *Dag) refreshPartitionMemDag() { if !ok { d.initDataForMainChainHeader(mainChain) log.Debugf("Init main chain mem dag for:%s", mainChain.GasToken.String()) - pmemdag := memunit.NewMemDag(mainChain.GasToken, threshold, true, db, unitRep, propRep, d.stableStateRep) + pmemdag := memunit.NewMemDag(mainChain.GasToken, threshold, true, db, unitRep, propRep, d.stableStateRep, cache()) //pmemdag.SetUnstableRepositories(d.unstableUnitRep, d.unstableUtxoRep, d.unstableStateRep, d.unstablePropRep, d.unstableUnitProduceRep) d.PartitionMemDag[mainChain.GasToken] = pmemdag } else { @@ -488,7 +500,7 @@ func (d *Dag) refreshPartitionMemDag() { threshold := int(partition.StableThreshold) d.initDataForPartition(partition) log.Debugf("Init partition mem dag for:%s", ptoken.String()) - pmemdag := memunit.NewMemDag(ptoken, threshold, true, db, unitRep, propRep, d.stableStateRep) + pmemdag := memunit.NewMemDag(ptoken, threshold, true, db, unitRep, propRep, d.stableStateRep, cache()) //pmemdag.SetUnstableRepositories(d.unstableUnitRep, d.unstableUtxoRep, d.unstableStateRep, d.unstablePropRep, d.unstableUnitProduceRep) partitionMemdag[ptoken] = pmemdag } @@ -504,7 +516,7 @@ func (d *Dag) refreshPartitionMemDag() { if !ok { d.initDataForPartition(partition) log.Debugf("Init partition mem dag for:%s", ptoken.String()) - pmemdag := memunit.NewMemDag(ptoken, threshold, true, db, unitRep, propRep, d.stableStateRep) + pmemdag := memunit.NewMemDag(ptoken, threshold, true, db, unitRep, propRep, d.stableStateRep, cache()) //pmemdag.SetUnstableRepositories(d.unstableUnitRep, d.unstableUtxoRep, d.unstableStateRep, d.unstablePropRep, d.unstableUnitProduceRep) d.PartitionMemDag[ptoken] = pmemdag } else { @@ -548,7 +560,8 @@ func NewDag(db ptndb.Database, light bool) (*Dag, error) { //hash, idx, _ := stablePropRep.GetLastStableUnit(modules.PTNCOIN) gasToken := dagconfig.DagConfig.GetGasToken() threshold, _ := propRep.GetChainThreshold() - unstableChain := memunit.NewMemDag(gasToken, threshold, light /*false*/, db, unitRep, propRep, stateRep) + cache := freecache.NewCache(1000 * 1024) + unstableChain := memunit.NewMemDag(gasToken, threshold, light /*false*/, db, unitRep, propRep, stateRep, cache) tunitRep, tutxoRep, tstateRep, tpropRep, tUnitProduceRep := unstableChain.GetUnstableRepositories() //validate := validator.NewValidate(tunitRep, tutxoRep, tstateRep, tpropRep) //partitionMemdag := make(map[modules.AssetId]memunit.IMemDag) @@ -708,7 +721,7 @@ func NewDagForTest(db ptndb.Database) (*Dag, error) { threshold, _ := propRep.GetChainThreshold() //validate := validator.NewValidate(dagDb, utxoRep, stateDb, propRep) - unstableChain := memunit.NewMemDag(modules.PTNCOIN, threshold, false, db, unitRep, propRep, stateRep) + unstableChain := memunit.NewMemDag(modules.PTNCOIN, threshold, false, db, unitRep, propRep, stateRep, cache()) tunitRep, tutxoRep, tstateRep, tpropRep, tUnitProduceRep := unstableChain.GetUnstableRepositories() dag := &Dag{ @@ -885,7 +898,9 @@ func (d *Dag) GetContractJury(contractId []byte) ([]modules.ElectionInf, error) } func (d *Dag) CreateUnit(mAddr common.Address, txpool txspool.ITxPool, t time.Time) (*modules.Unit, error) { - return d.unstableUnitRep.CreateUnit(mAddr, txpool, t) + _, _, _, rep, _ := d.Memdag.GetUnstableRepositories() + + return d.unstableUnitRep.CreateUnit(mAddr, txpool, rep, t) } func (d *Dag) saveHeader(header *modules.Header) error { @@ -899,9 +914,18 @@ func (d *Dag) saveHeader(header *modules.Header) error { log.Error(err.Error()) return err } - if err := memdag.AddUnit(unit, nil); err != nil { + if a, b, c, dd, e, err := memdag.AddUnit(unit, nil); err != nil { return fmt.Errorf("Save MemDag, occurred error: %s", err.Error()) + } else { + if a != nil { + d.unstableUnitRep = a + d.unstableUtxoRep = b + d.unstableStateRep = c + d.unstablePropRep = dd + d.unstableUnitProduceRep = e + } } + return nil } @@ -940,10 +964,16 @@ func (d *Dag) SaveUnit(unit *modules.Unit, txpool txspool.ITxPool, isGenesis boo return nil } - if err := d.Memdag.AddUnit(unit, txpool); err != nil { + if a, b, c, dd, e, err := d.Memdag.AddUnit(unit, txpool); err != nil { return fmt.Errorf("Save MemDag, occurred error: %s", err.Error()) } else { - log.Debug("============= save_memdag_unit =================", "save_memdag_unit_hex", unit.Hash().String(), "index", unit.UnitHeader.Index()) + if a != nil { + d.unstableUnitRep = a + d.unstableUtxoRep = b + d.unstableStateRep = c + d.unstablePropRep = dd + d.unstableUnitProduceRep = e + } } return nil diff --git a/dag/dag_unit.go b/dag/dag_unit.go index 2c2af6745..e41433fbe 100644 --- a/dag/dag_unit.go +++ b/dag/dag_unit.go @@ -55,8 +55,8 @@ func (dag *Dag) GenerateUnit(when time.Time, producer common.Address, groupPubKe } newUnit.UnitHeader.Time = when.Unix() - newUnit.UnitHeader.ParentsHash[0] = dag.HeadUnitHash() - newUnit.UnitHeader.Number.Index = dag.HeadUnitNum() + 1 + //newUnit.UnitHeader.ParentsHash[0] = dag.HeadUnitHash() + //newUnit.UnitHeader.Number.Index = dag.HeadUnitNum() + 1 newUnit.UnitHeader.GroupPubKey = groupPubKey newUnit.Hash() @@ -67,12 +67,19 @@ func (dag *Dag) GenerateUnit(when time.Time, producer common.Address, groupPubKe } sign_unit.UnitSize = sign_unit.Size() - log.Debugf("Generate new unit index:[%d],hash:[%s],size:%s, parent unit[%s],txs[%d], spent time: %s", + log.Infof("Generate new unit index:[%d],hash:[%s],size:%s, parent unit[%s],txs[%d], spent time: %s", sign_unit.NumberU64(), sign_unit.Hash().String(), sign_unit.UnitSize.String(), sign_unit.UnitHeader.ParentsHash[0].String(), sign_unit.Txs.Len(), time.Since(t0).String()) //3.将新单元添加到MemDag中 - dag.Memdag.AddUnit(sign_unit, txpool) + a, b, c, d, e, err := dag.Memdag.AddUnit(sign_unit, txpool) + if a != nil && err == nil { + dag.unstableUnitRep = a + dag.unstableUtxoRep = b + dag.unstableStateRep = c + dag.unstablePropRep = d + dag.unstableUnitProduceRep = e + } //4.PostChainEvents //TODO add PostChainEvents diff --git a/dag/getter_saver.go b/dag/getter_saver.go index d5d408ddc..2cc0b3762 100644 --- a/dag/getter_saver.go +++ b/dag/getter_saver.go @@ -139,11 +139,15 @@ func (d *Dag) GetMediator(add common.Address) *core.Mediator { //} func (dag *Dag) GetSlotAtTime(when time.Time) uint32 { - return dag.unstablePropRep.GetSlotAtTime(when) + _, _, _, rep, _ := dag.Memdag.GetUnstableRepositories() + return rep.GetSlotAtTime(when) + //return dag.unstablePropRep.GetSlotAtTime(when) } func (dag *Dag) GetNewestUnitTimestamp(token modules.AssetId) (int64, error) { - return dag.unstablePropRep.GetNewestUnitTimestamp(token) + _, _, _, rep, _ := dag.Memdag.GetUnstableRepositories() + return rep.GetNewestUnitTimestamp(token) + //return dag.unstablePropRep.GetNewestUnitTimestamp(token) } func (dag *Dag) GetSlotTime(slotNum uint32) time.Time { @@ -156,13 +160,17 @@ func (dag *Dag) GetScheduledMediator(slotNum uint32) common.Address { func (dag *Dag) HeadUnitTime() int64 { gasToken := dagconfig.DagConfig.GetGasToken() - t, _ := dag.unstablePropRep.GetNewestUnitTimestamp(gasToken) + //t, _ := dag.unstablePropRep.GetNewestUnitTimestamp(gasToken) + _, _, _, rep, _ := dag.Memdag.GetUnstableRepositories() + t, _ := rep.GetNewestUnitTimestamp(gasToken) return t } func (dag *Dag) HeadUnitNum() uint64 { gasToken := dagconfig.DagConfig.GetGasToken() - _, idx, _ := dag.unstablePropRep.GetNewestUnit(gasToken) + //_, idx, _ := dag.unstablePropRep.GetNewestUnit(gasToken) + _, _, _, rep, _ := dag.Memdag.GetUnstableRepositories() + _, idx, _ := rep.GetNewestUnit(gasToken) return idx.Index } @@ -172,7 +180,9 @@ func (dag *Dag) LastMaintenanceTime() int64 { func (dag *Dag) HeadUnitHash() common.Hash { gasToken := dagconfig.DagConfig.GetGasToken() - hash, _, _ := dag.unstablePropRep.GetNewestUnit(gasToken) + _, _, _, rep, _ := dag.Memdag.GetUnstableRepositories() + hash, _, _ := rep.GetNewestUnit(gasToken) + //hash, _, _ := dag.unstablePropRep.GetNewestUnit(gasToken) return hash } diff --git a/dag/memunit/chain_tempdb.go b/dag/memunit/chain_tempdb.go new file mode 100644 index 000000000..dcc5977ba --- /dev/null +++ b/dag/memunit/chain_tempdb.go @@ -0,0 +1,64 @@ +package memunit + +import ( + "github.com/palletone/go-palletone/common/ptndb" + comm2 "github.com/palletone/go-palletone/dag/common" + "github.com/palletone/go-palletone/dag/modules" + "github.com/palletone/go-palletone/dag/palletcache" + "github.com/palletone/go-palletone/validator" +) + +type ChainTempDb struct { + Tempdb *Tempdb + UnitRep comm2.IUnitRepository + UtxoRep comm2.IUtxoRepository + StateRep comm2.IStateRepository + PropRep comm2.IPropRepository + UnitProduceRep comm2.IUnitProduceRepository + Validator validator.Validator + Unit *modules.Unit +} + +func NewChainTempDb(db ptndb.Database, cache palletcache.ICache) (*ChainTempDb, error) { + tempdb, _ := NewTempdb(db) + trep := comm2.NewUnitRepository4Db(tempdb) + tutxoRep := comm2.NewUtxoRepository4Db(tempdb) + tstateRep := comm2.NewStateRepository4Db(tempdb) + tpropRep := comm2.NewPropRepository4Db(tempdb) + tunitProduceRep := comm2.NewUnitProduceRepository(trep, tpropRep, tstateRep) + val := validator.NewValidate(trep, tutxoRep, tstateRep, tpropRep, cache) + + return &ChainTempDb{ + Tempdb: tempdb, + UnitRep: trep, + UtxoRep: tutxoRep, + StateRep: tstateRep, + PropRep: tpropRep, + UnitProduceRep: tunitProduceRep, + Validator: val, + }, nil +} + +func (chain_temp *ChainTempDb) AddUnit(unit *modules.Unit, saveHeaderOnly bool) (*ChainTempDb, error) { + if saveHeaderOnly { + err := chain_temp.UnitRep.SaveNewestHeader(unit.Header()) + if err != nil { + return chain_temp, err + } + } else { + err := chain_temp.UnitProduceRep.PushUnit(unit) + if err != nil { + return chain_temp, err + } + } + return &ChainTempDb{ + Tempdb: chain_temp.Tempdb, + UnitRep: chain_temp.UnitRep, + UtxoRep: chain_temp.UtxoRep, + StateRep: chain_temp.StateRep, + PropRep: chain_temp.PropRep, + UnitProduceRep: chain_temp.UnitProduceRep, + Validator: chain_temp.Validator, + Unit: unit, + }, nil +} diff --git a/dag/memunit/interface.go b/dag/memunit/interface.go index e70e99f6b..22ac19e69 100755 --- a/dag/memunit/interface.go +++ b/dag/memunit/interface.go @@ -44,7 +44,7 @@ import ( // } type IMemDag interface { - AddUnit(unit *modules.Unit, txpool txspool.ITxPool) error + AddUnit(unit *modules.Unit, txpool txspool.ITxPool) (common2.IUnitRepository, common2.IUtxoRepository, common2.IStateRepository, common2.IPropRepository, common2.IUnitProduceRepository, error) GetLastMainChainUnit() *modules.Unit GetChainUnits() map[common.Hash]*modules.Unit SetStableThreshold(threshold int) diff --git a/dag/memunit/memdag.go b/dag/memunit/memdag.go index 2635f1cac..23e11c276 100644 --- a/dag/memunit/memdag.go +++ b/dag/memunit/memdag.go @@ -47,26 +47,27 @@ type MemDag struct { stableUnitHeight uint64 lastMainChainUnit *modules.Unit threshold int + height_hashs map[uint64][]common.Hash orphanUnits sync.Map orphanUnitsParants sync.Map chainUnits sync.Map - tempdbunitRep map[common.Hash]common2.IUnitRepository - tempUtxoRep map[common.Hash]common2.IUtxoRepository - tempStateRep map[common.Hash]common2.IStateRepository - tempPropRep map[common.Hash]common2.IPropRepository - tempUnitProduceRep common2.IUnitProduceRepository + //tempdbunitRep map[common.Hash]common2.IUnitRepository + //tempUtxoRep map[common.Hash]common2.IUtxoRepository + //tempStateRep map[common.Hash]common2.IStateRepository + //tempPropRep map[common.Hash]common2.IPropRepository + //tempUnitProduceRep map[common.Hash]common2.IUnitProduceRepository ldbunitRep common2.IUnitRepository ldbPropRep common2.IPropRepository ldbUnitProduceRep common2.IUnitProduceRepository - tempdb map[common.Hash]*Tempdb + tempdb map[common.Hash]*ChainTempDb saveHeaderOnly bool lock sync.RWMutex - validator validator.Validator cache palletcache.ICache // append by albert·gou 用于通知群签名 toGroupSignFeed event.Feed toGroupSignScope event.SubscriptionScope + db ptndb.Database } func (pmg *MemDag) Close() { @@ -85,14 +86,7 @@ func (pmg *MemDag) SetStableThreshold(count int) { func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptndb.Database, stableUnitRep common2.IUnitRepository, propRep common2.IPropRepository, - stableStateRep common2.IStateRepository) *MemDag { - tempdb, _ := NewTempdb(db) - cache := freecache.NewCache(20 * 1024 * 1024) - trep := common2.NewUnitRepository4Db(tempdb) - tutxoRep := common2.NewUtxoRepository4Db(tempdb) - tstateRep := common2.NewStateRepository4Db(tempdb) - tpropRep := common2.NewPropRepository4Db(tempdb) - tempUnitProduceRep := common2.NewUnitProduceRepository(trep, tpropRep, tstateRep) + stableStateRep common2.IStateRepository, cache palletcache.ICache) *MemDag { ldbUnitProduceRep := common2.NewUnitProduceRepository(stableUnitRep, propRep, stableStateRep) stablehash, stbIndex, err := propRep.GetNewestUnit(token) if err != nil { @@ -114,18 +108,17 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn return nil } } - log.Debugf("Init MemDag[%s], get last stable unit[%s] to set lastMainChainUnit", token.String(), stablehash.String()) - v := validator.NewValidate(trep, tutxoRep, tstateRep, tpropRep, cache) memdag := &MemDag{ - token: token, - threshold: threshold, - ldbunitRep: stableUnitRep, - ldbPropRep: propRep, - tempdbunitRep: make(map[common.Hash]common2.IUnitRepository), - tempUtxoRep: make(map[common.Hash]common2.IUtxoRepository), - tempStateRep: make(map[common.Hash]common2.IStateRepository), - tempPropRep: make(map[common.Hash]common2.IPropRepository), - tempdb: make(map[common.Hash]*Tempdb), + token: token, + threshold: threshold, + ldbunitRep: stableUnitRep, + ldbPropRep: propRep, + //tempdbunitRep: make(map[common.Hash]common2.IUnitRepository), + //tempUtxoRep: make(map[common.Hash]common2.IUtxoRepository), + //tempStateRep: make(map[common.Hash]common2.IStateRepository), + //tempPropRep: make(map[common.Hash]common2.IPropRepository), + tempdb: make(map[common.Hash]*ChainTempDb), + height_hashs: make(map[uint64][]common.Hash), orphanUnits: sync.Map{}, orphanUnitsParants: sync.Map{}, chainUnits: sync.Map{}, @@ -133,17 +126,14 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn stableUnitHeight: stbIndex.Index, lastMainChainUnit: stableUnit, saveHeaderOnly: saveHeaderOnly, - validator: v, cache: cache, ldbUnitProduceRep: ldbUnitProduceRep, - tempUnitProduceRep: tempUnitProduceRep, + db: db, } - memdag.tempdbunitRep[stablehash] = trep - memdag.tempUtxoRep[stablehash] = tutxoRep - memdag.tempStateRep[stablehash] = tstateRep - memdag.tempPropRep[stablehash] = tpropRep - memdag.chainUnits.Store(stablehash, stableUnit) - memdag.tempdb[stablehash] = tempdb + temp, _ := NewChainTempDb(db, cache) + temp.Unit = stableUnit + memdag.tempdb[stablehash] = temp + memdag.chainUnits.Store(stablehash, temp) go memdag.loopRebuildTmpDb() return memdag @@ -166,18 +156,19 @@ func (chain *MemDag) loopRebuildTmpDb() { } func (chain *MemDag) GetUnstableRepositories() (common2.IUnitRepository, common2.IUtxoRepository, common2.IStateRepository, common2.IPropRepository, common2.IUnitProduceRepository) { last_main_hash := chain.lastMainChainUnit.Hash() - return chain.tempdbunitRep[last_main_hash], chain.tempUtxoRep[last_main_hash], chain.tempStateRep[last_main_hash], chain.tempPropRep[last_main_hash], chain.tempUnitProduceRep + temp_rep, _ := chain.getChainUnit(last_main_hash) + return temp_rep.UnitRep, temp_rep.UtxoRep, temp_rep.StateRep, temp_rep.PropRep, temp_rep.UnitProduceRep } func (chain *MemDag) GetHeaderByHash(hash common.Hash) (*modules.Header, error) { - if unit_rep, has := chain.tempdbunitRep[chain.lastMainChainUnit.Hash()]; has { - return unit_rep.GetHeaderByHash(hash) + if temp, has := chain.tempdb[chain.lastMainChainUnit.Hash()]; has { + return temp.UnitRep.GetHeaderByHash(hash) } return nil, errors.New("not found") } func (chain *MemDag) GetHeaderByNumber(number *modules.ChainIndex) (*modules.Header, error) { - if unit_rep, has := chain.tempdbunitRep[chain.lastMainChainUnit.Hash()]; has { - return unit_rep.GetHeaderByNumber(number) + if temp, has := chain.tempdb[chain.lastMainChainUnit.Hash()]; has { + return temp.UnitRep.GetHeaderByNumber(number) } return nil, errors.New("not found") } @@ -195,12 +186,12 @@ func (chain *MemDag) getHeaderByNumber(number *modules.ChainIndex) (*modules.Hea func (chain *MemDag) SetUnitGroupSign(uHash common.Hash /*, groupPubKey []byte*/, groupSign []byte, txpool txspool.ITxPool) error { //1. Set this unit as stable - unit, err := chain.getChainUnit(uHash) + unit_temp, err := chain.getChainUnit(uHash) if err != nil { log.Debugf("get Chain Unit error: %v", err.Error()) return err } - + unit := unit_temp.Unit if !(unit.NumberU64() > chain.stableUnitHeight) { return nil } @@ -250,7 +241,10 @@ func (chain *MemDag) setStableUnit(hash common.Hash, height uint64, txpool txspo max_height = unit.NumberU64() } chain.setNextStableUnit(unit, txpool) + } + // 更新tempdb ,将低于稳定单元的分叉链都删除 + go chain.delHeightUnitsAndTemp(max_height) log.InfoDynamic(func() string { return fmt.Sprintf("set next stable unit cost time: %s ,index: %d, hash: %s", time.Since(tt), height, hash.String()) @@ -336,7 +330,7 @@ func (chain *MemDag) checkStableCondition(unit *modules.Unit, txpool txspool.ITx childrenCofirmAddrs[u.Author()] = true if len(hs) >= chain.threshold { - log.Debugf("Unit[%s] has enough confirm address count=%d, make it to stable.", ustbHash.String(), len(hs)) + log.Infof("Unit[%s] has enough confirm address count=%d, make it to stable.", ustbHash.String(), len(hs)) chain.setStableUnit(ustbHash, u.NumberU64(), txpool) return true } @@ -345,18 +339,24 @@ func (chain *MemDag) checkStableCondition(unit *modules.Unit, txpool txspool.ITx return false } -//清空Tempdb,然后基于稳定单元到最新主链单元的路径,构建新的Tempdb +//清空主链的Tempdb,然后基于稳定单元到最新主链单元的路径,构建新的Tempdb func (chain *MemDag) rebuildTempdb() { - last_main_hash := chain.lastMainChainUnit.Hash() - forks := make([]common.Hash, 0) - for hash, temp := range chain.tempdb { - forks = append(forks, hash) - temp.Clear() - } - - unstableUnits := chain.getMainChainUnits() - for _, unit := range unstableUnits { - chain.saveUnitToDb(chain.tempdbunitRep[last_main_hash], chain.tempUnitProduceRep, unit) + for h, temp := range chain.tempdb { + var keep bool + temp.Tempdb.Clear() + if unit_temp, err := chain.getChainUnit(h); err == nil { + if unit_temp.Unit.NumberU64() > chain.stableUnitHeight { + keep = true + forks := chain.getForkUnits(unit_temp.Unit) + for _, u := range forks { + temp.AddUnit(u, chain.saveHeaderOnly) + } + chain.tempdb[h] = temp + } + } + if !keep { + delete(chain.tempdb, h) + } } } @@ -387,18 +387,22 @@ func (chain *MemDag) getMainChainUnits() []*modules.Unit { func (chain *MemDag) getForkUnits(unit *modules.Unit) []*modules.Unit { chain_units := chain.getChainUnits() - hash := unit.Hash() unstableCount := int(unit.NumberU64() - chain.stableUnitHeight) - unstableUnits := make([]*modules.Unit, unstableCount) - for i := 0; i < unstableCount; i++ { + if unstableCount <= 1 { + return append(make([]*modules.Unit, 0), unit) + } + hash := unit.ParentHash()[0] + fork_len := unstableCount - 1 + unstableUnits := make([]*modules.Unit, fork_len) + for i := 0; i < fork_len; i++ { u, ok := chain_units[hash] if !ok { - log.Errorf("getforks chainUnits don't have unit[%s], last_main[%s]", hash.String(), unit.Hash().String()) + log.Errorf("getforks chainUnits don't have unit[%s], last_main[%s]", hash.String(), chain.lastMainChainUnit.Hash().String()) } - unstableUnits[unstableCount-i-1] = u + unstableUnits[fork_len-i-1] = u hash = u.ParentHash()[0] } - return unstableUnits + return append(unstableUnits, unit) } //判断当前设置是保存Header还是Unit,将对应的对象保存到Tempdb数据库 @@ -430,24 +434,24 @@ func (chain *MemDag) removeUnitAndChildren(hash common.Hash, txpool txspool.ITxP } } -func (chain *MemDag) AddUnit(unit *modules.Unit, txpool txspool.ITxPool) error { +func (chain *MemDag) AddUnit(unit *modules.Unit, txpool txspool.ITxPool) (common2.IUnitRepository, common2.IUtxoRepository, common2.IStateRepository, common2.IPropRepository, common2.IUnitProduceRepository, error) { start := time.Now() if unit == nil { - return errors.ErrNullPoint + return nil, nil, nil, nil, nil, errors.ErrNullPoint } chain.lock.Lock() defer chain.lock.Unlock() if unit.NumberU64() <= chain.stableUnitHeight { log.Debugf("This unit is too old! Ignore it,stable unit height:%d, stable hash:%s", chain.stableUnitHeight, chain.stableUnitHash.String()) - return nil + return nil, nil, nil, nil, nil, nil } chain_units := chain.getChainUnits() if _, has := chain_units[unit.Hash()]; has { // 不重复添加 log.Infof("MemDag[%s] received a repeated unit, hash[%s] ", chain.token.String(), unit.Hash().String()) - return nil + return nil, nil, nil, nil, nil, nil } - err := chain.addUnit(unit, txpool) + a, b, c, d, e, err := chain.addUnit(unit, txpool) log.InfoDynamic(func() string { return fmt.Sprintf("MemDag[%s] AddUnit cost time: %v ,index: %d, hash: %s", chain.token.String(), time.Since(start), unit.NumberU64(), unit.Hash().String()) @@ -459,72 +463,103 @@ func (chain *MemDag) AddUnit(unit *modules.Unit, txpool txspool.ITxPool) error { go chain.toGroupSignFeed.Send(modules.ToGroupSignEvent{}) } - return err + return a, b, c, d, e, err } -func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) error { +func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common2.IUnitRepository, common2.IUtxoRepository, common2.IStateRepository, common2.IPropRepository, common2.IUnitProduceRepository, error) { parentHash := unit.ParentHash()[0] uHash := unit.Hash() height := unit.NumberU64() if _, ok := chain.getChainUnits()[parentHash]; ok || parentHash == chain.stableUnitHash { //add unit to chain + inter, _ := chain.chainUnits.Load(parentHash) + parent_temp := inter.(*ChainTempDb) log.Debugf("chain[%p] Add unit[%s] to chainUnits", chain, uHash.String()) //add at the end of main chain unit if parentHash == chain.lastMainChainUnit.Hash() { //Add a new unit to main chain //Check unit and it's txs are valid - //只有主链上添加单元时才能判断整个Unit的有效性 + tempdb, has := chain.tempdb[parentHash] + if !has { + tempdb, _ = NewChainTempDb(parent_temp.Tempdb, freecache.NewCache(1000*1024)) + } validateCode := validator.TxValidationCode_VALID if chain.saveHeaderOnly { - validateCode = chain.validator.ValidateHeader(unit.UnitHeader) + validateCode = tempdb.Validator.ValidateHeader(unit.UnitHeader) } else { - validateCode = chain.validator.ValidateUnitExceptGroupSig(unit) + validateCode = tempdb.Validator.ValidateUnitExceptGroupSig(unit) } if validateCode != validator.TxValidationCode_VALID { - return validator.NewValidateError(validateCode) + vali_err := validator.NewValidateError(validateCode) + log.Infof("validate main chain unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) + return nil, nil, nil, nil, nil, vali_err + } + tempdb, _ = tempdb.AddUnit(unit, chain.saveHeaderOnly) + chain.tempdb[uHash] = tempdb + chain.chainUnits.Store(uHash, tempdb) + if has { + delete(chain.tempdb, parentHash) + chain.setLastMainchainUnit(unit) + + start := time.Now() + if chain.checkStableCondition(unit, txpool) { //增加了单元后检查是否满足稳定单元的条件 + // 进行下一个unit的群签名 + log.Debugf("send toGroupSign event") + go chain.toGroupSignFeed.Send(modules.ToGroupSignEvent{}) + log.Debugf("unit[%s] checkStableCondition =true", uHash.String()) + log.InfoDynamic(func() string { + return fmt.Sprintf("check stable cost time: %s ,index: %d, hash: %s", + time.Since(start), height, uHash.String()) + }) + } } - chain.setLastMainchainUnit(unit) - chain.chainUnits.Store(uHash, unit) //update txpool's tx status to pending if len(unit.Txs) > 0 { go txpool.SetPendingTxs(unit.Hash(), height, unit.Txs) } - //增加了单元后检查是否满足稳定单元的条件 - start := time.Now() - // todo Albert·gou 待重做 优化逻辑 - if chain.checkStableCondition(unit, txpool) { - // 进行下一个unit的群签名 - log.Debugf("send toGroupSign event") - go chain.toGroupSignFeed.Send(modules.ToGroupSignEvent{}) - log.Debugf("unit[%s] checkStableCondition =true", uHash.String()) - } - log.InfoDynamic(func() string { - return fmt.Sprintf("check stable cost time: %s ,index: %d, hash: %s", - time.Since(start), height, uHash.String()) - }) + } else { //Fork unit start1 := time.Now() - unit_rep := chain.tempdbunitRep[parentHash] - chain.tempdbunitRep[uHash] = unit_rep - delete(chain.tempdbunitRep, parentHash) - chain.saveUnitToDb(unit_rep, chain.tempUnitProduceRep, unit) - log.DebugDynamic(func() string { - return fmt.Sprintf("save unit cost time: %s ,index: %d, hash: %s", + validateCode := validator.TxValidationCode_VALID + main_temp, has := chain.tempdb[parentHash] + if !has { // 分叉 + main_temp, _ = NewChainTempDb(chain.db, freecache.NewCache(1000*1024)) + forks := chain.getForkUnits(unit) + for i := 0; i < len(forks)-1; i++ { + main_temp, _ = main_temp.AddUnit(forks[i], chain.saveHeaderOnly) + } + } + if chain.saveHeaderOnly { + validateCode = main_temp.Validator.ValidateHeader(unit.UnitHeader) + } else { + validateCode = main_temp.Validator.ValidateUnitExceptGroupSig(unit) + } + if validateCode != validator.TxValidationCode_VALID { + vali_err := validator.NewValidateError(validateCode) + log.Infof("validate fork unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) + return nil, nil, nil, nil, nil, vali_err + } + temp, _ := main_temp.AddUnit(unit, chain.saveHeaderOnly) + delete(chain.tempdb, parentHash) // 删除parent的tempdb + chain.tempdb[uHash] = temp + chain.chainUnits.Store(uHash, temp) + + log.InfoDynamic(func() string { + return fmt.Sprintf("save fork unit cost time: %s ,index: %d, hash: %s", time.Since(start1), height, uHash.String()) }) - } else { //Fork unit - chain.chainUnits.Store(uHash, unit) // 满足切换主链条件, 则切换主链,更新主链单元。 - if unit.NumberU64() > chain.lastMainChainUnit.NumberU64() { - cur_confirm_num := chain.getCofirmAddrs(uHash, height) - main_confirm_num := chain.getCofirmAddrs(chain.lastMainChainUnit.Hash(), - chain.lastMainChainUnit.NumberU64()) - if cur_confirm_num > main_confirm_num { //Need switch main chain - chain.switchMainChain(unit, txpool) - } + if height > chain.lastMainChainUnit.NumberU64() { + log.Infof("switch main chain starting, fork index:%d, chain index:%d ,fork hash:%s, main hash:%s", height, + chain.lastMainChainUnit.NumberU64(), uHash.String(), chain.lastMainChainUnit.Hash().String()) + chain.switchMainChain(unit, txpool) log.InfoDynamic(func() string { - return fmt.Sprintf("switch chain ,count fork chain confirm address number:%d, main chain number:%d "+ - "index:%d ,hash:%s,main_hash:%s", cur_confirm_num, main_confirm_num, height, uHash.String(), chain.lastMainChainUnit.Hash().String()) + main_chains := chain.getMainChainUnits() + hashs := make([]common.Hash, 0) + for _, u := range main_chains { + hashs = append(hashs, u.UnitHash) + } + return fmt.Sprintf("switch chain end , main_chains:[%#x]", hashs) }) } } @@ -540,7 +575,9 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) error { chain.orphanUnits.Store(uHash, unit) chain.orphanUnitsParants.Store(unit.ParentHash()[0], uHash) } - return nil + chain.addUnitHeight(unit) + tmp := chain.tempdb[chain.lastMainChainUnit.Hash()] + return tmp.UnitRep, tmp.UtxoRep, tmp.StateRep, tmp.PropRep, tmp.UnitProduceRep, nil } func (chain *MemDag) getCofirmAddrs(hash common.Hash, height uint64) int { log.Infof("get confirm address index:%d,stable_height:%d,hash: %s", height, chain.stableUnitHeight, hash.String()) @@ -568,6 +605,30 @@ func (chain *MemDag) getCofirmAddrs(hash common.Hash, height uint64) int { return num } +// 缓存该高度的所有单元hash +func (chain *MemDag) addUnitHeight(unit *modules.Unit) { + height := unit.NumberU64() + hs := make([]common.Hash, 0) + all, has := chain.height_hashs[height] + if has { + hs = append(hs, all...) + } + hs = append(hs, unit.Hash()) + chain.height_hashs[height] = hs +} + +// 单元稳定后,清空该高度的所有缓存 +func (chain *MemDag) delHeightUnitsAndTemp(height uint64) { + for hei, all := range chain.height_hashs { + if hei <= height { + for _, hash := range all { + delete(chain.tempdb, hash) + } + delete(chain.height_hashs, height) + } + } +} + //计算一个单元到稳定单元之间有多少个确认地址数 func (chain *MemDag) getChainAddressCount(lastUnit *modules.Unit) int { addrs := map[common.Address]bool{} @@ -593,17 +654,9 @@ func (chain *MemDag) switchMainChain(newUnit *modules.Unit, txpool txspool.ITxPo if forks_units == nil { return } + for _, m_u := range forks_units { - // 验证单元有效性 hash := m_u.Hash() - validateCode := chain.validator.ValidateUnitExceptGroupSig(m_u) - if validateCode != validator.TxValidationCode_VALID { - log.Infof("switch main chain error:%s, hash:%s", validator.NewValidateError(validateCode).Error(), hash.String()) - // coinbase 验证失败,会误删unit , 下次切换主链时,不连续的链会panic。 - // go chain.removeUnitAndChildren(hash, txpool) - return - } - if _, has := chain_units[hash]; has { delete(chain_units, hash) } @@ -624,10 +677,7 @@ func (chain *MemDag) switchMainChain(newUnit *modules.Unit, txpool txspool.ITxPo } } //设置最新主链单元 - chain.tempdbunitRep[newUnit.Hash()] = chain.tempdbunitRep[chain.lastMainChainUnit.Hash()] chain.setLastMainchainUnit(newUnit) - //基于新主链的单元和稳定单元,重新构建Tempdb - chain.rebuildTempdb() } //将其从孤儿单元列表中删除,并添加到ChainUnits中。 @@ -669,16 +719,16 @@ func (chain *MemDag) getChainUnits() map[common.Hash]*modules.Unit { units := make(map[common.Hash]*modules.Unit) chain.chainUnits.Range(func(k, v interface{}) bool { hash := k.(common.Hash) - u := v.(*modules.Unit) - units[hash] = u + ct := v.(*ChainTempDb) + units[hash] = ct.Unit return true }) return units } -func (chain *MemDag) getChainUnit(hash common.Hash) (*modules.Unit, error) { +func (chain *MemDag) getChainUnit(hash common.Hash) (*ChainTempDb, error) { inter, ok := chain.chainUnits.Load(hash) if ok { - return inter.(*modules.Unit), nil + return inter.(*ChainTempDb), nil } return nil, errors.ErrNotFound } @@ -691,20 +741,6 @@ func (chain *MemDag) GetLastMainChainUnit() *modules.Unit { //设置最新的主链单元,并更新PropDB func (chain *MemDag) setLastMainchainUnit(unit *modules.Unit) { - // update tempdb interface - old_main_unit_hash := chain.lastMainChainUnit.Hash() - hash := unit.Hash() - chain.tempdbunitRep[hash] = chain.tempdbunitRep[old_main_unit_hash] - chain.tempPropRep[hash] = chain.tempPropRep[old_main_unit_hash] - chain.tempStateRep[hash] = chain.tempStateRep[old_main_unit_hash] - chain.tempUtxoRep[hash] = chain.tempUtxoRep[old_main_unit_hash] - chain.tempdb[hash] = chain.tempdb[old_main_unit_hash] - delete(chain.tempdbunitRep, old_main_unit_hash) - delete(chain.tempPropRep, old_main_unit_hash) - delete(chain.tempStateRep, old_main_unit_hash) - delete(chain.tempUtxoRep, old_main_unit_hash) - //delete(chain.tempdb, old_main_unit_hash) - chain.lastMainChainUnit = unit } diff --git a/dag/memunit/memdag_test.go b/dag/memunit/memdag_test.go index ee35f5b5f..15af9d2e6 100644 --- a/dag/memunit/memdag_test.go +++ b/dag/memunit/memdag_test.go @@ -31,13 +31,18 @@ import ( "github.com/palletone/go-palletone/dag/txspool" "github.com/stretchr/testify/assert" + "github.com/coocood/freecache" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/core" "github.com/palletone/go-palletone/dag/dagconfig" - "testing" + "github.com/palletone/go-palletone/dag/palletcache" "github.com/palletone/go-palletone/validator" + "testing" ) +func cache() palletcache.ICache { + return freecache.NewCache(1000 * 1024) +} func TestMemDag_AddUnit(t *testing.T) { //mockCtrl := gomock.NewController(t) //defer mockCtrl.Finish() @@ -57,9 +62,9 @@ func TestMemDag_AddUnit(t *testing.T) { propRep.StoreGlobalProp(modules.NewGlobalProp()) stateRep := dagcommon.NewStateRepository(stateDb) gasToken := dagconfig.DagConfig.GetGasToken() - memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep) + memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep, cache()) - err := memdag.AddUnit(newTestUnit(common.Hash{}, 0, key2), nil) + _, _, _, _, _, err := memdag.AddUnit(newTestUnit(common.Hash{}, 0, key2), nil) assert.Nil(t, err) } func BenchmarkMemDag_AddUnit(b *testing.B) { @@ -81,12 +86,12 @@ func BenchmarkMemDag_AddUnit(b *testing.B) { propRep.StoreGlobalProp(modules.NewGlobalProp()) stateRep := dagcommon.NewStateRepository(stateDb) gasToken := modules.PTNCOIN - memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep) + memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep, cache()) parentHash := lastHeader.Hash() for i := 0; i < b.N; i++ { unit := newTestUnit(parentHash, uint64(i+1), key1) - err := memdag.AddUnit(unit, nil) + _, _, _, _, _, err := memdag.AddUnit(unit, nil) assert.Nil(b, err) parentHash = unit.Hash() } @@ -97,14 +102,14 @@ func newTestUnit(parentHash common.Hash, height uint64, key []byte) *modules.Uni } var ( - key1, _ = crypto.MyCryptoLib.KeyGen() - pubKey1,_=crypto.MyCryptoLib.PrivateKeyToPubKey(key1) - addr1 = crypto.PubkeyBytesToAddress(pubKey1) - key2, _ = crypto.MyCryptoLib.KeyGen() - pubKey2,_=crypto.MyCryptoLib.PrivateKeyToPubKey(key2) - addr2 = crypto.PubkeyBytesToAddress(pubKey2) - key3, _ = crypto.MyCryptoLib.KeyGen() - key4, _ = crypto.MyCryptoLib.KeyGen() + key1, _ = crypto.MyCryptoLib.KeyGen() + pubKey1, _ = crypto.MyCryptoLib.PrivateKeyToPubKey(key1) + addr1 = crypto.PubkeyBytesToAddress(pubKey1) + key2, _ = crypto.MyCryptoLib.KeyGen() + pubKey2, _ = crypto.MyCryptoLib.PrivateKeyToPubKey(key2) + addr2 = crypto.PubkeyBytesToAddress(pubKey2) + key3, _ = crypto.MyCryptoLib.KeyGen() + key4, _ = crypto.MyCryptoLib.KeyGen() ) func newTestHeader(parentHash common.Hash, height uint64, key []byte) *modules.Header { @@ -119,13 +124,13 @@ func newTestHeader(parentHash common.Hash, height uint64, key []byte) *modules.H h.Number.Index = height h.Extra = make([]byte, 20) h.ParentsHash = []common.Hash{parentHash} - h.TxRoot = common.HexToHash("c35639062e40f8891cef2526b387f42e353b8f403b930106bb5aa3519e59e35f") + h.TxRoot = common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - sig, _ := crypto.MyCryptoLib.Sign(key,h.TxRoot[:]) + sig, _ := crypto.MyCryptoLib.Sign(key, h.TxRoot[:]) au.Signature = sig - au.PubKey,_ = crypto.MyCryptoLib.PrivateKeyToPubKey(key) + au.PubKey, _ = crypto.MyCryptoLib.PrivateKeyToPubKey(key) h.Authors = au - h.Time = int64(height) * 3 + h.Time = int64(1536451200) + 1000 return h } @@ -149,22 +154,21 @@ func TestMemDag_AddOrphanUnit(t *testing.T) { propRep := dagcommon.NewPropRepository(propDb) stateRep := dagcommon.NewStateRepository(stateDb) gasToken := modules.PTNCOIN - memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep) - memdag.validator=mockValidator() + memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep, cache()) u1 := newTestUnit(lastHeader.Hash(), 1, key2) log.Debugf("Try add unit[%x] to memdag", u1.Hash()) - err := memdag.AddUnit(u1, txpool) + _, _, _, _, _, err := memdag.AddUnit(u1, txpool) assert.Nil(t, err) assert.EqualValues(t, 1, memdag.GetLastMainChainUnit().NumberU64()) u2 := newTestUnit(u1.Hash(), 2, key1) u3 := newTestUnit(u2.Hash(), 3, key2) log.Debugf("Try add orphan unit[%x] to memdag", u3.Hash()) - err = memdag.AddUnit(u3, txpool) + _, _, _, _, _, err = memdag.AddUnit(u3, txpool) assert.Nil(t, err) assert.EqualValues(t, 1, memdag.GetLastMainChainUnit().NumberU64()) log.Debugf("Try add missed unit[%x] to memdag", u2.Hash()) - err = memdag.AddUnit(u2, txpool) + _, _, _, _, _, err = memdag.AddUnit(u2, txpool) assert.Nil(t, err) assert.EqualValues(t, 3, memdag.GetLastMainChainUnit().NumberU64()) } @@ -188,24 +192,24 @@ func TestMemDag_SwitchMainChain(t *testing.T) { propRep := dagcommon.NewPropRepository(propDb) stateRep := dagcommon.NewStateRepository(stateDb) gasToken := modules.PTNCOIN - memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep) - memdag.validator=mockValidator() + memdag := NewMemDag(gasToken, 2, false, db, unitRep, propRep, stateRep, cache()) + //memdag.validator = mockValidator() u1 := newTestUnit(u0.Hash(), 2, key2) log.Debugf("Try add unit[%x] to memdag", u1.Hash()) - err := memdag.AddUnit(u1, txpool) + _, _, _, _, _, err := memdag.AddUnit(u1, txpool) assert.Nil(t, err) assert.EqualValues(t, 2, memdag.GetLastMainChainUnit().NumberU64()) u22 := newTestUnit(u0.Hash(), 2, key1) log.Debugf("Try add side unit[%x] to memdag", u22.Hash()) - err = memdag.AddUnit(u22, txpool) + _, _, _, _, _, err = memdag.AddUnit(u22, txpool) assert.Nil(t, err) assert.EqualValues(t, u1.Hash(), memdag.GetLastMainChainUnit().Hash()) u33 := newTestUnit(u22.Hash(), 3, key2) log.Debugf("Try add new longest chain unit[%x] to memdag", u33.Hash()) - err = memdag.AddUnit(u33, txpool) + _, _, _, _, _, err = memdag.AddUnit(u33, txpool) assert.Nil(t, err) assert.EqualValues(t, 3, memdag.GetLastMainChainUnit().NumberU64()) } @@ -232,29 +236,31 @@ func mockMediatorInit(statedb storage.IStateDb, propDb storage.IPropertyDb) { ms.CurrentShuffledMediators = append(ms.CurrentShuffledMediators, addr2) propDb.StoreMediatorSchl(ms) } -func mockValidator() validator.Validator{ +func mockValidator() validator.Validator { return &mockValidate{} } -type mockValidate struct { +type mockValidate struct { } -func(v mockValidate)ValidateTx(tx *modules.Transaction, isFullTx bool) ([]*modules.Addition, validator.ValidationCode, error){ - return nil,validator.TxValidationCode_VALID,nil + +func (v mockValidate) ValidateTx(tx *modules.Transaction, isFullTx bool) ([]*modules.Addition, validator.ValidationCode, error) { + return nil, validator.TxValidationCode_VALID, nil } -func(v mockValidate)ValidateUnitExceptGroupSig(unit *modules.Unit) validator.ValidationCode{ +func (v mockValidate) ValidateUnitExceptGroupSig(unit *modules.Unit) validator.ValidationCode { return validator.TxValidationCode_VALID } -func(v mockValidate)ValidateUnitExceptPayment(unit *modules.Unit) error{ +func (v mockValidate) ValidateUnitExceptPayment(unit *modules.Unit) error { return nil } + //验证一个Header是否合法(Mediator签名有效) -func(v mockValidate)ValidateHeader(h *modules.Header) validator.ValidationCode{ +func (v mockValidate) ValidateHeader(h *modules.Header) validator.ValidationCode { return validator.TxValidationCode_VALID } -func(v mockValidate)ValidateUnitGroupSign(h *modules.Header) error{ +func (v mockValidate) ValidateUnitGroupSign(h *modules.Header) error { return nil } -func(v mockValidate)CheckTxIsExist(tx *modules.Transaction) bool{ +func (v mockValidate) CheckTxIsExist(tx *modules.Transaction) bool { return false -} \ No newline at end of file +} diff --git a/dag/memunit/tempdb.go b/dag/memunit/tempdb.go index 83e14809e..37aa3920b 100644 --- a/dag/memunit/tempdb.go +++ b/dag/memunit/tempdb.go @@ -48,13 +48,6 @@ func (db *Tempdb) Clear() { db.lock.Lock() defer db.lock.Unlock() - //for k := range db.kv { - // delete(db.kv, k) - //} - //for k := range db.deleted { - // delete(db.deleted, k) - //} - db.kv = make(map[string][]byte) db.deleted = make(map[string]bool) } diff --git a/ptn/fetcher/fetcher.go b/ptn/fetcher/fetcher.go index 17f5d6a3b..570a7679f 100755 --- a/ptn/fetcher/fetcher.go +++ b/ptn/fetcher/fetcher.go @@ -657,19 +657,17 @@ func (f *Fetcher) insert(peer string, block *modules.Unit) { log.Debug("Importing propagated block insert DAG", "peer", peer, "number", block.Number().Index, "hash", hash) go func() { defer func() { f.done <- hash }() - - // If the parent's unknown, abort insertion - //parent := f.isHeaderExist(block.ParentHash()) - parentsHash := block.ParentHash() - for _, parentHash := range parentsHash { - //fmt.Println("parentHash=>", parentHash) - log.Debug("Importing propagated block insert DAG Enter isHeaderExist") - if !f.isHeaderExist(parentHash) { - log.Warn("Unknown parent of propagated block", "peer", peer, "number", block.Number().Index, "hash", hash, "parent", parentHash) - return - } - log.Debug("Importing propagated block insert DAG End isHeaderExist") - } + // 如果本节点与主网断连后重连进p2p网络,那么接下来收到的单元很有可能是相对本节点的孤儿单元,则本节点会永远分叉回不去。 + //parentsHash := block.ParentHash() + //for _, parentHash := range parentsHash { + // //fmt.Println("parentHash=>", parentHash) + // log.Debug("Importing propagated block insert DAG Enter isHeaderExist") + // if !f.isHeaderExist(parentHash) { + // log.Warn("Unknown parent of propagated block", "peer", peer, "number", block.Number().Index, "hash", hash, "parent", parentHash) + // return + // } + // log.Debug("Importing propagated block insert DAG End isHeaderExist") + //} // Quickly validate the header and propagate the block if it passes switch err := f.verifyUnit(block); err { diff --git a/ptn/handler.go b/ptn/handler.go index caafe8efd..95a71cdcc 100755 --- a/ptn/handler.go +++ b/ptn/handler.go @@ -582,7 +582,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { // Transactions arrived, make sure we have a valid and fresh chain to handle them return pm.TxMsg(msg, p) - // append by Albert·Gou + // append by Albert·Gou case msg.Code == SigShareMsg: return pm.SigShareMsg(msg, p) @@ -651,13 +651,13 @@ func (pm *ProtocolManager) ContractReqLocalSend(event jury.ContractEvent) { // will only announce it's availability (depending what's requested). func (pm *ProtocolManager) BroadcastUnit(unit *modules.Unit, propagate bool) { hash := unit.Hash() - - for _, parentHash := range unit.ParentHash() { - if parent, err := pm.dag.GetUnitByHash(parentHash); err != nil || parent == nil { - log.Error("Propagating dangling block", "index", unit.Number().Index, "hash", hash, "parent_hash", parentHash.String()) - return - } - } + // 孤儿单元是需要同步的 + //for _, parentHash := range unit.ParentHash() { + // if parent, err := pm.dag.GetUnitByHash(parentHash); err != nil || parent == nil { + // log.Error("Propagating dangling block", "index", unit.Number().Index, "hash", hash, "parent_hash", parentHash.String()) + // return + // } + //} data, err := json.Marshal(unit) if err != nil { From 6bc1f2be954dbf40729af8399a3da93c0660f50d Mon Sep 17 00:00:00 2001 From: Yang Jay Date: Mon, 15 Jul 2019 01:52:52 +0800 Subject: [PATCH 26/44] fixed --- dag/memunit/chain_tempdb.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/dag/memunit/chain_tempdb.go b/dag/memunit/chain_tempdb.go index dcc5977ba..d194e845e 100644 --- a/dag/memunit/chain_tempdb.go +++ b/dag/memunit/chain_tempdb.go @@ -1,3 +1,23 @@ +/* + * + * This file is part of go-palletone. + * go-palletone is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * go-palletone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with go-palletone. If not, see . + * / + * + * * @author PalletOne core developer + * * @date 2018-2019 + * + */ + package memunit import ( From 81efb628be24e65e76713375b0dc8a21ea2908ae Mon Sep 17 00:00:00 2001 From: Yang Jay Date: Mon, 15 Jul 2019 13:03:53 +0800 Subject: [PATCH 27/44] fixed concurrent map error --- dag/memunit/memdag.go | 165 +++++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 75 deletions(-) diff --git a/dag/memunit/memdag.go b/dag/memunit/memdag.go index 23e11c276..543cc04a2 100644 --- a/dag/memunit/memdag.go +++ b/dag/memunit/memdag.go @@ -47,20 +47,15 @@ type MemDag struct { stableUnitHeight uint64 lastMainChainUnit *modules.Unit threshold int - height_hashs map[uint64][]common.Hash + height_hashs sync.Map orphanUnits sync.Map orphanUnitsParants sync.Map chainUnits sync.Map - //tempdbunitRep map[common.Hash]common2.IUnitRepository - //tempUtxoRep map[common.Hash]common2.IUtxoRepository - //tempStateRep map[common.Hash]common2.IStateRepository - //tempPropRep map[common.Hash]common2.IPropRepository - //tempUnitProduceRep map[common.Hash]common2.IUnitProduceRepository + tempdb sync.Map ldbunitRep common2.IUnitRepository ldbPropRep common2.IPropRepository ldbUnitProduceRep common2.IUnitProduceRepository - tempdb map[common.Hash]*ChainTempDb saveHeaderOnly bool lock sync.RWMutex cache palletcache.ICache @@ -109,16 +104,12 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn } } memdag := &MemDag{ - token: token, - threshold: threshold, - ldbunitRep: stableUnitRep, - ldbPropRep: propRep, - //tempdbunitRep: make(map[common.Hash]common2.IUnitRepository), - //tempUtxoRep: make(map[common.Hash]common2.IUtxoRepository), - //tempStateRep: make(map[common.Hash]common2.IStateRepository), - //tempPropRep: make(map[common.Hash]common2.IPropRepository), - tempdb: make(map[common.Hash]*ChainTempDb), - height_hashs: make(map[uint64][]common.Hash), + token: token, + threshold: threshold, + ldbunitRep: stableUnitRep, + ldbPropRep: propRep, + tempdb: sync.Map{}, + height_hashs: sync.Map{}, orphanUnits: sync.Map{}, orphanUnitsParants: sync.Map{}, chainUnits: sync.Map{}, @@ -132,7 +123,7 @@ func NewMemDag(token modules.AssetId, threshold int, saveHeaderOnly bool, db ptn } temp, _ := NewChainTempDb(db, cache) temp.Unit = stableUnit - memdag.tempdb[stablehash] = temp + memdag.tempdb.Store(stablehash, temp) memdag.chainUnits.Store(stablehash, temp) go memdag.loopRebuildTmpDb() @@ -161,13 +152,15 @@ func (chain *MemDag) GetUnstableRepositories() (common2.IUnitRepository, common2 } func (chain *MemDag) GetHeaderByHash(hash common.Hash) (*modules.Header, error) { - if temp, has := chain.tempdb[chain.lastMainChainUnit.Hash()]; has { + if inter, has := chain.tempdb.Load(chain.lastMainChainUnit.Hash()); has { + temp := inter.(*ChainTempDb) return temp.UnitRep.GetHeaderByHash(hash) } return nil, errors.New("not found") } func (chain *MemDag) GetHeaderByNumber(number *modules.ChainIndex) (*modules.Header, error) { - if temp, has := chain.tempdb[chain.lastMainChainUnit.Hash()]; has { + if inter, has := chain.tempdb.Load(chain.lastMainChainUnit.Hash()); has { + temp := inter.(*ChainTempDb) return temp.UnitRep.GetHeaderByNumber(number) } return nil, errors.New("not found") @@ -341,22 +334,27 @@ func (chain *MemDag) checkStableCondition(unit *modules.Unit, txpool txspool.ITx //清空主链的Tempdb,然后基于稳定单元到最新主链单元的路径,构建新的Tempdb func (chain *MemDag) rebuildTempdb() { - for h, temp := range chain.tempdb { - var keep bool - temp.Tempdb.Clear() - if unit_temp, err := chain.getChainUnit(h); err == nil { - if unit_temp.Unit.NumberU64() > chain.stableUnitHeight { - keep = true - forks := chain.getForkUnits(unit_temp.Unit) - for _, u := range forks { - temp.AddUnit(u, chain.saveHeaderOnly) + to_del := make([]common.Hash, 0) + chain.tempdb.Range(func(k, v interface{}) bool { + hash := k.(common.Hash) + if unit_temp, err := chain.getChainUnit(hash); err == nil { + if num := unit_temp.Unit.NumberU64(); num < chain.stableUnitHeight { + to_del = append(to_del, hash) + } else if num == chain.stableUnitHeight { + if unit_temp.Unit.Hash() != chain.stableUnitHash { + to_del = append(to_del, hash) } - chain.tempdb[h] = temp } } - if !keep { - delete(chain.tempdb, h) + return true + }) + for _, h := range to_del { + inter, ok := chain.tempdb.Load(h) + if ok { + temp := inter.(*ChainTempDb) + temp.Tempdb.Clear() } + chain.tempdb.Delete(h) } } @@ -448,7 +446,7 @@ func (chain *MemDag) AddUnit(unit *modules.Unit, txpool txspool.ITxPool) (common } chain_units := chain.getChainUnits() if _, has := chain_units[unit.Hash()]; has { // 不重复添加 - log.Infof("MemDag[%s] received a repeated unit, hash[%s] ", chain.token.String(), unit.Hash().String()) + log.Debugf("MemDag[%s] received a repeated unit, hash[%s] ", chain.token.String(), unit.Hash().String()) return nil, nil, nil, nil, nil, nil } a, b, c, d, e, err := chain.addUnit(unit, txpool) @@ -479,9 +477,12 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common if parentHash == chain.lastMainChainUnit.Hash() { //Add a new unit to main chain //Check unit and it's txs are valid - tempdb, has := chain.tempdb[parentHash] + tempdb := new(ChainTempDb) + inter_temp, has := chain.tempdb.Load(parentHash) if !has { tempdb, _ = NewChainTempDb(parent_temp.Tempdb, freecache.NewCache(1000*1024)) + } else { + tempdb = inter_temp.(*ChainTempDb) } validateCode := validator.TxValidationCode_VALID if chain.saveHeaderOnly { @@ -491,14 +492,14 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common } if validateCode != validator.TxValidationCode_VALID { vali_err := validator.NewValidateError(validateCode) - log.Infof("validate main chain unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) + log.Debugf("validate main chain unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) return nil, nil, nil, nil, nil, vali_err } tempdb, _ = tempdb.AddUnit(unit, chain.saveHeaderOnly) - chain.tempdb[uHash] = tempdb + chain.tempdb.Store(uHash, tempdb) chain.chainUnits.Store(uHash, tempdb) if has { - delete(chain.tempdb, parentHash) + chain.tempdb.Delete(parentHash) chain.setLastMainchainUnit(unit) start := time.Now() @@ -521,13 +522,16 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common } else { //Fork unit start1 := time.Now() validateCode := validator.TxValidationCode_VALID - main_temp, has := chain.tempdb[parentHash] + main_temp := new(ChainTempDb) + inter_main, has := chain.tempdb.Load(parentHash) if !has { // 分叉 main_temp, _ = NewChainTempDb(chain.db, freecache.NewCache(1000*1024)) forks := chain.getForkUnits(unit) for i := 0; i < len(forks)-1; i++ { main_temp, _ = main_temp.AddUnit(forks[i], chain.saveHeaderOnly) } + } else { + main_temp = inter_main.(*ChainTempDb) } if chain.saveHeaderOnly { validateCode = main_temp.Validator.ValidateHeader(unit.UnitHeader) @@ -536,12 +540,12 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common } if validateCode != validator.TxValidationCode_VALID { vali_err := validator.NewValidateError(validateCode) - log.Infof("validate fork unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) + log.Debugf("validate fork unit error, %s, unit hash:%s", vali_err.Error(), uHash.String()) return nil, nil, nil, nil, nil, vali_err } temp, _ := main_temp.AddUnit(unit, chain.saveHeaderOnly) - delete(chain.tempdb, parentHash) // 删除parent的tempdb - chain.tempdb[uHash] = temp + chain.tempdb.Delete(parentHash) // 删除parent的tempdb + chain.tempdb.Store(uHash, temp) chain.chainUnits.Store(uHash, temp) log.InfoDynamic(func() string { @@ -571,61 +575,72 @@ func (chain *MemDag) addUnit(unit *modules.Unit, txpool txspool.ITxPool) (common } } else { //add unit to orphan - log.Infof("This unit[%s] is an orphan unit", uHash.String()) + log.Debugf("This unit[%s] is an orphan unit", uHash.String()) chain.orphanUnits.Store(uHash, unit) chain.orphanUnitsParants.Store(unit.ParentHash()[0], uHash) } chain.addUnitHeight(unit) - tmp := chain.tempdb[chain.lastMainChainUnit.Hash()] + inter_tmp, _ := chain.tempdb.Load(chain.lastMainChainUnit.Hash()) + tmp := inter_tmp.(*ChainTempDb) return tmp.UnitRep, tmp.UtxoRep, tmp.StateRep, tmp.PropRep, tmp.UnitProduceRep, nil } -func (chain *MemDag) getCofirmAddrs(hash common.Hash, height uint64) int { - log.Infof("get confirm address index:%d,stable_height:%d,hash: %s", height, chain.stableUnitHeight, hash.String()) - num := 0 - count := int(height - chain.stableUnitHeight) - unstableCofirmAddrs := make(map[common.Hash]map[common.Address]bool) - childrenCofirmAddrs := make(map[common.Address]bool) - chain_units := chain.getChainUnits() - for i := 0; i < count; i++ { - u := chain_units[hash] - hs := unstableCofirmAddrs[hash] - if hs == nil { - hs = make(map[common.Address]bool) - unstableCofirmAddrs[hash] = hs - } - hs[u.Author()] = true - for addr := range childrenCofirmAddrs { - hs[addr] = true - } - childrenCofirmAddrs[u.Author()] = true - hash = u.ParentHash()[0] - num = len(hs) - } - return num -} +//func (chain *MemDag) getCofirmAddrs(hash common.Hash, height uint64) int { +// num := 0 +// count := int(height - chain.stableUnitHeight) +// unstableCofirmAddrs := make(map[common.Hash]map[common.Address]bool) +// childrenCofirmAddrs := make(map[common.Address]bool) +// chain_units := chain.getChainUnits() +// for i := 0; i < count; i++ { +// u := chain_units[hash] +// hs := unstableCofirmAddrs[hash] +// if hs == nil { +// hs = make(map[common.Address]bool) +// unstableCofirmAddrs[hash] = hs +// } +// hs[u.Author()] = true +// for addr := range childrenCofirmAddrs { +// hs[addr] = true +// } +// childrenCofirmAddrs[u.Author()] = true +// +// hash = u.ParentHash()[0] +// num = len(hs) +// } +// return num +//} // 缓存该高度的所有单元hash func (chain *MemDag) addUnitHeight(unit *modules.Unit) { height := unit.NumberU64() hs := make([]common.Hash, 0) - all, has := chain.height_hashs[height] + inter, has := chain.height_hashs.Load(height) if has { + all := inter.([]common.Hash) hs = append(hs, all...) } hs = append(hs, unit.Hash()) - chain.height_hashs[height] = hs + chain.height_hashs.Store(height, hs) } // 单元稳定后,清空该高度的所有缓存 func (chain *MemDag) delHeightUnitsAndTemp(height uint64) { - for hei, all := range chain.height_hashs { - if hei <= height { - for _, hash := range all { - delete(chain.tempdb, hash) - } - delete(chain.height_hashs, height) + to_del_h := make([]uint64, 0) + to_del_hash := make([]common.Hash, 0) + chain.height_hashs.Range(func(k, v interface{}) bool { + h := k.(uint64) + if h <= height { + to_del_h = append(to_del_h, h) + hashs := v.([]common.Hash) + to_del_hash = append(to_del_hash, hashs...) } + return true + }) + for _, h := range to_del_h { + chain.height_hashs.Delete(h) + } + for _, hash := range to_del_hash { + chain.tempdb.Delete(hash) } } From e6bb597dcfd46800295fb57ff73732857989b315 Mon Sep 17 00:00:00 2001 From: wzhyuan Date: Mon, 15 Jul 2019 15:40:26 +0800 Subject: [PATCH 28/44] update contract keystore action to private --- internal/ptnapi/contract_api.go | 10 ++++++++-- nohup.out | 0 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 nohup.out diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index 3f017ba25..265304ba7 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -59,6 +59,12 @@ func NewPublicContractAPI(b Backend) *PublicContractAPI { return &PublicContractAPI{b} } +type PrivateContractAPI struct { + b Backend +} +func NewPrivateContractAPI(b Backend) *PrivateContractAPI { + return &PrivateContractAPI{b} +} //contract command //install func (s *PublicContractAPI) Ccinstall(ctx context.Context, ccname, ccpath, ccversion, ccdescription, ccabi, cclanguage string) (hexutil.Bytes, error) { @@ -298,7 +304,7 @@ func (s *PublicContractAPI) CcinvokeToken(ctx context.Context, from, to, toToken return rsp1, err } -func (s *PublicContractAPI) CcinvoketxPass(ctx context.Context, from, to, daoAmount, daoFee, deployId string, param []string, password string, duration *uint64, certID string) (string, error) { +func (s *PrivateContractAPI) CcinvoketxPass(ctx context.Context, from, to, daoAmount, daoFee, deployId string, param []string, password string, duration *uint64, certID string) (string, error) { contractAddr, _ := common.StringToAddress(deployId) fromAddr, _ := common.StringToAddress(from) @@ -359,7 +365,7 @@ func (s *PublicContractAPI) Ccstoptx(ctx context.Context, from, to, daoAmount, d return hex.EncodeToString(reqId[:]), err } -func (s *PublicContractAPI) unlockKS(addr common.Address, password string, duration *uint64) error { +func (s *PrivateContractAPI) unlockKS(addr common.Address, password string, duration *uint64) error { const max = uint64(time.Duration(math.MaxInt64) / time.Second) var d time.Duration if duration == nil { diff --git a/nohup.out b/nohup.out new file mode 100644 index 000000000..e69de29bb From 7cfa99cc2530eab2380992c5690102887a7ded91 Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 15 Jul 2019 15:59:42 +0800 Subject: [PATCH 29/44] Ignore sm2.ofile --- .gitignore | 1 + common/crypto/gmsm/sm2/ofile | Bin 71 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 common/crypto/gmsm/sm2/ofile diff --git a/.gitignore b/.gitignore index 8e008c9fd..d4d860857 100755 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,4 @@ cmd/gptn/ gptn/ dag/transactions.rlp.new dag/transactions.rlp +ofile diff --git a/common/crypto/gmsm/sm2/ofile b/common/crypto/gmsm/sm2/ofile deleted file mode 100644 index b1188953c3bec92d380a745979ffff88fceef28d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71 zcmV-N0J#4!MFJrJnQnQM#{0R^cSEKJ@^U*uqxUKd#)s;Qx&(f5mTJtK0w5|WkdCq* dRh4-V{-4_O+}O)^V}%s)otdIC6{B}4%FC_lBLM&a From 037eb52e45d1eb94a6fd3e3a7d01c2562e34b1f8 Mon Sep 17 00:00:00 2001 From: lk Date: Mon, 15 Jul 2019 16:06:28 +0800 Subject: [PATCH 30/44] Modify interface type --- dag/common/unit_repository.go | 18 +++--------------- dag/dag.go | 2 +- dag/interface.go | 2 +- internal/ptnapi/backend.go | 2 +- internal/ptnapi/ptn_api.go | 7 +------ internal/ptnapi/walletapi.go | 7 +------ light/api_backend.go | 2 +- ptn/api_backend.go | 4 ++-- 8 files changed, 11 insertions(+), 33 deletions(-) diff --git a/dag/common/unit_repository.go b/dag/common/unit_repository.go index eeb3aa162..f29ac303c 100755 --- a/dag/common/unit_repository.go +++ b/dag/common/unit_repository.go @@ -99,7 +99,7 @@ type IUnitRepository interface { GetTxRequesterAddress(tx *modules.Transaction) (common.Address, error) //根据现有Tx数据,重新构建地址和Tx的关系索引 RefreshAddrTxIndex() error - GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) + GetAssetReference(asset []byte) ([]*modules.ProofOfExistence, error) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) SubscribeSysContractStateChangeEvent(ob AfterSysContractStateChangeEventFunc) SaveCommon(key, val []byte) error @@ -1728,20 +1728,8 @@ func (rep *UnitRepository) RefreshAddrTxIndex() error { return nil } -func (rep *UnitRepository) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { - - txInfor, err := rep.GetAssetTxHistory(asset) - if err != nil { - return nil, err - } - for _, tx := range txInfor { - for _, msg := range tx.TxMessages { - pay := msg.Payload.(*modules.DataPayload) - ref := pay.Reference - return rep.idxdb.QueryProofOfExistenceByReference(ref) - } - } - return nil,nil +func (rep *UnitRepository) GetAssetReference(asset []byte) ([]*modules.ProofOfExistence, error) { + return rep.idxdb.QueryProofOfExistenceByReference(asset) } func (rep *UnitRepository) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) { diff --git a/dag/dag.go b/dag/dag.go index 747452b61..6d0099aed 100644 --- a/dag/dag.go +++ b/dag/dag.go @@ -1221,6 +1221,6 @@ func (dag *Dag) QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOf return dag.stableUnitRep.QueryProofOfExistenceByReference(ref) } -func (dag *Dag) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { +func (dag *Dag) GetAssetReference(asset []byte) ([]*modules.ProofOfExistence, error) { return dag.stableUnitRep.GetAssetReference(asset) } diff --git a/dag/interface.go b/dag/interface.go index 99685bc42..634f4dbac 100644 --- a/dag/interface.go +++ b/dag/interface.go @@ -181,5 +181,5 @@ type IDag interface { GetDataVersion() (*modules.DataVersion, error) StoreDataVersion(dv *modules.DataVersion) error QueryProofOfExistenceByReference(ref []byte) ([]*modules.ProofOfExistence, error) - GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) + GetAssetReference(asset []byte) ([]*modules.ProofOfExistence, error) } diff --git a/internal/ptnapi/backend.go b/internal/ptnapi/backend.go index 8d558214b..ff69f5ce4 100755 --- a/internal/ptnapi/backend.go +++ b/internal/ptnapi/backend.go @@ -129,7 +129,7 @@ type Backend interface { GetAddressBalanceStatistics(token string, topN int) (*statistics.TokenAddressBalanceJson, error) GetAddrTxHistory(addr string) ([]*ptnjson.TxHistoryJson, error) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHistoryJson, error) - GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) + GetAssetExistence(asset string) ([]*ptnjson.ProofOfExistenceJson, error) //contract control ContractInstall(ccName string, ccPath string, ccVersion string, ccDescription, ccAbi, ccLanguage string) (TemplateId []byte, err error) ContractDeploy(templateId []byte, txid string, args [][]byte, timeout time.Duration) (deployId []byte, err error) diff --git a/internal/ptnapi/ptn_api.go b/internal/ptnapi/ptn_api.go index 6623b11a9..1e8e274bc 100755 --- a/internal/ptnapi/ptn_api.go +++ b/internal/ptnapi/ptn_api.go @@ -133,12 +133,7 @@ func (s *PublicBlockChainAPI) GetTokenTxHistory(ctx context.Context, assetStr st return result, err } -func (s *PublicBlockChainAPI) GetAssetExistence(ctx context.Context, assetStr string) ([]*ptnjson.ProofOfExistenceJson, error) { - asset := &modules.Asset{} - err := asset.SetString(assetStr) - if err != nil { - return nil, errors.New("Invalid asset string") - } +func (s *PublicBlockChainAPI) GetAssetExistence(ctx context.Context, asset string) ([]*ptnjson.ProofOfExistenceJson, error) { result, err := s.b.GetAssetExistence(asset) return result, err diff --git a/internal/ptnapi/walletapi.go b/internal/ptnapi/walletapi.go index e8cbd6b2e..3ffadb628 100755 --- a/internal/ptnapi/walletapi.go +++ b/internal/ptnapi/walletapi.go @@ -1216,12 +1216,7 @@ func (s *PublicWalletAPI) GetProofOfExistencesByRef(ctx context.Context, referen return s.b.QueryProofOfExistenceByReference(reference) } -func (s *PublicWalletAPI) GetProofOfExistencesByAsset(ctx context.Context, ass string) ([]*ptnjson.ProofOfExistenceJson, error) { - asset := &modules.Asset{} - err := asset.SetString(ass) - if err != nil { - return nil, errors.New("Invalid asset string") - } +func (s *PublicWalletAPI) GetProofOfExistencesByAsset(ctx context.Context, asset string) ([]*ptnjson.ProofOfExistenceJson, error) { return s.b.GetAssetExistence(asset) } diff --git a/light/api_backend.go b/light/api_backend.go index aa0eebdf5..2b69da285 100755 --- a/light/api_backend.go +++ b/light/api_backend.go @@ -416,7 +416,7 @@ func (b *LesApiBackend) GetAddrTxHistory(addr string) ([]*ptnjson.TxHistoryJson, func (b *LesApiBackend) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHistoryJson, error) { return nil, nil } -func (b *LesApiBackend) GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) { +func (b *LesApiBackend) GetAssetExistence(asset string) ([]*ptnjson.ProofOfExistenceJson, error) { return nil, nil } diff --git a/ptn/api_backend.go b/ptn/api_backend.go index 027975364..ad7bcd746 100755 --- a/ptn/api_backend.go +++ b/ptn/api_backend.go @@ -316,8 +316,8 @@ func (b *PtnApiBackend) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHi return txjs, nil } -func (b *PtnApiBackend) GetAssetExistence(asset *modules.Asset) ([]*ptnjson.ProofOfExistenceJson, error) { - poes, err := b.ptn.dag.GetAssetReference(asset) +func (b *PtnApiBackend) GetAssetExistence(asset string) ([]*ptnjson.ProofOfExistenceJson, error) { + poes, err := b.ptn.dag.GetAssetReference([]byte(asset)) if err != nil { return nil, err } From b8277552e3a2a7ae3ff3d7c01c30f3a9a46c982a Mon Sep 17 00:00:00 2001 From: etying Date: Mon, 15 Jul 2019 01:14:18 -0700 Subject: [PATCH 31/44] modify values --- light/server.go | 34 ++++++++++++++++++++++------------ light/utxo.go | 3 +-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/light/server.go b/light/server.go index 3932eac27..f08137dc0 100644 --- a/light/server.go +++ b/light/server.go @@ -42,6 +42,13 @@ import ( "time" ) +const ( + CodeErr = "error" + CodeOK = "ok" + CodeTimeout = "timeout" + CodeEmptyPeers = "empty peers" +) + type LesServer struct { config *ptn.Config protocolManager *ProtocolManager @@ -423,13 +430,13 @@ func (pm *ProtocolManager) ReqProofByTxHash(strhash string) string { result := vreq.Wait() if result == 0 { - return "OK" + return CodeOK } else if result == 1 { - return "error" + return CodeErr } else if result == 2 { - return "timeout" + return CodeTimeout } - return "errors" + return CodeErr } func (pm *ProtocolManager) ReqProofByRlptx(rlptx [][]byte) string { @@ -445,13 +452,13 @@ func (pm *ProtocolManager) ReqProofByRlptx(rlptx [][]byte) string { return err.Error() } if result == 0 { - return "OK" + return CodeOK } else if result == 1 { - return "error" + return CodeErr } else if result == 2 { - return "timeout" + return CodeTimeout } - return "errors" + return CodeErr } func (pm *ProtocolManager) SyncUTXOByAddr(addr string) string { @@ -471,17 +478,20 @@ func (pm *ProtocolManager) SyncUTXOByAddr(addr string) string { //random select peer to download GetAddrUtxos(addr) rand.Seed(time.Now().UnixNano()) peers := pm.peers.AllPeers(pm.assetId) + if len(peers) <= 0 { + return CodeEmptyPeers + } x := rand.Intn(len(peers)) p := peers[x] p.RequestUTXOs(0, 0, req.addr) result := req.Wait() if result == 0 { - return "OK" + return CodeOK } else if result == 1 { - return "error" + return CodeErr } else if result == 2 { - return "timeout" + return CodeTimeout } - return "errors" + return CodeErr } diff --git a/light/utxo.go b/light/utxo.go index 08819eb4b..64f503598 100644 --- a/light/utxo.go +++ b/light/utxo.go @@ -89,8 +89,7 @@ func (u *utxosRespData) decode(arrs [][][]byte) error { for _, arr := range arrs[1:] { var outpoint modules.OutPoint var utxo *modules.Utxo - //log.Debug("Light PalletOne","utxosRespData decode outpoint",string(arr[0])) - //log.Debug("Light PalletOne","utxosRespData decode utxo",string(arr[1])) + if err := json.Unmarshal(arr[0], &outpoint); err != nil { return err } From 6f4d58f4798d8007f64fe9ab0c7b69d45b097d3a Mon Sep 17 00:00:00 2001 From: Devin Date: Mon, 15 Jul 2019 17:04:57 +0800 Subject: [PATCH 32/44] Update dag_mock.go --- dag/dag_mock.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dag/dag_mock.go b/dag/dag_mock.go index 4f9da7971..224f9e162 100644 --- a/dag/dag_mock.go +++ b/dag/dag_mock.go @@ -1653,7 +1653,7 @@ func (mr *MockIDagMockRecorder) QueryProofOfExistenceByReference(ref interface{} } // GetAssetReference mocks base method -func (m *MockIDag) GetAssetReference(asset *modules.Asset) ([]*modules.ProofOfExistence, error) { +func (m *MockIDag) GetAssetReference(asset []byte) ([]*modules.ProofOfExistence, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetAssetReference", asset) ret0, _ := ret[0].([]*modules.ProofOfExistence) From 830cfc4e56b0fb6e812663244147d483f34bd33c Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Mon, 15 Jul 2019 18:29:05 +0800 Subject: [PATCH 33/44] Fix bug in user contract init when that was restarted --- contracts/manger/ccapi.go | 7 ++++--- contracts/platforms/util/utils.go | 3 +-- contracts/shim/handler.go | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/contracts/manger/ccapi.go b/contracts/manger/ccapi.go index 2401b1902..1d28658ca 100755 --- a/contracts/manger/ccapi.go +++ b/contracts/manger/ccapi.go @@ -18,12 +18,12 @@ import ( "github.com/palletone/go-palletone/contracts/scc" "github.com/palletone/go-palletone/contracts/ucc" + "github.com/palletone/go-palletone/common/util" "github.com/palletone/go-palletone/contracts/contractcfg" pb "github.com/palletone/go-palletone/core/vmContractPub/protos/peer" "github.com/palletone/go-palletone/dag" md "github.com/palletone/go-palletone/dag/modules" "github.com/palletone/go-palletone/dag/rwset" - "math/rand" "strings" ) @@ -349,9 +349,10 @@ func GetAllContainers(client *docker.Client) { log.Infof("common.StringToAddress err: %s", err.Error()) return } - txid := fmt.Sprintf("%08v", rand.New(rand.NewSource(time.Now().UnixNano())).Int31n(100000000)) + rd, err := crypto.GetRandomBytes(32) + txid := util.RlpHash(rd) log.Infof("==============需要重启====容器名称为-->%s,---->%s", name, hex.EncodeToString(contractAddr.Bytes21())) - _, err = StartChaincodeContainert(dag, "palletone", contractAddr.Bytes21(), txid) + _, err = StartChaincodeContainert(dag, "palletone", contractAddr.Bytes21(), txid.String()) if err != nil { log.Infof("startChaincodeContainert err: %s", err.Error()) return diff --git a/contracts/platforms/util/utils.go b/contracts/platforms/util/utils.go index b275c9ca9..e65c2c509 100755 --- a/contracts/platforms/util/utils.go +++ b/contracts/platforms/util/utils.go @@ -259,10 +259,9 @@ func DockerBuild(opts DockerBuildOptions) error { for { select { case <-time.After(contractcfg.GetConfig().ContractDeploytimeout): - log.Infof("======go build error") err := client.RemoveContainer(docker.RemoveContainerOptions{ID: id, Force: true}) if err != nil { - log.Infof("======go build error,%s", err.Error()) + log.Infof("remove container error: %s", err.Error()) } return } diff --git a/contracts/shim/handler.go b/contracts/shim/handler.go index 91980d4b7..b6886e3ff 100755 --- a/contracts/shim/handler.go +++ b/contracts/shim/handler.go @@ -218,8 +218,21 @@ func (handler *Handler) handleInit(msg *pb.ChaincodeMessage) { if nextStateMsg = errFunc(err, nil, stub.chaincodeEvent, "[%s]Init get error response. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { return } - - res := handler.cc.Init(stub) + for i, a := range stub.args { + fmt.Println(i, a) + } + res := pb.Response{} + if len(input.Args) != 0 { + log.Infof("user contract deploy") + res = handler.cc.Init(stub) + } else { + log.Infof("user contract restart") + res = pb.Response{ + Status: OK, + Message: "Restart container", + Payload: nil, + } + } log.Debugf("[%s]Init get response status: %d, payload len: %d", shorttxid(msg.Txid), res.Status, len(res.Payload)) if res.Status >= ERROR { From 289ac186690e8354c4da8fd20bae5dcefe43305f Mon Sep 17 00:00:00 2001 From: lk Date: Tue, 16 Jul 2019 10:34:11 +0800 Subject: [PATCH 34/44] Modify TextIndex config --- dag/dagconfig/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dag/dagconfig/config.go b/dag/dagconfig/config.go index c5ee47a87..1483f15c7 100755 --- a/dag/dagconfig/config.go +++ b/dag/dagconfig/config.go @@ -46,7 +46,7 @@ var DefaultConfig = Config{ PartitionForkUnitHeight: 0, AddrTxsIndex: false, Token721TxIndex: true, - TextFileHashIndex: false, + TextFileHashIndex: true, GasToken: DefaultToken, } From 9bb410b5b58650300d5d71420a2de1f1e3ec6638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E7=AB=8B=E5=8D=8E?= Date: Tue, 16 Jul 2019 10:44:49 +0800 Subject: [PATCH 35/44] add contract query RW close --- consensus/jury/service.go | 2 +- contracts/manger/endorser.go | 16 ---------------- ptn/api_backend.go | 1 + 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/consensus/jury/service.go b/consensus/jury/service.go index 688ff4464..bb7bfb98e 100755 --- a/consensus/jury/service.go +++ b/consensus/jury/service.go @@ -588,7 +588,7 @@ func (p *Processor) CheckContractTxValid(rwM rwset.TxManager, tx *modules.Transa } //检查本阶段时候有合约执行权限 if !p.contractEventExecutable(CONTRACT_EVENT_EXEC, tx, nil, 0) { - log.Errorf("[%s]CheckContractTxValid, nodeContractExecutable false", shortId(reqId.String())) + log.Debugf("[%s]CheckContractTxValid, nodeContractExecutable false", shortId(reqId.String())) return false } msgs, err := runContractCmd(rwM, p.dag, p.contract, tx, nil, p.errMsgEnable) // long time ... diff --git a/contracts/manger/endorser.go b/contracts/manger/endorser.go index c8ffbe231..4f82fe796 100755 --- a/contracts/manger/endorser.go +++ b/contracts/manger/endorser.go @@ -258,27 +258,11 @@ func (e *Endorser) ProcessProposal(rwM rwset.TxManager, idag dag.IDag, deployId cis, err := putils.GetChaincodeInvocationSpec(prop) if err != nil { } - unit, err := RwTxResult2DagInvokeUnit(txsim, txid, cis.ChaincodeSpec.ChaincodeId.Name, deployId, cis.ChaincodeSpec.Input.Args, tmout) if err != nil { log.Errorf("chainID[%s] converRwTxResult2DagUnit failed", chainID) return nil, nil, errors.New("Conver RwSet to dag unit fail") } - //for i := 0; i < len(unit.WriteSet); i++ { - // fmt.Printf("==unit=> %v\n", unit.WriteSet[i].IsDelete) - // fmt.Printf("==unit=> %s\n", unit.WriteSet[i].Key) - // fmt.Printf("==unit=> %s\n", unit.WriteSet[i].Value) - // fmt.Println() - // fmt.Println() - //} - //fmt.Println("===") - //if len(unit.TokenPayOut) > 0 { - // fmt.Printf("==unit=> %#v\n", unit.TokenPayOut[0]) - // fmt.Printf("==unit=> %s\n", unit.TokenPayOut[0].Asset.String()) - // fmt.Printf("==unit=> %d\n", unit.TokenPayOut[0].Amount) - // fmt.Printf("==unit=> %s\n", unit.TokenPayOut[0].PayTo.String()) - //} - // todo pResp.Response.Payload = res.Payload unit.Payload = res.Payload diff --git a/ptn/api_backend.go b/ptn/api_backend.go index ad7bcd746..1ca4dc1e7 100755 --- a/ptn/api_backend.go +++ b/ptn/api_backend.go @@ -592,6 +592,7 @@ func (b *PtnApiBackend) ContractQuery(contractId []byte, txid string, args [][]b //contractAddr := common.HexToAddress(hex.EncodeToString(contractId)) channelId := "palletone" rsp, err := b.ptn.contract.Invoke(rwset.RwM, channelId, contractId, txid, args, timeout) + rwset.RwM.Close() if err != nil { log.Debugf(" err!=nil =====>ContractQuery:contractId[%s]txid[%s]", hex.EncodeToString(contractId), txid) return nil, err From ce465a32b5f0964c950e310525217023ab03c446 Mon Sep 17 00:00:00 2001 From: shuizhongmose <602554102@qq.com> Date: Tue, 16 Jul 2019 12:07:16 +0800 Subject: [PATCH 36/44] fix digital certificate bdd error --- contracts/core/handler.go | 107 +++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/contracts/core/handler.go b/contracts/core/handler.go index af001a32b..68406eb7a 100755 --- a/contracts/core/handler.go +++ b/contracts/core/handler.go @@ -23,6 +23,7 @@ package core import ( "bytes" "fmt" + "github.com/palletone/go-palletone/contracts/syscontract" "io" "sync" "time" @@ -224,7 +225,7 @@ func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStre {Name: pb.ChaincodeMessage_PAY_OUT_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_SUPPLY_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_DEFINE_TOKEN.String(), Src: []string{readystate}, Dst: readystate}, - //{Name: pb.ChaincodeMessage_GET_CERT_STATE.String(), Src: []string{readystate}, Dst: readystate}, + {Name: pb.ChaincodeMessage_GET_CERT_STATE.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_SEND_JURY.String(), Src: []string{readystate}, Dst: readystate}, {Name: pb.ChaincodeMessage_RECV_JURY.String(), Src: []string{readystate}, Dst: readystate}, }, @@ -255,7 +256,7 @@ func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStre "after_" + pb.ChaincodeMessage_PAY_OUT_TOKEN.String(): func(e *fsm.Event) { v.enterPayOutToken(e) }, "after_" + pb.ChaincodeMessage_DEFINE_TOKEN.String(): func(e *fsm.Event) { v.enterDefineToken(e) }, "after_" + pb.ChaincodeMessage_SUPPLY_TOKEN.String(): func(e *fsm.Event) { v.enterSupplyToken(e) }, - //"after_" + pb.ChaincodeMessage_GET_CERT_STATE.String(): func(e *fsm.Event) { v.enterGetCertByID(e) }, + "after_" + pb.ChaincodeMessage_GET_CERT_STATE.String(): func(e *fsm.Event) { v.enterGetCertByID(e) }, }, ) @@ -2195,57 +2196,57 @@ func (handler *Handler) isRunning() bool { } } -//func (handler *Handler) enterGetCertByID(e *fsm.Event) { -// msg, ok := e.Args[0].(*pb.ChaincodeMessage) -// if !ok { -// e.Cancel(errors.New("received unexpected message type")) -// return -// } -// log.Debugf("[%s]Received %s, invoking get state from ledger", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_CERT_STATE) -// // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition -// // is completed before the next one is triggered. The previous state transition is deemed complete only when -// // the afterGetState function is exited. Interesting bug fix!! -// go func() { -// // Check if this is the unique state request from this chaincode txid -// uniqueReq := handler.createTXIDEntry(msg.ChannelId, msg.Txid) -// if !uniqueReq { -// // Drop this request -// log.Error("Another state request pending for this Txid. Cannot process.") -// return -// } -// -// var serialSendMsg *pb.ChaincodeMessage -// var txContext *transactionContext -// txContext, serialSendMsg = handler.isValidTxSim(msg.ChannelId, msg.Txid, -// "[%s]No ledger context for GetState. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) -// if txContext == nil { -// return -// } -// defer func() { -// handler.deleteTXIDEntry(msg.ChannelId, msg.Txid) -// log.Debugf("[%s]handleenterGetDepositConfig serial send %s", -// shorttxid(serialSendMsg.Txid), serialSendMsg.Type) -// handler.serialSendAsync(serialSendMsg, nil) -// }() -// keyForSystemConfig := &pb.KeyForSystemConfig{} -// unmarshalErr := proto.Unmarshal(msg.Payload, keyForSystemConfig) -// if unmarshalErr != nil { -// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(unmarshalErr.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} -// return -// } -// chaincodeID := handler.getCCRootName() -// contractID := syscontract.DigitalIdentityContractAddress.Bytes() -// payloadBytes, err := txContext.txsimulator.GetState(contractID, chaincodeID, keyForSystemConfig.Key) -// log.Debugf("[%s] getting cert bytes for chaincode %s, channel %s", shorttxid(msg.Txid), chaincodeID, msg.ChannelId) -// if err != nil { -// log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) -// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} -// return -// } -// log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_RESPONSE) -// serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId} -// }() -//} +func (handler *Handler) enterGetCertByID(e *fsm.Event) { + msg, ok := e.Args[0].(*pb.ChaincodeMessage) + if !ok { + e.Cancel(errors.New("received unexpected message type")) + return + } + log.Debugf("[%s]Received %s, invoking get state from ledger", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_CERT_STATE) + // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition + // is completed before the next one is triggered. The previous state transition is deemed complete only when + // the afterGetState function is exited. Interesting bug fix!! + go func() { + // Check if this is the unique state request from this chaincode txid + uniqueReq := handler.createTXIDEntry(msg.ChannelId, msg.Txid) + if !uniqueReq { + // Drop this request + log.Error("Another state request pending for this Txid. Cannot process.") + return + } + + var serialSendMsg *pb.ChaincodeMessage + var txContext *transactionContext + txContext, serialSendMsg = handler.isValidTxSim(msg.ChannelId, msg.Txid, + "[%s]No ledger context for GetState. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) + if txContext == nil { + return + } + defer func() { + handler.deleteTXIDEntry(msg.ChannelId, msg.Txid) + log.Debugf("[%s]handleenterGetDepositConfig serial send %s", + shorttxid(serialSendMsg.Txid), serialSendMsg.Type) + handler.serialSendAsync(serialSendMsg, nil) + }() + keyForSystemConfig := &pb.KeyForSystemConfig{} + unmarshalErr := proto.Unmarshal(msg.Payload, keyForSystemConfig) + if unmarshalErr != nil { + serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(unmarshalErr.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} + return + } + chaincodeID := handler.getCCRootName() + contractID := syscontract.DigitalIdentityContractAddress.Bytes() + payloadBytes, err := txContext.txsimulator.GetState(contractID, chaincodeID, keyForSystemConfig.Key) + log.Debugf("[%s] getting cert bytes for chaincode %s, channel %s", shorttxid(msg.Txid), chaincodeID, msg.ChannelId) + if err != nil { + log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) + serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId} + return + } + log.Debugf("[%s]Got deposit configs. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_RESPONSE) + serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId} + }() +} //glh /* From 2a4570467a9693f1fdf1ae5f6efd4b54970a76cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=C2=B7Gou?= Date: Tue, 16 Jul 2019 12:10:02 +0800 Subject: [PATCH 37/44] add dealBuf and refactor NewMediatorPlugin --- consensus/mediatorplugin/service.go | 133 +++++++++++++------------- ptn/backend.go | 4 +- ptn/{vss_groupsign.go => vss_tbls.go} | 0 3 files changed, 70 insertions(+), 67 deletions(-) rename ptn/{vss_groupsign.go => vss_tbls.go} (100%) mode change 100755 => 100644 diff --git a/consensus/mediatorplugin/service.go b/consensus/mediatorplugin/service.go index adf24619d..e96837089 100755 --- a/consensus/mediatorplugin/service.go +++ b/consensus/mediatorplugin/service.go @@ -86,7 +86,7 @@ type MediatorPlugin struct { ptn PalletOne // Full PalletOne service to retrieve other function quit chan struct{} // Channel used for graceful exit dag iDag - srvr *p2p.Server + //srvr *p2p.Server // 标记是否主程序启动时,就开启unit生产功能 producingEnabled bool @@ -119,6 +119,7 @@ type MediatorPlugin struct { precedingDKGs map[common.Address]*dkg.DistKeyGenerator // dkg 完成 vss 协议相关 + dealBuf map[common.Address]chan *dkg.Deal // todo 待加锁,防止写冲突 respBuf map[common.Address]map[common.Address]chan *dkg.Response @@ -165,31 +166,13 @@ func (mp *MediatorPlugin) APIs() []rpc.API { } } -func (mp *MediatorPlugin) ScheduleProductionLoop() { - // 1. 判断是否满足生产unit的条件,主要判断本节点是否控制至少一个mediator账户 - if len(mp.mediators) == 0 { - log.Debugf("No mediators configured! Please add mediator and private keys to configuration.") - } else { - // 2. 开启循环生产计划 - log.Infof("Launching unit production for %v mediators.", len(mp.mediators)) - - if mp.productionEnabled { - if mp.dag.HeadUnitNum() == 0 { - mp.newChainBanner() - } - } - - // 调度生产unit - go mp.scheduleProductionLoop() - } -} - func (mp *MediatorPlugin) newActiveMediatorsDKG() { dag := mp.dag - if !mp.productionEnabled && !dag.IsSynced() { - log.Debugf("we're not synced") - return - } + // 重复判断 + //if !mp.productionEnabled && !dag.IsSynced() { + // log.Debugf("we're not synced") + // return + //} lams := mp.GetLocalActiveMediators() initPubs := dag.GetActiveMediatorInitPubs() @@ -197,7 +180,8 @@ func (mp *MediatorPlugin) newActiveMediatorsDKG() { lamc := len(lams) mp.activeDKGs = make(map[common.Address]*dkg.DistKeyGenerator, lamc) - mp.respBuf = make(map[common.Address]map[common.Address]chan *dkg.Response, lamc) + //mp.dealBuf = make(map[common.Address]chan *dkg.Deal, lamc) + //mp.respBuf = make(map[common.Address]map[common.Address]chan *dkg.Response, lamc) for _, localMed := range lams { initSec := mp.mediators[localMed].InitPrivKey @@ -210,12 +194,14 @@ func (mp *MediatorPlugin) newActiveMediatorsDKG() { } mp.activeDKGs[localMed] = dkgr - mp.initRespBuf(localMed) + //mp.initVSSBuf(localMed) } } -func (mp *MediatorPlugin) initRespBuf(localMed common.Address) { +// todo Albert 待删除 +func (mp *MediatorPlugin) initVSSBuf(localMed common.Address) { aSize := mp.dag.ActiveMediatorsCount() + mp.dealBuf[localMed] = make(chan *dkg.Deal, aSize) mp.respBuf[localMed] = make(map[common.Address]chan *dkg.Response, aSize) for i := 0; i < aSize; i++ { @@ -226,17 +212,14 @@ func (mp *MediatorPlugin) initRespBuf(localMed common.Address) { func (mp *MediatorPlugin) Start(server *p2p.Server) error { log.Debugf("mediator plugin startup begin") - mp.srvr = server - - // 1. 解锁本地控制的mediator账户 - mp.unlockLocalMediators() + //mp.srvr = server - // 2. 开启循环生产计划 + // 开启循环生产计划 if mp.producingEnabled { go mp.ScheduleProductionLoop() } - // 3. 开始完成 vss 协议 + // 开始完成 vss 协议 // todo albert 待优化 //if mp.groupSigningEnabled { // go mp.startVSSProtocol() @@ -246,15 +229,22 @@ func (mp *MediatorPlugin) Start(server *p2p.Server) error { return nil } -func (mp *MediatorPlugin) unlockLocalMediators() { - ks := mp.ptn.GetKeyStore() +func (mp *MediatorPlugin) ScheduleProductionLoop() { + // 1. 判断是否满足生产unit的条件,主要判断本节点是否控制至少一个mediator账户 + if len(mp.mediators) == 0 { + log.Debugf("No mediators configured! Please add mediator and private keys to configuration.") + } else { + // 2. 开启循环生产计划 + log.Infof("Launching unit production for %v mediators.", len(mp.mediators)) - for add, medAcc := range mp.mediators { - err := ks.Unlock(accounts.Account{Address: add}, medAcc.Password) - if err != nil { - log.Debugf("fail to unlock the mediator(%v), error: %v", add.Str(), err.Error()) - delete(mp.mediators, add) + if mp.productionEnabled { + if mp.dag.HeadUnitNum() == 0 { + mp.newChainBanner() + } } + + // 调度生产unit + go mp.scheduleProductionLoop() } } @@ -318,7 +308,7 @@ func RegisterMediatorPluginService(stack *node.Node, cfg *Config) { } } -func NewMediatorPlugin(ptn PalletOne, dag iDag, cfg *Config) (*MediatorPlugin, error) { +func NewMediatorPlugin(ctx *node.ServiceContext, cfg *Config, ptn PalletOne, dag iDag) (*MediatorPlugin, error) { log.Debugf("mediator plugin initialize begin") if ptn == nil || dag == nil || cfg == nil { @@ -327,22 +317,6 @@ func NewMediatorPlugin(ptn PalletOne, dag iDag, cfg *Config) (*MediatorPlugin, e panic(err) } - mss := cfg.Mediators - msm := make(map[common.Address]*MediatorAccount, len(mss)) - - for _, medConf := range mss { - medAcc := medConf.configToAccount() - if medAcc == nil { - continue - } - - addr := medAcc.Address - log.Debugf("this node control mediator account address: %v", addr.Str()) - - msm[addr] = medAcc - } - log.Debugf("This node controls %v mediators.", len(msm)) - mp := MediatorPlugin{ ptn: ptn, quit: make(chan struct{}), @@ -356,27 +330,56 @@ func NewMediatorPlugin(ptn PalletOne, dag iDag, cfg *Config) (*MediatorPlugin, e requiredParticipation: cfg.RequiredParticipation * core.PalletOne1Percent, groupSigningEnabled: cfg.EnableGroupSigning, - mediators: msm, - suite: core.Suite, activeDKGs: make(map[common.Address]*dkg.DistKeyGenerator), precedingDKGs: make(map[common.Address]*dkg.DistKeyGenerator), } + mp.initLocalConfigMediator(cfg.Mediators, ctx.AccountManager) + if mp.groupSigningEnabled { - mp.newActiveMediatorsDKG() - mp.initTBLSBuf() + //mp.newActiveMediatorsDKG() + mp.initGroupSignBuf() } log.Debugf("mediator plugin initialize end") return &mp, nil } +func (mp *MediatorPlugin) initLocalConfigMediator(mcs []*MediatorConf, am *accounts.Manager) { + mas := make(map[common.Address]*MediatorAccount, len(mcs)) + ks := am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) + + for _, medConf := range mcs { + medAcc := medConf.configToAccount() + if medAcc == nil { + continue + } + + addr := medAcc.Address + // 解锁本地配置的mediator账户 + err := ks.Unlock(accounts.Account{Address: addr}, medAcc.Password) + if err != nil { + log.Debugf("fail to unlock the mediator(%v), error: %v", medConf.Address, err.Error()) + continue + } + + log.Debugf("this node control mediator account address: %v", medConf.Address) + mas[addr] = medAcc + } + + log.Debugf("This node controls %v mediators.", len(mas)) + mp.mediators = mas +} + // initTBLSBuf, 初始化与TBLS签名相关的buf -func (mp *MediatorPlugin) initTBLSBuf() { - lmc := len(mp.mediators) +func (mp *MediatorPlugin) initGroupSignBuf() { + lamc := len(mp.mediators) + + mp.dealBuf = make(map[common.Address]chan *dkg.Deal, lamc) + mp.respBuf = make(map[common.Address]map[common.Address]chan *dkg.Response, lamc) - mp.toTBLSSignBuf = make(map[common.Address]*sync.Map, lmc) - mp.toTBLSRecoverBuf = make(map[common.Address]map[common.Hash]*sigShareSet, lmc) + mp.toTBLSSignBuf = make(map[common.Address]*sync.Map, lamc) + mp.toTBLSRecoverBuf = make(map[common.Address]map[common.Hash]*sigShareSet, lamc) mp.recoverBufLock = new(sync.RWMutex) } diff --git a/ptn/backend.go b/ptn/backend.go index 8a59d3fcc..c5e68b3e3 100755 --- a/ptn/backend.go +++ b/ptn/backend.go @@ -124,7 +124,7 @@ func New(ctx *node.ServiceContext, config *Config) (*PalletOne, error) { log.Error("PalletOne New", "CreateDB err:", err) return nil, err } - dag, err := dag.NewDag(db,false) + dag, err := dag.NewDag(db, false) if err != nil { log.Error("PalletOne New", "NewDag err:", err) return nil, err @@ -152,7 +152,7 @@ func New(ctx *node.ServiceContext, config *Config) (*PalletOne, error) { //Test for P2P ptn.engine = consensus.New(dag, ptn.txPool) - ptn.mediatorPlugin, err = mp.NewMediatorPlugin(ptn, dag, &config.MediatorPlugin) + ptn.mediatorPlugin, err = mp.NewMediatorPlugin(ctx, &config.MediatorPlugin, ptn, dag) if err != nil { log.Error("Initialize mediator plugin err:", "error", err) return nil, err diff --git a/ptn/vss_groupsign.go b/ptn/vss_tbls.go old mode 100755 new mode 100644 similarity index 100% rename from ptn/vss_groupsign.go rename to ptn/vss_tbls.go From 566b91bab32f8243f3f2b3b34917530b91c831cd Mon Sep 17 00:00:00 2001 From: Devin Date: Tue, 16 Jul 2019 14:55:21 +0800 Subject: [PATCH 38/44] Fix mistake about some contract api to PrivateAPI --- internal/ptnapi/backend.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/ptnapi/backend.go b/internal/ptnapi/backend.go index ff69f5ce4..1116f2319 100755 --- a/internal/ptnapi/backend.go +++ b/internal/ptnapi/backend.go @@ -244,6 +244,11 @@ func GetAPIs(apiBackend Backend) []rpc.API { Version: "1.0", Service: NewPublicContractAPI(apiBackend), Public: true, + }, { + Namespace: "contract", + Version: "1.0", + Service: NewPrivateContractAPI(apiBackend), + Public: false, }, { Namespace: "mediator", Version: "1.0", From 84923e821b55015e4148195314f1ecb4f5df9f29 Mon Sep 17 00:00:00 2001 From: etying Date: Tue, 16 Jul 2019 00:40:56 -0700 Subject: [PATCH 39/44] modify light bdd value --- bdd/light/testcases/bddstart.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bdd/light/testcases/bddstart.sh b/bdd/light/testcases/bddstart.sh index 777593a9b..4ba485993 100755 --- a/bdd/light/testcases/bddstart.sh +++ b/bdd/light/testcases/bddstart.sh @@ -36,7 +36,7 @@ sleep 5 #ptn.syncUTXOByAddr("P19wzjSAfVKRY84pPQMsqJSxeVK7oTYEiXt") in light node5 syncutxocommand=`./gptn --exec "ptn.syncUTXOByAddr($account5)" attach node_test5/palletone/gptn5.ipc` syncutxoinfo=`echo $syncutxocommand` -value="\"OK\"" +value="\"ok\"" echo $syncutxoinfo if [ $syncutxoinfo = $value ];then echo "============syncUTXOByAddr account5 ok============" From 0ee23217af8207a93ea3ec435198bbc07efa31ba Mon Sep 17 00:00:00 2001 From: lk Date: Tue, 16 Jul 2019 15:58:52 +0800 Subject: [PATCH 40/44] Add application bdd --- .travis.yml | 41 +++++++++++++- .../ProofOfExistence/proofOfExistence.robot | 43 +++++++++++++++ bdd/application/init.sh | 36 +++++++++++++ bdd/application/pubFuncs.robot | 53 +++++++++++++++++++ bdd/application/pubVariables.robot | 22 ++++++++ bdd/application/setups.robot | 23 ++++++++ 6 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 bdd/application/ProofOfExistence/proofOfExistence.robot create mode 100644 bdd/application/init.sh create mode 100644 bdd/application/pubFuncs.robot create mode 100644 bdd/application/pubVariables.robot create mode 100644 bdd/application/setups.robot diff --git a/.travis.yml b/.travis.yml index 6e325d834..33c8c6273 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,7 @@ env: - DEPOSIT_DIR=deposit - GAS_TOKEN_DIR=gasToken - MEDIATOR_VOTE_DIR=meidatorvote + - APPLICATION_DIR=application - LOG_NAME=log.html - REPORT_NAME=report.html ########## control testcase ############## @@ -30,6 +31,7 @@ env: - IS_RUN_VOTE=true - IS_RUN_GASTOKEN=true - IS_RUN_MEDIATOR_VOTE=true + - IS_RUN_APPLICATION=true - GO111MODULE=on - IS_UPLOAD=true # - 'SFTP_KEY=[base64-encoded-rsa-key]' @@ -241,13 +243,50 @@ matrix: - sudo -H apt-get install expect - sudo -H apt-get install lftp - chmod +x bdd/upload2Ftp.sh + - os: linux + dist: xenial + go: 1.12.5 + env: application_bdd + script: + - go build ./cmd/gptn + - mkdir bdd/application/node + - cp gptn bdd/application/node + - if [ $IS_RUN_APPLICATION == 'true' ]; then + cd ./bdd/application; + chmod +x ./init.sh; + ./init.sh; + sleep 15; + python -m robot.run -d ${BDD_LOG_PATH}/${APPLICATION_DIR} .; + fi + after_script: + - killall gptn + - sleep 2 + - cd ${BASE_DIR} + - zip -j ./bdd/logs/application_log.zip ./bdd/application/node/log/* + - | + if [ $IS_UPLOAD == 'true' ]; then + # uplaod all log + ./bdd/upload2Ftp.sh ${FTP_PWD} ${TRAVIS_BRANCH}; + echo "The path of all bdd log in vsftpd is 'ftp://47.74.209.46" + fi + install: + - sudo -H pip install --upgrade pip + - sudo -H pip install robotframework==2.8.5 + - sudo -H pip install requests + - sudo -H pip install robotframework-requests + - sudo -H pip install demjson + - sudo -H pip install pexpect + - sudo -H apt-get install expect + - sudo -H apt-get install lftp + - chmod +x bdd/upload2Ftp.sh before_install: - go get -u github.com/palletone/adaptor - go get -u github.com/palletone/btc-adaptor - go get -u github.com/palletone/eth-adaptor - source ./build/goget_by_version.sh #- source ./gomockgen.sh - + + addons: apt: update: true diff --git a/bdd/application/ProofOfExistence/proofOfExistence.robot b/bdd/application/ProofOfExistence/proofOfExistence.robot new file mode 100644 index 000000000..122517b34 --- /dev/null +++ b/bdd/application/ProofOfExistence/proofOfExistence.robot @@ -0,0 +1,43 @@ +*** Settings *** +Test Setup beforeVote +Library Collections +Resource ../pubVariables.robot +Resource ../pubFuncs.robot +Resource ../setups.robot + +*** Test Cases *** +mediatorvote + Given user unlock its account succeed + When create proof existence + and wait transaction packaged + Then check proof existence + +*** Keywords *** +user unlock its account succeed + ${respJson}= unlockAccount ${userAccount} + log ${respJson} + Dictionary Should Contain Key ${respJson} result + Should Be Equal ${respJson["result"]} ${true} + +create proof existence + Log create proof existence + ${args}= Create List + ${params}= Create List ${userAccount} ${maindata} ${extradata} ${reference} ${fee} + ${resp}= sendRpcPost ${createProofExistence} ${params} create proof existence + ${res} set variable ${resp["result"]} + log ${res} INFO + +wait transaction packaged + Log wait for transaction being packaged + Sleep 15 + +check proof existence + Log check proof existence + ${args}= Create List + ${params}= Create List ${reference} + ${resp}= sendRpcPost ${checkProofExistence} ${params} check proof existence + ${res}= Get From Dictionary ${resp} result + ${refs}= Get From List ${res} 0 + ${ref} set variable ${refs["reference"]} + Should Be Equal ${ref} ${reference} + log ${ref} INFO diff --git a/bdd/application/init.sh b/bdd/application/init.sh new file mode 100644 index 000000000..e48389881 --- /dev/null +++ b/bdd/application/init.sh @@ -0,0 +1,36 @@ +#!/bin/bash +#pkill gptn +#tskill gptn +#cd ../../cmd/gptn && go build +cd ../../ +#rm -rf ./bdd/application/node* +#cp ./cmd/gptn/gptn ./bdd/application/node +cd ./bdd/application/node +chmod +x gptn + +# new genesis +./gptn newgenesis "" fasle << EOF +y +1 +1 +EOF + +# edit toml file +tomlFile="ptn-config.toml" +if [ -e "$tomlFile" ]; then + #file already exist, modify + sed -i "s/HTTPPort = 8545/HTTPPort = 8600/g" $tomlFile + +else + #file not found, new file + echo "no $tomlFile" + exit -1 +fi + +# gptn init +./gptn init << EOF +1 +EOF + +# start gptn +nohup ./gptn & \ No newline at end of file diff --git a/bdd/application/pubFuncs.robot b/bdd/application/pubFuncs.robot new file mode 100644 index 000000000..885a292e5 --- /dev/null +++ b/bdd/application/pubFuncs.robot @@ -0,0 +1,53 @@ +*** Settings *** +Resource pubVariables.robot + +*** Keywords *** +newAccount + ${params}= Create List 1 + ${respJson}= sendRpcPost personal_newAccount ${params} newAccount + Dictionary Should Contain Key ${respJson} result + [Return] ${respJson["result"]} + +transferPTN + [Arguments] ${to} + ${params}= Create List ${tokenHolder} ${to} ${amount} ${fee} ${null} + ... ${pwd} + ${respJson}= sendRpcPost ${transerferPTNMethod} ${params} transferPTN + Dictionary Should Contain Key ${respJson} result + +getBalance + [Arguments] ${addr} + ${params}= Create List ${addr} + ${respJson}= sendRpcPost ${getBalanceMethod} ${params} getBalance + Dictionary Should Contain Key ${respJson} result + Dictionary Should Contain Key ${respJson["result"]} PTN + [Return] ${respJson["result"]["PTN"]} + +unlockAccount + [Arguments] ${addr} + ${params}= Create List ${addr} ${pwd} ${600000000} + ${respJson}= sendRpcPost ${unlockAccountMethod} ${params} unlockAccount + [Return] ${respJson} + +sendRpcPost + [Arguments] ${method} ${params} ${alias} + ${header}= Create Dictionary Content-Type application/json + ${data} Create Dictionary jsonrpc=2.0 method=${method} params=${params} id=1 + Create Session ${alias} http://127.0.0.1:8600 + ${resp} Post Request ${alias} http://127.0.0.1:8600 data=${data} headers=${header} + ${respJson} To Json ${resp.content} + [Return] ${respJson} + +queryTokenHolder + ${args}= Create List + ${params}= Create List + ${respJson}= sendRpcPost ${personalListAccountsMethod} ${params} queryTokenHolder + Dictionary Should Contain Key ${respJson} result + ${accounts}= Get From Dictionary ${respJson} result + ${firstAddr}= Get From List ${accounts} 0 + Set Global Variable ${tokenHolder} ${firstAddr} + log ${tokenHolder} + +wait for transaction being packaged + Log wait for transaction being packaged + Sleep 6 diff --git a/bdd/application/pubVariables.robot b/bdd/application/pubVariables.robot new file mode 100644 index 000000000..cbb2cd339 --- /dev/null +++ b/bdd/application/pubVariables.robot @@ -0,0 +1,22 @@ +*** Settings *** +Library RequestsLibrary + +*** Variables *** +${host} http://localhost:8600/ +# methods +${transerferPTNMethod} wallet_transferPtn +${getBalanceMethod} wallet_getBalance +${personalListAccountsMethod} personal_listAccounts +${unlockAccountMethod} personal_unlockAccount +${createProofExistence} wallet_createProofOfExistenceTx +${checkProofExistence} wallet_getProofOfExistencesByRef +# common variables +${userAccount} ${null} +${tokenHolder} ${null} +${maindata} maindata +${extradata} extradata +${reference} A +${amount} 10000 +${fee} 1 +${pwd} 1 +${duration} 600000000 diff --git a/bdd/application/setups.robot b/bdd/application/setups.robot new file mode 100644 index 000000000..44c072f24 --- /dev/null +++ b/bdd/application/setups.robot @@ -0,0 +1,23 @@ +*** Settings *** +Resource pubVariables.robot +Resource pubFuncs.robot +Library Collections + +*** Keywords *** +beforeVote + queryTokenHolder + newAccounts + transferPTNToUser + +newAccounts + # create a user for the poll + ${user1}= newAccount + Set Global Variable ${userAccount} ${user1} + +transferPTNToUser + # transfer PTN to user for the poll + transferPTN ${userAccount} + Log wait for tx being packaged into unit + Sleep 5 # should sleep, because transaction has not been packaged into unit + ${balance}= getBalance ${userAccount} + Should Be Equal ${balance} ${amount} From bc67cec29880436e13aa82166ccbeb114be769e5 Mon Sep 17 00:00:00 2001 From: etying Date: Tue, 16 Jul 2019 02:08:57 -0700 Subject: [PATCH 41/44] modify UT fetcherTester insertChain --- ptn/fetcher/fetcher_test.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/ptn/fetcher/fetcher_test.go b/ptn/fetcher/fetcher_test.go index 5e75c6a0f..e85c29069 100755 --- a/ptn/fetcher/fetcher_test.go +++ b/ptn/fetcher/fetcher_test.go @@ -17,7 +17,6 @@ package fetcher import ( - "errors" "fmt" "github.com/palletone/go-palletone/common" "github.com/palletone/go-palletone/common/ptndb" @@ -246,12 +245,12 @@ func (f *fetcherTester) chainHeight(assetId modules.AssetId) uint64 { func (f *fetcherTester) insertChain(units modules.Units) (int, error) { f.lock.Lock() defer f.lock.Unlock() - fmt.Println(len(units)) + //fmt.Println(len(units)) for i, unit := range units { // Make sure the parent in known - if _, ok := f.blocks[unit.ParentHash()[0]]; !ok { - return i, errors.New("unknown parent") - } + //if _, ok := f.blocks[unit.ParentHash()[0]]; !ok { + // return i, errors.New("unknown parent") + //} // Discard any new blocks if the same height already exists if unit.NumberU64() <= f.blocks[f.hashes[len(f.hashes)-1]].NumberU64() { return i, nil @@ -372,7 +371,7 @@ func verifyImportCount(t *testing.T, imported chan *modules.Unit, count int) { for i := 0; i < count; i++ { select { case <-imported: - case <-time.After(time.Second): + case <-time.After(3 * time.Second): t.Fatalf("block %d: import timeout", i+1) } } @@ -406,7 +405,7 @@ func testSequentialAnnouncements(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - i - 1), + Index: uint64(len(hashes) - i - 1), } tester.fetcher.Notify("valid", hashes[i], chain, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) verifyImportEvent(t, imported, true) @@ -443,7 +442,7 @@ func testConcurrentAnnouncements(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - i - 1), + Index: uint64(len(hashes) - i - 1), } tester.fetcher.Notify("first", hashes[i], chain, time.Now().Add(-arriveTimeout), firstHeaderWrapper, firstBodyFetcher) tester.fetcher.Notify("second", hashes[i], chain, time.Now().Add(-arriveTimeout+time.Millisecond), secondHeaderWrapper, secondBodyFetcher) @@ -478,7 +477,7 @@ func testRandomArrivalImport(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - i - 1), + Index: uint64(len(hashes) - i - 1), } tester.fetcher.Notify("valid", hashes[i], chain, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) time.Sleep(time.Millisecond) @@ -488,7 +487,7 @@ func testRandomArrivalImport(t *testing.T, protocol int) { chainskip := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - skip - 1), + Index: uint64(len(hashes) - skip - 1), } tester.fetcher.Notify("valid", hashes[skip], chainskip, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) verifyImportCount(t, imported, len(hashes)-1) @@ -516,7 +515,7 @@ func testQueueGapFill(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - i - 1), + Index: uint64(len(hashes) - i - 1), } tester.fetcher.Notify("valid", hashes[i], chain, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) time.Sleep(time.Millisecond) @@ -554,7 +553,7 @@ func testImportDeduplication(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: 1, + Index: 1, } tester.fetcher.Notify("valid", hashes[0], chain, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) <-fetching @@ -598,7 +597,7 @@ func testEmptyBlockShortCircuit(t *testing.T, protocol int) { chain := &modules.ChainIndex{ AssetID: modules.PTNCOIN, //IsMain: true, - Index: uint64(len(hashes) - i - 1), + Index: uint64(len(hashes) - i - 1), } tester.fetcher.Notify("valid", hashes[i], chain, time.Now().Add(-arriveTimeout), headerFetcher, bodyFetcher) From 7b8c058126a9bb3f2a8d7cf068d350e7139dd7bb Mon Sep 17 00:00:00 2001 From: zhichunqi <1558763837@qq.com> Date: Tue, 16 Jul 2019 18:34:43 +0800 Subject: [PATCH 42/44] Fix bug when container exited --- contracts/core/chaincode_support.go | 43 ++++------------ contracts/core/handler.go | 10 +++- contracts/manger/ccapi.go | 6 +-- .../uccresources.go => utils/utils.go} | 49 ++++++++++++++++++- 4 files changed, 70 insertions(+), 38 deletions(-) rename contracts/{manger/uccresources.go => utils/utils.go} (77%) diff --git a/contracts/core/chaincode_support.go b/contracts/core/chaincode_support.go index b93b7cf5e..98cfd473c 100755 --- a/contracts/core/chaincode_support.go +++ b/contracts/core/chaincode_support.go @@ -32,19 +32,17 @@ import ( "github.com/golang/protobuf/proto" - "bytes" - "github.com/fsouza/go-dockerclient" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/contracts/accesscontrol" cfg "github.com/palletone/go-palletone/contracts/contractcfg" "github.com/palletone/go-palletone/contracts/platforms" "github.com/palletone/go-palletone/contracts/shim" + "github.com/palletone/go-palletone/contracts/utils" "github.com/palletone/go-palletone/core/vmContractPub/ccprovider" pb "github.com/palletone/go-palletone/core/vmContractPub/protos/peer" "github.com/palletone/go-palletone/dag/rwset" "github.com/palletone/go-palletone/vm/api" "github.com/palletone/go-palletone/vm/ccintf" - "github.com/palletone/go-palletone/vm/common" "github.com/palletone/go-palletone/vm/controller" "github.com/pkg/errors" "github.com/spf13/viper" @@ -877,43 +875,22 @@ func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, cccid *c var ccresp *pb.ChaincodeMessage select { case ccresp = <-notfy: + log.Infof("notfy = %v", ccresp) //response is sent to user or calling chaincode. ChaincodeMessage_ERROR //are typically treated as error //log.Errorf("{{{{{ time out [%d]", setTimeout) case <-time.After(setTimeout): + log.Debugf("time out when execute,time = %v", setTimeout) //err = errors.New("timeout expired while executing transaction") //log.Info("====================================timeout expired while executing transaction") - var client *docker.Client - client, err = util.NewDockerClient() - if err != nil { - log.Error("util.NewDockerClient", "error", err) - err = errors.New("timeout expired while executing transaction") - } - var buf bytes.Buffer - logsO := docker.LogsOptions{ - Container: cccid.GetContainerName(), - ErrorStream: &buf, - Follow: true, - Stdout: true, - Stderr: true, - Tail: "30", - } - err = client.Logs(logsO) - if err != nil { - //log.Info("===================4=================timeout expired while executing transaction") - log.Error("client.Logs", "error", err) - err = errors.New("timeout expired while executing transaction") + containerErrStr := utils.GetLogFromContainer(cccid.GetContainerName()) + if containerErrStr != "" { + log.Error("error from container %s", containerErrStr) + err = errors.New(containerErrStr) } else { - //log.Info("==============1======================timeout expired while executing transaction") - line, _ := buf.ReadString('\n') - line = strings.TrimSpace(line) - if strings.Contains(line, "panic: runtime error") || strings.Contains(line, "fatal error: runtime") { - err = errors.New(line) - } else { - //log.Info("===================2=================timeout expired while executing transaction") - log.Errorf("<<%s,---->%s", name, hex.EncodeToString(contractAddr.Bytes21())) - _, err = StartChaincodeContainert(dag, "palletone", contractAddr.Bytes21(), txid.String()) + _, err = RestartContainer(dag, "palletone", contractAddr.Bytes21(), txid.String()) if err != nil { - log.Infof("startChaincodeContainert err: %s", err.Error()) + log.Infof("RestartContainer err: %s", err.Error()) return } } @@ -365,7 +365,7 @@ func GetAllContainers(client *docker.Client) { } } -func StartChaincodeContainert(idag dag.IDag, chainID string, deployId []byte, txId string) ([]byte, error) { +func RestartContainer(idag dag.IDag, chainID string, deployId []byte, txId string) ([]byte, error) { _, err := Stop(nil, idag, deployId, chainID, deployId, txId, false, true) if err != nil { return nil, err diff --git a/contracts/manger/uccresources.go b/contracts/utils/utils.go similarity index 77% rename from contracts/manger/uccresources.go rename to contracts/utils/utils.go index c41dcd273..c46bea75d 100755 --- a/contracts/manger/uccresources.go +++ b/contracts/utils/utils.go @@ -1,13 +1,16 @@ -package manger +package utils import ( + "bytes" "fmt" "github.com/fsouza/go-dockerclient" "github.com/palletone/go-palletone/common/log" "github.com/palletone/go-palletone/contracts/contractcfg" "github.com/palletone/go-palletone/contracts/list" "github.com/palletone/go-palletone/vm/common" + "io" "strings" + "time" ) type UccInterface interface { @@ -111,3 +114,47 @@ func getResourceUses(cc *list.CCInfo) (*docker.Stats, error) { } return nil, fmt.Errorf("get container stats error") } + +// 通过容器名称获取容器里面的错误信息,返回最后一条 +func GetLogFromContainer(name string) string { + var client *docker.Client + client, err := util.NewDockerClient() + if err != nil { + log.Info("util.NewDockerClient", "error", err) + return "" + } + var buf bytes.Buffer + logsO := docker.LogsOptions{ + Container: name, + ErrorStream: &buf, + Follow: true, + Stderr: true, + InactivityTimeout: time.Duration(5 * time.Second), + } + log.Debugf("start docker logs") + err = client.Logs(logsO) + log.Debugf("end docker logs") + if err != nil { + log.Infof("get log from container %s error: %s", name, err.Error()) + return "" + } + errArray := make([]string, 0) + for { + line, err := buf.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + return "" + } + line = strings.TrimSpace(line) + if strings.Contains(line, "panic: runtime error") || strings.Contains(line, "fatal error: runtime") { + log.Infof("container %s error %s", name, line) + errArray = append(errArray, line) + } + } + if len(errArray) != 0 { + return errArray[len(errArray)-1] + } + return "" +} From 93fe23455b24bd6ec7a789fae3125b6cf2e7ef3e Mon Sep 17 00:00:00 2001 From: etying Date: Tue, 16 Jul 2019 18:54:31 -0700 Subject: [PATCH 43/44] delete debug console command --- internal/web3ext/debugjs.go | 4 +++- internal/web3ext/web3ext.go | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/web3ext/debugjs.go b/internal/web3ext/debugjs.go index f82e42fef..66cdec61a 100644 --- a/internal/web3ext/debugjs.go +++ b/internal/web3ext/debugjs.go @@ -20,6 +20,7 @@ package web3ext +/* func init() { Modules["debug"] = Debug_JS } @@ -32,7 +33,7 @@ web3._extend({ name: 'ccinvoke', call: 'debug_ccinvoke', params: 4 - }), + }), new web3._extend.Method({ name: 'printBlock', call: 'debug_printBlock', @@ -262,3 +263,4 @@ web3._extend({ properties: [] }); ` +*/ diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index c6180c480..f11812a8c 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -21,11 +21,11 @@ package web3ext var Modules = map[string]string{ - "chequebook": Chequebook_JS, - "clique": Clique_JS, - "net": Net_JS, - "rpc": RPC_JS, - "txpool": TxPool_JS, + //"chequebook": Chequebook_JS, + //"clique": Clique_JS, + //"net": Net_JS, + //"rpc": RPC_JS, + "txpool": TxPool_JS, } const Chequebook_JS = ` From 75a62882d7beffacc6801845f758e1edf8626bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E7=AB=8B=E5=8D=8E?= Date: Wed, 17 Jul 2019 10:30:58 +0800 Subject: [PATCH 44/44] add deploy request tx extend data --- consensus/jury/config.go | 1 + consensus/jury/contractReq.go | 8 +- dag/modules/message.go | 1 + internal/ptnapi/backend.go | 2 +- internal/ptnapi/contract_api.go | 126 +++++++++++++------------------- internal/web3ext/contractjs.go | 4 +- light/api_backend.go | 6 +- ptn/api_backend.go | 30 +++----- ptnjson/txjson.go | 14 ++-- 9 files changed, 82 insertions(+), 110 deletions(-) diff --git a/consensus/jury/config.go b/consensus/jury/config.go index 104db7ff6..22ac14489 100755 --- a/consensus/jury/config.go +++ b/consensus/jury/config.go @@ -36,6 +36,7 @@ const ( MaxNumberTplEleAddrHash = 5 //合约模板指定节点地址hash数量 MaxLengthTplId = 128 //合约模板Id长度 MaxNumberArgs = 32 //合约请求参数数量 + MaxLengthExtData = 16 //合约请求扩展数据长度 ) var ( diff --git a/consensus/jury/contractReq.go b/consensus/jury/contractReq.go index 1faf4e27f..1f1fbbbed 100755 --- a/consensus/jury/contractReq.go +++ b/consensus/jury/contractReq.go @@ -100,13 +100,13 @@ func (p *Processor) ContractInstallReq(from, to common.Address, daoAmount, daoFe return reqId, nil, nil } -func (p *Processor) ContractDeployReq(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, timeout time.Duration) (common.Hash, common.Address, error) { +func (p *Processor) ContractDeployReq(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, extData []byte, timeout time.Duration) (common.Hash, common.Address, error) { if from == (common.Address{}) || to == (common.Address{}) || templateId == nil { log.Error("ContractDeployReq", "param is error") return common.Hash{}, common.Address{}, errors.New("ContractDeployReq request param is error") } - if len(templateId) > MaxLengthTplId || len(args) > MaxNumberArgs { - log.Error("ContractDeployReq", "len(templateId)", len(templateId), "len(args)", len(args)) + if len(templateId) > MaxLengthTplId || len(args) > MaxNumberArgs || len(extData) > MaxLengthExtData { + log.Error("ContractDeployReq", "len(templateId)", len(templateId), "len(args)", len(args), "len(extData)", len(extData)) return common.Hash{}, common.Address{}, errors.New("ContractDeployReq request param len overflow") } msgReq := &modules.Message{ @@ -114,6 +114,7 @@ func (p *Processor) ContractDeployReq(from, to common.Address, daoAmount, daoFee Payload: &modules.ContractDeployRequestPayload{ TplId: templateId, Args: args, + ExtData: extData, Timeout: uint32(timeout), }, } @@ -238,4 +239,3 @@ func (p *Processor) UpdateJuryAccount(addr common.Address, pwd string) bool { return true } - diff --git a/dag/modules/message.go b/dag/modules/message.go index dc4cd9a30..5c7c0ac7e 100755 --- a/dag/modules/message.go +++ b/dag/modules/message.go @@ -402,6 +402,7 @@ type ContractInstallRequestPayload struct { type ContractDeployRequestPayload struct { TplId []byte `json:"tpl_name"` Args [][]byte `json:"args"` + ExtData []byte `json:"extend_data"` Timeout uint32 `json:"timeout"` } diff --git a/internal/ptnapi/backend.go b/internal/ptnapi/backend.go index 1116f2319..f1b131ed5 100755 --- a/internal/ptnapi/backend.go +++ b/internal/ptnapi/backend.go @@ -140,7 +140,7 @@ type Backend interface { EncodeTx(jsonStr string) (string, error) ContractInstallReqTx(from, to common.Address, daoAmount, daoFee uint64, tplName, path, version string, description, abi, language string, addrs []common.Address) (reqId common.Hash, tplId []byte, err error) - ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, timeout time.Duration) (reqId common.Hash, contractAddr common.Address, err error) + ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, extData []byte,timeout time.Duration) (reqId common.Hash, contractAddr common.Address, err error) ContractInvokeReqTx(from, to common.Address, daoAmount, daoFee uint64, certID *big.Int, contractAddress common.Address, args [][]byte, timeout uint32) (reqId common.Hash, err error) SendContractInvokeReqTx(requestTx *modules.Transaction) (reqId common.Hash, err error) ContractInvokeReqTokenTx(from, to, toToken common.Address, daoAmount, daoFee, daoAmountToken uint64, asset string, contractAddress common.Address, args [][]byte, timeout uint32) (reqId common.Hash, err error) diff --git a/internal/ptnapi/contract_api.go b/internal/ptnapi/contract_api.go index 265304ba7..d3ce7edb8 100755 --- a/internal/ptnapi/contract_api.go +++ b/internal/ptnapi/contract_api.go @@ -60,11 +60,13 @@ func NewPublicContractAPI(b Backend) *PublicContractAPI { } type PrivateContractAPI struct { - b Backend + b Backend } + func NewPrivateContractAPI(b Backend) *PrivateContractAPI { - return &PrivateContractAPI{b} + return &PrivateContractAPI{b} } + //contract command //install func (s *PublicContractAPI) Ccinstall(ctx context.Context, ccname, ccpath, ccversion, ccdescription, ccabi, cclanguage string) (hexutil.Bytes, error) { @@ -155,19 +157,12 @@ func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount amount, _ := strconv.ParseUint(daoAmount, 10, 64) fee, _ := strconv.ParseUint(daoFee, 10, 64) - //templateName, _ := hex.DecodeString(tplName) - - log.Debug("-----Ccinstalltx:", "fromAddr", fromAddr.String()) - log.Debug("-----Ccinstalltx:", "toAddr", toAddr.String()) - log.Debug("-----Ccinstalltx:", "amount", amount) - log.Debug("-----Ccinstalltx:", "fee", fee) - log.Debug("-----Ccinstalltx:", "tplName", tplName) - log.Debug("-----Ccinstalltx:", "path", path) - log.Debug("-----Ccinstalltx:", "version", version) - log.Debug("-----Ccinstalltx:", "description", ccdescription) - log.Debug("-----Ccinstalltx:", "abi", ccabi) - log.Debug("-----Ccinstalltx:", "language", cclanguage) - + log.Info("Ccinstalltx info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" tplName[%s], path[%s],version[%s]", tplName, path, version) + log.Infof(" description[%s], abi[%s],language[%s]", ccdescription, ccabi, cclanguage) + log.Infof(" addrs len[%d]", len(addr)) if strings.ToLower(cclanguage) == "go" { cclanguage = "golang" } @@ -175,25 +170,18 @@ func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount if _, ok := peer.ChaincodeSpec_Type_value[language]; !ok { return nil, errors.New(cclanguage + " language is not supported") } - /* - "P1QFTh1Xq2JpfTbu9bfaMfWh2sR1nHrMV8z", "P1NHVBFRkooh8HD9SvtvU3bpbeVmuGKPPuF", - "P1PpgjUC7Nkxgi5KdKCGx2tMu6F5wfPGrVX", "P1MBXJypFCsQpafDGi9ivEooR8QiYmxq4qw" - */ - //addr := []string{"P1QFTh1Xq2JpfTbu9bfaMfWh2sR1nHrMV8z", "P1NHVBFRkooh8HD9SvtvU3bpbeVmuGKPPuF", - // "P1PpgjUC7Nkxgi5KdKCGx2tMu6F5wfPGrVX", "P1MBXJypFCsQpafDGi9ivEooR8QiYmxq4qw"} - //var addr []string addrs := make([]common.Address, 0) - for _, s := range addr { + for i, s := range addr { a, _ := common.StringToAddress(s) addrs = append(addrs, a) + log.Infof(" index[%d],addr[%s]", i, s) } - log.Debug("-----Ccinstalltx:", "addrHash", addrs, "len", len(addrs)) reqId, tplId, err := s.b.ContractInstallReqTx(fromAddr, toAddr, amount, fee, tplName, path, version, ccdescription, ccabi, language, addrs) sReqId := hex.EncodeToString(reqId[:]) sTplId := hex.EncodeToString(tplId) - log.Debug("-----Ccinstalltx:", "reqId", sReqId, "tplId", sTplId) + log.Info("Ccinstalltx:", "reqId", sReqId, "tplId", sTplId) rsp := &ContractInstallRsp{ ReqId: sReqId, @@ -202,18 +190,18 @@ func (s *PublicContractAPI) Ccinstalltx(ctx context.Context, from, to, daoAmount return rsp, err } -func (s *PublicContractAPI) Ccdeploytx(ctx context.Context, from, to, daoAmount, daoFee, tplId string, param []string) (*ContractDeployRsp, error) { +func (s *PublicContractAPI) Ccdeploytx(ctx context.Context, from, to, daoAmount, daoFee, tplId string, param []string, extData string) (*ContractDeployRsp, error) { fromAddr, _ := common.StringToAddress(from) toAddr, _ := common.StringToAddress(to) amount, _ := strconv.ParseUint(daoAmount, 10, 64) fee, _ := strconv.ParseUint(daoFee, 10, 64) templateId, _ := hex.DecodeString(tplId) + extendData, _ := hex.DecodeString(extData) - log.Debug("-----Ccdeploytx:", "fromAddr", fromAddr.String()) - log.Debug("-----Ccdeploytx:", "toAddr", toAddr.String()) - log.Debug("-----Ccdeploytx:", "amount", amount) - log.Debug("-----Ccdeploytx:", "fee", fee) - log.Debug("-----Ccdeploytx:", "tplId", templateId) + log.Info("Ccdeploytx info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" templateId[%s], extData[%s]", tplId, extData) args := make([][]byte, len(param)) for i, arg := range param { @@ -222,7 +210,7 @@ func (s *PublicContractAPI) Ccdeploytx(ctx context.Context, from, to, daoAmount, } fullArgs := [][]byte{defaultMsg0} fullArgs = append(fullArgs, args...) - reqId, _, err := s.b.ContractDeployReqTx(fromAddr, toAddr, amount, fee, templateId, fullArgs, 0) + reqId, _, err := s.b.ContractDeployReqTx(fromAddr, toAddr, amount, fee, templateId, fullArgs, extendData, 0) contractAddr := crypto.RequestIdToContractAddress(reqId) sReqId := hex.EncodeToString(reqId[:]) log.Debug("-----Ccdeploytx:", "reqId", sReqId, "depId", contractAddr.String()) @@ -242,28 +230,28 @@ func (s *PublicContractAPI) Ccinvoketx(ctx context.Context, from, to, daoAmount, fee, _ := strconv.ParseUint(daoFee, 10, 64) timeout64, _ := strconv.ParseUint(timeout, 10, 64) - log.Debug("-----Ccinvoketx:", "contractId", contractAddr.String()) - log.Debug("-----Ccinvoketx:", "fromAddr", fromAddr.String()) - log.Debug("-----Ccinvoketx:", "toAddr", toAddr.String()) - log.Debug("-----Ccinvoketx:", "daoAmount", daoAmount) - log.Debug("-----Ccinvoketx:", "amount", amount) - log.Debug("-----Ccinvoketx:", "fee", fee) - log.Debug("-----Ccinvoketx:", "param len", len(param)) - log.Debug("-----Ccinvoketx:", "timeout64", timeout64) + log.Info("Ccinvoketx info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" contractId[%s], certID[%s], timeout[%s]", contractAddr.String(), certID, timeout) + intCertID := new(big.Int) if len(certID) > 0 { if _, ok := intCertID.SetString(certID, 10); !ok { return &ContractDeployRsp{}, fmt.Errorf("certid is invalid") } - log.Debug("-----Ccinvoketx:", "certificate serial number", certID) + //log.Debug("Ccinvoketx:", "certificate serial number", certID) } + + log.Infof(" param len[%d]", len(param)) args := make([][]byte, len(param)) for i, arg := range param { args[i] = []byte(arg) - fmt.Printf("index[%d], value[%s]\n", i, arg) + log.Infof(" index[%d], value[%s]\n", i, arg) } reqId, err := s.b.ContractInvokeReqTx(fromAddr, toAddr, amount, fee, intCertID, contractAddr, args, uint32(timeout64)) - log.Debug("-----ContractInvokeTxReq:" + hex.EncodeToString(reqId[:])) + //log.Debug("-----ContractInvokeTxReq:" + hex.EncodeToString(reqId[:])) + log.Infof(" reqId[%s]", hex.EncodeToString(reqId[:])) rsp1 := &ContractDeployRsp{ ReqId: hex.EncodeToString(reqId[:]), ContractId: deployId, @@ -273,7 +261,6 @@ func (s *PublicContractAPI) Ccinvoketx(ctx context.Context, from, to, daoAmount, func (s *PublicContractAPI) CcinvokeToken(ctx context.Context, from, to, toToken, daoAmount, daoFee, assetToken, amountToken, deployId string, param []string) (*ContractDeployRsp, error) { contractAddr, _ := common.StringToAddress(deployId) - fromAddr, _ := common.StringToAddress(from) toAddr, _ := common.StringToAddress(to) toAddrToken, _ := common.StringToAddress(toToken) @@ -281,22 +268,20 @@ func (s *PublicContractAPI) CcinvokeToken(ctx context.Context, from, to, toToken fee, _ := strconv.ParseUint(daoFee, 10, 64) amountOfToken, _ := strconv.ParseUint(amountToken, 10, 64) - log.Debug("-----CcinvokeToken:", "contractId", contractAddr.String()) - log.Debug("-----CcinvokeToken:", "fromAddr", fromAddr.String()) - log.Debug("-----CcinvokeToken:", "toAddr", toAddr.String()) - log.Debug("-----CcinvokeToken:", "amount", amount) - log.Debug("-----CcinvokeToken:", "fee", fee) - log.Debug("-----CcinvokeToken:", "toAddrToken", toAddrToken.String()) - log.Debug("-----CcinvokeToken:", "amountVote", amountOfToken) - log.Debug("-----CcinvokeToken:", "param len", len(param)) + log.Info("CcinvokeToken info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" toAddrToken[%s], amountVote[%d]", toAddrToken.String(), amountOfToken) + log.Infof(" contractId[%s]", contractAddr.String()) + log.Infof(" param len[%d]", len(param)) args := make([][]byte, len(param)) for i, arg := range param { args[i] = []byte(arg) - fmt.Printf("index[%d], value[%s]\n", i, arg) + log.Infof(" index[%d], value[%s]\n", i, arg) } reqId, err := s.b.ContractInvokeReqTokenTx(fromAddr, toAddr, toAddrToken, amount, fee, amountOfToken, assetToken, contractAddr, args, 0) - log.Debug("-----ContractInvokeTxReq:" + hex.EncodeToString(reqId[:])) + log.Infof(" reqId[%s]", hex.EncodeToString(reqId[:])) rsp1 := &ContractDeployRsp{ ReqId: hex.EncodeToString(reqId[:]), ContractId: deployId, @@ -306,29 +291,27 @@ func (s *PublicContractAPI) CcinvokeToken(ctx context.Context, from, to, toToken func (s *PrivateContractAPI) CcinvoketxPass(ctx context.Context, from, to, daoAmount, daoFee, deployId string, param []string, password string, duration *uint64, certID string) (string, error) { contractAddr, _ := common.StringToAddress(deployId) - fromAddr, _ := common.StringToAddress(from) toAddr, _ := common.StringToAddress(to) amount, _ := strconv.ParseUint(daoAmount, 10, 64) fee, _ := strconv.ParseUint(daoFee, 10, 64) - log.Debug("-----CcinvoketxPass:", "contractId", contractAddr.String()) - log.Debug("-----CcinvoketxPass:", "fromAddr", fromAddr.String()) - log.Debug("-----CcinvoketxPass:", "toAddr", toAddr.String()) - log.Debug("-----CcinvoketxPass:", "amount", amount) - log.Debug("-----CcinvoketxPass:", "fee", fee) + log.Info("CcinvoketxPass info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" contractId[%s], certID[%s], password[%s]", contractAddr.String(), certID, password) intCertID := new(big.Int) if len(certID) > 0 { if _, ok := intCertID.SetString(certID, 10); !ok { return "", fmt.Errorf("certid is invalid") } - log.Debug("-----CcinvoketxPass:", "certificate serial number", certID) } + log.Infof(" param len[%d]", len(param)) args := make([][]byte, len(param)) for i, arg := range param { args[i] = []byte(arg) - fmt.Printf("index[%d], value[%s]\n", i, arg) + log.Infof(" index[%d], value[%s]\n", i, arg) } //2. @@ -338,7 +321,7 @@ func (s *PrivateContractAPI) CcinvoketxPass(ctx context.Context, from, to, daoAm } reqId, err := s.b.ContractInvokeReqTx(fromAddr, toAddr, amount, fee, intCertID, contractAddr, args, 0) - log.Debug("-----ContractInvokeTxReq:" + hex.EncodeToString(reqId[:])) + log.Infof(" reqId[%s]", hex.EncodeToString(reqId[:])) return hex.EncodeToString(reqId[:]), err } @@ -349,19 +332,14 @@ func (s *PublicContractAPI) Ccstoptx(ctx context.Context, from, to, daoAmount, d amount, _ := strconv.ParseUint(daoAmount, 10, 64) fee, _ := strconv.ParseUint(daoFee, 10, 64) contractAddr, _ := common.StringToAddress(contractId) - //TODO delImg 为 true 时,目前是会删除基础镜像的 - //delImg := true - //if del, _ := strconv.Atoi(deleteImage); del <= 0 { - // delImg = false - //} - log.Debug("-----Ccstoptx:", "fromAddr", fromAddr.String()) - log.Debug("-----Ccstoptx:", "toAddr", toAddr.String()) - log.Debug("-----Ccstoptx:", "amount", amount) - log.Debug("-----Ccstoptx:", "fee", fee) - log.Debug("-----Ccstoptx:", "contractId", contractAddr) + + log.Info("Ccstoptx info:") + log.Infof(" fromAddr[%s], toAddr[%s]", fromAddr.String(), toAddr.String()) + log.Infof(" amount[%d], fee[%d]", amount, fee) + log.Infof(" contractId[%s]", contractAddr.String()) reqId, err := s.b.ContractStopReqTx(fromAddr, toAddr, amount, fee, contractAddr, false) - log.Debug("-----Ccstoptx:" + hex.EncodeToString(reqId[:])) + log.Infof(" reqId[%s]", hex.EncodeToString(reqId[:])) return hex.EncodeToString(reqId[:]), err } diff --git a/internal/web3ext/contractjs.go b/internal/web3ext/contractjs.go index bd1ca0d45..4b6a3c9f4 100755 --- a/internal/web3ext/contractjs.go +++ b/internal/web3ext/contractjs.go @@ -38,8 +38,8 @@ web3._extend({ new web3._extend.Method({ name: 'ccdeploytx', call: 'contract_ccdeploytx', - params: 6, //from, to , daoAmount, daoFee , templateId , args - inputFormatter: [null, null, null,null, null, null] + params: 7, //from, to , daoAmount, daoFee , templateId , args , extData + inputFormatter: [null, null, null,null, null, null, null] }), new web3._extend.Method({ name: 'ccinvoketx', diff --git a/light/api_backend.go b/light/api_backend.go index 2b69da285..abc28d515 100755 --- a/light/api_backend.go +++ b/light/api_backend.go @@ -285,7 +285,7 @@ func (b *LesApiBackend) GetCommonByPrefix(prefix []byte) map[string][]byte { } // Get Contract Api -func (b *LesApiBackend) GetContract(contractAddr common.Address) (*ptnjson.ContractJson, error){ +func (b *LesApiBackend) GetContract(contractAddr common.Address) (*ptnjson.ContractJson, error) { return nil, nil } @@ -416,7 +416,7 @@ func (b *LesApiBackend) GetAddrTxHistory(addr string) ([]*ptnjson.TxHistoryJson, func (b *LesApiBackend) GetAssetTxHistory(asset *modules.Asset) ([]*ptnjson.TxHistoryJson, error) { return nil, nil } -func (b *LesApiBackend) GetAssetExistence(asset string) ([]*ptnjson.ProofOfExistenceJson, error) { +func (b *LesApiBackend) GetAssetExistence(asset string) ([]*ptnjson.ProofOfExistenceJson, error) { return nil, nil } @@ -445,7 +445,7 @@ func (b *LesApiBackend) EncodeTx(jsonStr string) (string, error) { func (b *LesApiBackend) ContractInstallReqTx(from, to common.Address, daoAmount, daoFee uint64, tplName, path, version string, description, abi, language string, addrs []common.Address) (reqId common.Hash, tplId []byte, err error) { return } -func (b *LesApiBackend) ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, timeout time.Duration) (reqId common.Hash, depId common.Address, err error) { +func (b *LesApiBackend) ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, extData []byte, timeout time.Duration) (reqId common.Hash, depId common.Address, err error) { return } func (b *LesApiBackend) ContractInvokeReqTx(from, to common.Address, daoAmount, daoFee uint64, certID *big.Int, contractAddress common.Address, args [][]byte, timeout uint32) (reqId common.Hash, err error) { diff --git a/ptn/api_backend.go b/ptn/api_backend.go index 1ca4dc1e7..29eaf0959 100755 --- a/ptn/api_backend.go +++ b/ptn/api_backend.go @@ -247,17 +247,17 @@ func (b *PtnApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma // GetContract func (b *PtnApiBackend) GetContract(addr common.Address) (*ptnjson.ContractJson, error) { - contract,err:= b.ptn.dag.GetContract(addr.Bytes()) - if err!=nil{ - return nil,err + contract, err := b.ptn.dag.GetContract(addr.Bytes()) + if err != nil { + return nil, err } - cjson:= ptnjson.ConvertContract2Json(contract) - tpl,err:= b.ptn.dag.GetContractTpl(contract.TemplateId) - if err!=nil{ - return cjson,nil + cjson := ptnjson.ConvertContract2Json(contract) + tpl, err := b.ptn.dag.GetContractTpl(contract.TemplateId) + if err != nil { + return cjson, nil } - cjson.Template= ptnjson.ConvertContractTemplate2Json(tpl) - return cjson,nil + cjson.Template = ptnjson.ConvertContractTemplate2Json(tpl) + return cjson, nil } func (b *PtnApiBackend) QueryDbByKey(key []byte) *ptnjson.DbRowJson { val, err := b.ptn.dag.QueryDbByKey(key) @@ -578,18 +578,13 @@ func (b *PtnApiBackend) ContractInvoke(deployId []byte, txid string, args [][]by log.Debugf("======>ContractInvoke:deployId[%s]txid[%s]", hex.EncodeToString(deployId), txid) channelId := "palletone" unit, err := b.ptn.contract.Invoke(rwset.RwM, channelId, deployId, txid, args, timeout) - //todo print rwset if err != nil { return nil, err } return unit.Payload, err - // todo tmp - //b.ptn.contractPorcessor.ContractTxReqBroadcast(deployId, txid, args, timeout) - //return nil, nil } func (b *PtnApiBackend) ContractQuery(contractId []byte, txid string, args [][]byte, timeout time.Duration) (rspPayload []byte, err error) { - //contractAddr := common.HexToAddress(hex.EncodeToString(contractId)) channelId := "palletone" rsp, err := b.ptn.contract.Invoke(rwset.RwM, channelId, contractId, txid, args, timeout) rwset.RwM.Close() @@ -598,14 +593,11 @@ func (b *PtnApiBackend) ContractQuery(contractId []byte, txid string, args [][]b return nil, err } log.Debugf("=====>ContractQuery:contractId[%s]txid[%s]", hex.EncodeToString(contractId), txid) - //fmt.Printf("contract query rsp = %#v\n", string(rsp.Payload)) return rsp.Payload, nil } func (b *PtnApiBackend) ContractStop(deployId []byte, txid string, deleteImage bool) error { log.Debugf("======>ContractStop:deployId[%s]txid[%s]", hex.EncodeToString(deployId), txid) - - //err := cc.Stop("palletone", deployId, txid, deleteImage) _, err := b.ptn.contract.Stop(rwset.RwM, "palletone", deployId, txid, deleteImage) return err } @@ -619,8 +611,8 @@ func (b *PtnApiBackend) SignAndSendRequest(addr common.Address, tx *modules.Tran func (b *PtnApiBackend) ContractInstallReqTx(from, to common.Address, daoAmount, daoFee uint64, tplName, path, version string, description, abi, language string, addrs []common.Address) (reqId common.Hash, tplId []byte, err error) { return b.ptn.contractPorcessor.ContractInstallReq(from, to, daoAmount, daoFee, tplName, path, version, description, abi, language, true, addrs) } -func (b *PtnApiBackend) ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, timeout time.Duration) (common.Hash, common.Address, error) { - return b.ptn.contractPorcessor.ContractDeployReq(from, to, daoAmount, daoFee, templateId, args, timeout) +func (b *PtnApiBackend) ContractDeployReqTx(from, to common.Address, daoAmount, daoFee uint64, templateId []byte, args [][]byte, extData []byte, timeout time.Duration) (common.Hash, common.Address, error) { + return b.ptn.contractPorcessor.ContractDeployReq(from, to, daoAmount, daoFee, templateId, args, extData, timeout) } func (b *PtnApiBackend) ContractInvokeReqTx(from, to common.Address, daoAmount, daoFee uint64, certID *big.Int, contractAddress common.Address, args [][]byte, timeout uint32) (reqId common.Hash, err error) { return b.ptn.contractPorcessor.ContractInvokeReq(from, to, daoAmount, daoFee, certID, contractAddress, args, timeout) diff --git a/ptnjson/txjson.go b/ptnjson/txjson.go index 969fbfcc1..1e59d666e 100755 --- a/ptnjson/txjson.go +++ b/ptnjson/txjson.go @@ -124,18 +124,17 @@ type InstallRequestJson struct { } type DeployRequestJson struct { - Number int `json:"row_number"` - TplId string `json:"tpl_id"` - //TxId string `json:"tx_id"` + Number int `json:"row_number"` + TplId string `json:"tpl_id"` Args []string `json:"arg_set"` Timeout time.Duration `json:"timeout"` + ExtData string `json:"extend_data"` } type StopRequestJson struct { - Number int `json:"row_number"` - ContractId string `json:"contract_id"` - //Txid string `json:"tx_id"` - DeleteImage bool `json:"delete_image"` + Number int `json:"row_number"` + ContractId string `json:"contract_id"` + DeleteImage bool `json:"delete_image"` } type DataJson struct { Number int `json:"row_number"` @@ -373,6 +372,7 @@ func convertDeployRequest2Json(req *modules.ContractDeployRequestPayload) *Deplo reqJson.Args = append(reqJson.Args, string(arg)) } reqJson.Timeout = time.Duration(req.Timeout) * time.Second + reqJson.ExtData = hex.EncodeToString(req.ExtData) return reqJson }