{"id":43209318,"url":"https://github.com/strahe/extend","last_synced_at":"2026-02-01T07:14:26.730Z","repository":{"id":242044799,"uuid":"798155976","full_name":"strahe/extend","owner":"strahe","description":"Convert the Filecoin sector extend tool into an HTTP service, supporting state management, exception handling, automatic acceleration, etc.","archived":false,"fork":false,"pushed_at":"2025-04-15T05:47:33.000Z","size":303,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-13T11:45:20.187Z","etag":null,"topics":["filecoin","filecoin-miner"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/strahe.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-05-09T07:50:08.000Z","updated_at":"2025-04-15T05:46:51.000Z","dependencies_parsed_at":"2024-06-11T04:27:13.508Z","dependency_job_id":"439bc0b0-1406-4c18-945e-93df4e2dc0a6","html_url":"https://github.com/strahe/extend","commit_stats":null,"previous_names":["gh-efforts/extend","strahe/extend"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/strahe/extend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strahe%2Fextend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strahe%2Fextend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strahe%2Fextend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strahe%2Fextend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/strahe","download_url":"https://codeload.github.com/strahe/extend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/strahe%2Fextend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28971777,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T06:46:42.625Z","status":"ssl_error","status_checked_at":"2026-02-01T06:44:56.173Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filecoin","filecoin-miner"],"created_at":"2026-02-01T07:14:26.165Z","updated_at":"2026-02-01T07:14:26.721Z","avatar_url":"https://github.com/strahe.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# extend\n\n[English](README.md)\n\nFilecoin sector 续期服务\n\n[![Build](https://github.com/gh-efforts/extend/actions/workflows/container-build.yml/badge.svg)](https://github.com/gh-efforts/extend/actions/workflows/container-build.yml)\n\n## 部署\n\n### 运行测试\n```shell\nmake test\n```\n\n### 编译\n```shell\nmake  # 或者 make docker\n```\n\n### 运行\n在运行之前，请确保设置了 `FULLNODE_API_INFO` 环境变量，具有必要的权限:\n```shell\nexport FULLNODE_API_INFO=\"lotus api info\"  # 需要 'sign' 权限\n```\n\n启动服务:\n```shell\n./extend run\n\nOPTIONS:\n   --listen value    specify the address to listen on (default: \"127.0.0.1:8000\")\n   --db value        specify the database URL to use， support sqlite3, mysql, postgres, https://github.com/xo/dburl?tab=readme-ov-file#example-urls (default: \"sqlite3:extend.db\")\n   --secret value    specify the secret to use for API authentication, if not set, no auth will be enabled\n   --max-wait value  [Warning] specify the maximum time to wait for messages on chain, otherwise try to replace them, only use this if you know what you are doing (default: 0s)\n   --debug           enable debug logging (default: false)\n   --help, -h        show help\n```\n\n查看帮助:\n```shell\n./extend -h  \n```\n\n### Docker\n使用Docker运行服务:\n```shell\ndocker run -d --name extend \\\n  -p 8000:8000 \\\n  -e FULLNODE_API_INFO=\"lotus api info\" \\\n  -v /path/to/extend:/app \\\n  ghcr.io/strahe/extend:latest run --listen 0.0.0.0:8000 --db /app/extend.db\n```\n\n### 开启鉴权 (可选)\n通过使用 `--secret` 选项启用鉴权:\n```shell\n./extend run --secret yoursecret\n```\n\n#### 生成token\n```shell\n./extend auth create-token --secret yoursecret --user {user} [--expiry 可选过期时间]\n\n# Example output\ntoken created successfully:\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJsZWUiLCJuYmYiOjE3MTU1NzExMzgsImlhdCI6MTcxNTU3MTEzOH0.2FinpGB7Dx07dLNWPAW3jqo703i13nZUB8ZCY__wKnQ\n```\n使用token:\n```\nAuthorization:  Bearer  \u003ctoken\u003e\n```\n\u003e [!Warning]\n\u003e 修改 `--secret yoursecret` ， 基于secret生成的所有token将会失效.\n\n## 2. Usage\n\n### 创建一个续期请求\n\n```http request\nPOST /requests\n```\n\n#### 请求参数\n\n| 参数名                 | 值                         | 是否必须 | 说明                                                                                       |  \n|---------------------|---------------------------|------|------------------------------------------------------------------------------------------|  \n| miner               | f01234                    | 是    | 节点名字                                                                                     |  \n| from                | 2024-05-12T07:34:47+00:00 | 是    | sector到期范围的开始时间,RFC3339格式，表明续期这个范围的sector                                                |  \n| to                  | 2024-05-13T07:34:47+00:00 | 是    | sector到期的结束时间,RFC3339格式，表明续期这个范围的sector                                                  |  \n| extension           | 20160                     | 否    | 续期的Epoch数量，即在原有效期的基础上追加对应的高度                                                             |  \n| new_expiration      | 3212223                   | 否    | 不管之前的有效期是多少，统一续期到指定的高度，如果设置了这个值，extension将被忽略                                            |  \n| tolerance           | 20160，7天，默认值              | 否    | 续期公差，精度，将到期时间相近的sector聚合成相同的到期时间，减少消息大小，降低gas, 且最低续期时间不能低于这个值， 使用new_expiration时，这个值会被忽略 |\n| max_sectors         | 500, 默认值                  | 否    | 单条消息允许包含的最大sector数量，最大25000                                                              |\n| max_initial_pledges | 0, 默认值                    | 否    | 续期的扇区中，累计允许的最大质押值，如果质押币累计超过设置的值，其余的sector将不会被续期，默认不限制                                    |\n| basefee_limit       | null                      | No   | 只有当网络basefee低于这个值时才发送续期消息， 0 和 null 表示不限制                                                |\n| dry_run             | false，默认                  | 否    | 是否是测试，如果是测试，不会真正执行续期操作，只会做一些检查                                                           |  \n\n#### 请求示例\n```json  \n{  \n    \"miner\": \"f01234\", \n    \"from\": \"2024-05-12T07:34:47+00:00\", \n    \"to\": \"2024-05-13T07:34:47+00:00\", \n    \"extension\": 20160, \n    \"new_expiration\": 3212223, \n    \"tolerance\": 20160, \n    \"max_sectors\": 500,\n    \"basefee_limit\": null,\n    \"dry_run\": false\n }  \n```  \n\n#### 返回参数\n| 参数名                 | 值                                                     | 说明                                                     |  \n|---------------------|-------------------------------------------------------|--------------------------------------------------------|  \n| id                  | 11                                                    | 请求ID                                                   |  \n| extension           | 21000                                                 | 续期追加的高度，创建时指定的参数                                       |  \n| from                | \"2024-05-12T07:34:47Z\"                                | 筛选过期sector的开始时间，创建时指定的参数                               |  \n| to                  | \"2024-05-13T07:34:47Z\"                                | 筛选过期sector的结束时间，创建时指定的参数                               |  \n| new_expiration      | null                                                  | 新的过期时间，创建时指定的参数                                        |  \n| max_sectors         | 500                                                   | 单条消息允许包含的最大sector数量，创建时指定的参数                           |\n| basefee_limit       | null                                                  | 只有当网络basefee低于这个值时才发送续期消息                              |\n| max_initial_pledges | 0                                                     | 续期的扇区中，累计允许的最大质押值，如果质押币累计超过设置的值，其余的sector将不会被续期，默认不限制  |\n| messages            | null                                                  | 续期上链的消息，array                                          |  \n| tolerance           | 20160                                                 | 续期公差，创建时指定的参数                                          |\n| miner               | \"t017387\"                                             | 矿工                                                     |  \n| status              | \"failed\"                                              | 状态，`created`,`pending`,`failed`,`partfailed`,`success` |  \n| took                | 526.841994321                                         | 续期执行耗时,单位s                                             |  \n| confirmed_at        | null                                                  | 消息上链的确认时间                                              |  \n| dry_run             | true                                                  | 是否为测试运行                                                |  \n| dry_run_result      | \"\"                                                    | 测试运行结果                                                 |  \n| error               | \"failed to get active sector set: RPCConnectionError\" | 错误信息                                                   |  \n| total_sectors       | 1000                                                  | 续期的sector数量                                            |\n| published_sectors   | 500                                                   | 实际上链的sector数量，注：上链并不一定成功                               |\n| succeeded_sectors   | 0                                                     | 成功续期的sector数量                                          |\n| created_at          | \"2024-05-11T13:39:40.74831759+08:00\"                  | 创建时间                                                   |  \n| updated_at          | \"2024-05-11T13:40:16.237069667+08:00\"                 | 更新时间                                                   |  \n\n#### 返回示例\n```json  \n{  \n  \"data\": {\n    \"basefee_limit\": null,\n    \"confirmed_at\": null, \n    \"created_at\": \"2024-05-11T13:39:40.74831759+08:00\", \n    \"dry_run\": true, \n    \"dry_run_result\": \"\", \n    \"error\": \"failed to get active sector set: RPCConnectionError\", \n    \"extension\": 21000, \n    \"tolerance\": 20160, \n    \"max_sectors\": 500,\n    \"max_initial_pledges\": 0,\n    \"from\": \"2024-05-12T07:34:47Z\", \n    \"id\": 11, \n    \"messages\": null, \n    \"miner\": \"t017387\", \n    \"new_expiration\": null, \n    \"status\": \"created\", \n    \"to\": \"2024-05-13T07:34:47Z\", \n    \"total_sectors\": 0,\n    \"published_sectors\": 0,\n    \"succeeded_sectors\": 0,\n    \"took\": 526.841994321, \n    \"updated_at\": \"2024-05-11T13:40:16.237069667+08:00\"\n  }\n}  \n``` \n\n### 查询续期请求\n根据ID查询一个续期请求，返回的结构与创建时一致\n```http request\nGET /requests/{:id}\n```\n\n#### 返回示例\n ```json\n{\n  \"data\": {\n    \"basefee_limit\": null,\n    \"confirmed_at\": null,\n    \"created_at\": \"2024-05-13T16:44:58.208723388+08:00\",\n    \"dry_run\": false,\n    \"dry_run_result\": \"\",\n    \"error\": \"\",\n    \"extension\": 21000,\n    \"from\": \"2024-05-13T15:18:47+08:00\",\n    \"id\": 19,\n    \"messages\": [\n      \"bafy2bzacecvqxeqlk4z2gugbtbhgjmptdfjpt73jemf2zwtbj7lepxhf4h6r4\"\n    ],\n    \"miner\": \"f017387\",\n    \"new_expiration\": null,\n    \"max_sectors\": 500,\n    \"max_initial_pledges\": 0,\n    \"status\": \"pending\",\n    \"to\": \"2024-05-14T15:18:47+08:00\",\n    \"total_sectors\": 1000,\n    \"published_sectors\": 500,\n    \"succeeded_sectors\": 0,\n    \"took\": 526.841994321,\n    \"updated_at\": \"2024-05-13T16:53:55.942614308+08:00\"\n  }\n}\n ```\n\n### 加速续期请求\n加速一个续期请求，将一个pending状态的请求未上链的所有消息重新预估gas后上链.\n```http request\nPOST /requests/{:id}/speedup\n```\n\u003e [!WARNING]\n\u003e 只有pending状态的请求才能加速，其他状态的请求不能加速.\n\u003e 加速返回success，并不能保证消息一定会上链，等待一段时间后再次查询请求状态，可多次尝试.\n\n#### 请求参数\n\n| 参数名       | 值    | 是否必须 | 说明                    |  \n|-----------|------|------|-----------------------|  \n| fee_limit | 1FIL | 否    | 允许最大消耗的GAS费用,不传系统自动预估 |  \n\n#### 请求示例\n ```json\n {\n  \"fee_limit\": \"1FIL\"\n}\n```\n\n#### 返回示例\n ```json\n {\n  \"data\": \"success\"\n}\n```\n\n### Update Request\n更新一个续期请求，只有未开始的请求才能更新， 目前只支持更新 `basefee_limit` 参数.\n\n```http request\nPATCH /requests/{:id}\n```\n\n#### Request Example\n\u003e [!NOTE]\n\u003e 0 和 null 表示不限制\n\n ```json\n {\n  \"basefee_limit\": 0 \n}\n```\n\n#### Response Example\n和创建请求的返回一致\n\n### 使用限制\n\n续期有很多硬性和软性的限制， 其中硬性限制是无法绕过的，包括：\n* 每个请求的sector数量不能超过25000个\n* 每个请求最大的Declarations不能超过3000个\n* sector 只能最大生命周期是5年\n* sector 最大续期周期是3年半 （1278d）\n\n软性限制包括：\n* gas fee 限制\n* 虚拟机性能限制等\n\n\u003e [!TIP]\n\u003e 什么是 Declarations？\n\u003e 想象一个二维坐标轴，x轴是要续期的目的高度，y轴是sector的位置(deadline,partition),任何续期的sector都可以用一个坐标来表示.\n\u003e sector 的位置(y)和续期目的高度(x)可以相同，即在坐标上用相同的点表示，也可以不同，即在坐标上用不同的点表示.\n\u003e 这一个点就是一个Declaration，一个请求可以有多个Declaration，但是不能超过3000个.\n\u003e 一个Declaration可以包含多个sector，且所有Declarations包含的sector不能大于25000个.\n\n\u003e [!TIP]\n\u003e 什么是 Tolerance? \n\u003e 根据Declarations的定义可以得知，续期限制主要是Declaration的数量，即二维坐标上的点的数量，而不是sector的数量.\n\u003e Tolerance是一个续期公差，用于将续期后的到期时间相近的sector聚合成相同的到期时间，即相同的x坐标，\n\u003e 这样在二维坐标上有更多的点重合，降低Declaration数量，从而降低消息大小，降低gas fee.\n\u003e 同时要求最低续期时间不能低于这个值.\n\u003e 举例说明： 如果一个sector续期到 2024-06-01:00:00:00, 另一个sector续期到它的6小时以后，即2024-06-01:00:06:00， 此时如果我们设置的Tolerance公差大于6小时，那么第二个sector也会续期到和第一个sector相同的时间，即2024-06-01:00:00:00，（比实际少续6小时）， 如果我们设置Tolerance公差小于6小时，那么这两个sector会单独续期到各自的时间.\n\n## 异常\n\nHttp status：\n* 400： 请求问题\n* 500： 服务器问题\n* 401： 授权问题（如果开启）\n\n```json\n{\n  \"error\": \"msg\"\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrahe%2Fextend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstrahe%2Fextend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrahe%2Fextend/lists"}