diff --git a/chain/event.go b/chain/event.go index 51f0192..34167a4 100644 --- a/chain/event.go +++ b/chain/event.go @@ -899,6 +899,53 @@ func (c *chainClient) RetrieveEvent_FileBank_ReplaceIdleSpace(blockhash types.Ha return result, errors.Errorf("failed: no %s event found", event.FileBankReplaceIdleSpace) } +func (c *chainClient) RetrieveEvent_FileBank_CalculateReport(blockhash types.Hash) (event.Event_CalculateReport, error) { + var result event.Event_CalculateReport + events, err := c.eventRetriever.GetEvents(blockhash) + if err != nil { + return result, err + } + for _, e := range events { + if e.Name == event.FileBankCalculateReport { + for _, v := range e.Fields { + if reflect.TypeOf(v.Value).Kind() == reflect.Slice { + vf := reflect.ValueOf(v.Value) + if vf.Len() > 0 { + allValue := fmt.Sprintf("%v", vf.Index(0)) + if strings.Contains(v.Name, "AccountId32") { + temp := strings.Split(allValue, "] ") + puk := make([]byte, types.AccountIDLen) + for _, v := range temp { + if strings.Count(v, " ") == (types.AccountIDLen - 1) { + subValue := strings.TrimPrefix(v, "[") + ids := strings.Split(subValue, " ") + if len(ids) != types.AccountIDLen { + continue + } + for kk, vv := range ids { + intv, _ := strconv.Atoi(vv) + puk[kk] = byte(intv) + } + } + } + if !utils.CompareSlice(puk, c.GetSignatureAccPulickey()) { + continue + } + accid, err := types.NewAccountID(puk) + if err != nil { + continue + } + result.Miner = *accid + return result, nil + } + } + } + } + } + } + return result, errors.Errorf("failed: no %s event found", event.FileBankCalculateReport) +} + func (c *chainClient) RetrieveEvent_Sminer_UpdataIp(blockhash types.Hash) (event.Event_UpdataIp, error) { var result event.Event_UpdataIp events, err := c.eventRetriever.GetEvents(blockhash) diff --git a/chain/fileBank.go b/chain/fileBank.go index edd8609..e373146 100644 --- a/chain/fileBank.go +++ b/chain/fileBank.go @@ -1680,3 +1680,117 @@ func (c *chainClient) ReplaceIdleSpace(idleSignInfo pattern.SpaceProofInfo, sign } } } + +func (c *chainClient) ReportTagCalculated(fragmentHash string) (string, error) { + c.lock.Lock() + defer func() { + c.lock.Unlock() + if err := recover(); err != nil { + log.Println(utils.RecoverError(err)) + } + }() + + var ( + txhash string + accountInfo types.AccountInfo + ) + + if !c.GetChainState() { + return txhash, pattern.ERR_RPC_CONNECTION + } + + var fragmenthash pattern.FileHash + + if len(fragmentHash) != pattern.FileHashLen { + return txhash, errors.New("invalid fragment hash") + } + + for i := 0; i < len(fragmentHash); i++ { + fragmenthash[i] = types.U8(fragmentHash[i]) + } + + call, err := types.NewCall(c.metadata, pattern.TX_FILEBANK_CALCULATEREPORT, fragmenthash) + if err != nil { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] NewCall: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + + key, err := types.CreateStorageKey(c.metadata, pattern.SYSTEM, pattern.ACCOUNT, c.keyring.PublicKey) + if err != nil { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] CreateStorageKey: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + + ok, err := c.api.RPC.State.GetStorageLatest(key, &accountInfo) + if err != nil { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] GetStorageLatest: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + if !ok { + return txhash, pattern.ERR_RPC_EMPTY_VALUE + } + + o := types.SignatureOptions{ + BlockHash: c.genesisHash, + Era: types.ExtrinsicEra{IsMortalEra: false}, + GenesisHash: c.genesisHash, + Nonce: types.NewUCompactFromUInt(uint64(accountInfo.Nonce)), + SpecVersion: c.runtimeVersion.SpecVersion, + Tip: types.NewUCompactFromUInt(0), + TransactionVersion: c.runtimeVersion.TransactionVersion, + } + + ext := types.NewExtrinsic(call) + + // Sign the transaction + err = ext.Sign(c.keyring, o) + if err != nil { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] Sign: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + + // Do the transfer and track the actual status + sub, err := c.api.RPC.Author.SubmitAndWatchExtrinsic(ext) + if err != nil { + if strings.Contains(err.Error(), pattern.ERR_RPC_PRIORITYTOOLOW) { + o.Nonce = types.NewUCompactFromUInt(uint64(accountInfo.Nonce + 1)) + err = ext.Sign(c.keyring, o) + if err != nil { + return txhash, errors.Wrap(err, "[Sign]") + } + sub, err = c.api.RPC.Author.SubmitAndWatchExtrinsic(ext) + if err != nil { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] SubmitAndWatchExtrinsic: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + } else { + err = fmt.Errorf("rpc err: [%s] [tx] [%s] SubmitAndWatchExtrinsic: %v", c.GetCurrentRpcAddr(), pattern.TX_FILEBANK_CALCULATEREPORT, err) + c.SetChainState(false) + return txhash, err + } + } + defer sub.Unsubscribe() + + timeout := time.NewTimer(c.packingTime) + defer timeout.Stop() + + for { + select { + case status := <-sub.Chan(): + if status.IsInBlock { + txhash = status.AsInBlock.Hex() + _, err = c.RetrieveEvent_Sminer_IncreaseDeclarationSpace(status.AsInBlock) + return txhash, err + } + case err = <-sub.Err(): + return txhash, errors.Wrap(err, "[sub]") + case <-timeout.C: + return txhash, pattern.ERR_RPC_TIMEOUT + } + } +} diff --git a/core/event/events.go b/core/event/events.go index 9cb8117..8d8da59 100644 --- a/core/event/events.go +++ b/core/event/events.go @@ -274,6 +274,13 @@ type Event_ReplaceIdleSpace struct { Topics []types.Hash } +type Event_CalculateReport struct { + Phase types.Phase + Miner types.AccountID + FileHash pattern.FileHash + Topics []types.Hash +} + // ------------------------StorageHandler-------------------------------- type Event_BuySpace struct { Phase types.Phase @@ -434,6 +441,7 @@ type EventRecords struct { FileBank_StorageCompleted []Event_StorageCompleted FileBank_IdleSpaceCert []Event_IdleSpaceCert FileBank_ReplaceIdleSpace []Event_ReplaceIdleSpace + FileBank_CalculateReport []Event_CalculateReport // OSS Oss_Authorize []Event_Authorize diff --git a/core/event/eventsName.go b/core/event/eventsName.go index 42d8ca3..9326c98 100644 --- a/core/event/eventsName.go +++ b/core/event/eventsName.go @@ -35,6 +35,7 @@ const ( FileBankStorageCompleted = "FileBank.StorageCompleted" FileBankIdleSpaceCert = "FileBank.IdleSpaceCert" FileBankReplaceIdleSpace = "FileBank.ReplaceIdleSpace" + FileBankCalculateReport = "FileBank.CalculateReport " // OSS OssAuthorize = "Oss.Authorize" diff --git a/core/pattern/pattern.go b/core/pattern/pattern.go index 268f2ea..cbe7356 100644 --- a/core/pattern/pattern.go +++ b/core/pattern/pattern.go @@ -143,6 +143,7 @@ const ( TX_FILEBANK_RESTORALCOMPLETE = FILEBANK + DOT + "restoral_order_complete" TX_FILEBANK_CERTIDLESPACE = FILEBANK + DOT + "cert_idle_space" TX_FILEBANK_REPLACEIDLESPACE = FILEBANK + DOT + "replace_idle_space" + TX_FILEBANK_CALCULATEREPORT = FILEBANK + DOT + "calculate_report" // STORAGE_HANDLER TX_STORAGE_BUYSPACE = STORAGEHANDLER + DOT + "buy_space" @@ -316,7 +317,7 @@ type FileMetadata struct { type SegmentInfo struct { Hash FileHash - FragmentList []FragmentList + FragmentList []FragmentInfo } type UserBrief struct { @@ -325,19 +326,18 @@ type UserBrief struct { BucketName types.Bytes } -type FragmentList struct { +type FragmentInfo struct { Hash FileHash Avail types.Bool + Tag types.Option[types.U32] Miner types.AccountID } type StorageOrder struct { - Stage types.U8 - Count types.U8 FileSize types.U128 SegmentList []SegmentList User UserBrief - CompleteInfo []CompleteInfo + CompleteList []CompleteInfo } type SegmentList struct { diff --git a/core/sdk/sdk.go b/core/sdk/sdk.go index 33432e2..3375354 100644 --- a/core/sdk/sdk.go +++ b/core/sdk/sdk.go @@ -380,6 +380,8 @@ type SDK interface { // RetrieveEvent_FileBank_ReplaceIdleSpace(blockhash types.Hash) (event.Event_ReplaceIdleSpace, error) // + RetrieveEvent_FileBank_CalculateReport(blockhash types.Hash) (event.Event_CalculateReport, error) + // RetrieveEvent_Sminer_Registered(blockhash types.Hash) (event.Event_Registered, error) // RetrieveEvent_Sminer_RegisterPoisKey(blockhash types.Hash) (event.Event_RegisterPoisKey, error)