Cluster Lock

Push Distributed Validator Cluster Lock Data

Changed on

This endpoint saves cluster lock objects that describe the created Distributed Validator Cluster. The lock is stored with its own cluster_definition (the one covered by lock_hash), which is what lock reads return. If the lock_hash is already stored with its definition, the existing lock is returned (idempotent; no re-validation) with the same 201 response. If it is stored without one (saved by an earlier API version, definition_stored: false), the posted file is validated and its definition stored. A lock_hash that is not stored yet must have cluster_definition.version v1.10.0 or later (400 otherwise); locks stored at older versions can still be re-posted. The posted cluster_definition.config_hash must be the hash of the posted definition, and when a definition record exists for it the lock must have the same operator and creator addresses and configuration (400 otherwise). Several locks can share a config_hash (the DKG run again, or the same validator keys re-split to other nodes): each is stored. For definitions whose operators do not sign their ENRs (solo flow, charon create cluster), a further lock must re-split the validator keys of a stored lock (409 otherwise). GET /lock/configHash/{configHash} returns the most recently created of them. The current lock for a config_hash and its validators (is_current, superseded_by, positions and counts) is the one whose Charon nodes reported most recently, else the most recently created. The cluster definition record (GET /definition/{configHash}) is never changed by this endpoint.

post/v1/lock

Request

  • Base URL
    https://api.obol.tech
  • Auth
    none declared

Request body

signature_aggregatestring required
lock_hashstring required
node_signaturesstring[] required

Example request

{
  "cluster_definition": {
    "name": "My Obol Cluster",
    "uuid": "0194FDC2-FA2F-FCC0-41D3-FF12045B73C8",
    "version": "v1.8.0",
    "num_validators": 5,
    "threshold": 3,
    "dkg_algorithm": "default",
    "fork_version": "0x00001020",
    "config_hash": "0x2204ba6c238ed2d6a8ff951d4513db993c8d6f8860468391342649bf735a87d7",
    "timestamp": "2022-07-19T18:19:58+02:00",
    "deposit_amounts": [
      "8000000000",
      "16000000000",
      "8000000000"
    ],
    "definition_hash": "0xb656f5a4a5537b5817d6bcf735d043f17f5aff568b1a7ec9102a9f687bd4510c",
    "fee_recipient_address": "0x000000000000000000000000000000000000dead",
    "withdrawal_address": "0x000000000000000000000000000000000000dead",
    "consensus_protocol": "qbft",
    "target_gas_limit": 36000000,
    "compounding": true
  },
  "distributed_validators": [
    {
      "distributed_public_key": "0xb51336c31c4f0cc365d6c7b5d8ff1b4b7d4cf7c70163f9fd51a2badc854f5e29823fa11e3d7749d207807867149508d6",
      "deposit_data": {
        "pubkey": "0xb51336c31c4f0cc365d6c7b5d8ff1b4b7d4cf7c70163f9fd51a2badc854f5e29823fa11e3d7749d207807867149508d6",
        "withdrawal_credentials": "0x01000000000000000000000086b8145c98e5bd25ba722645b15ed65f024a87ec",
        "amount": "32000000000",
        "deposit_data_root": "5e58a5d8f1e53479343cb6188f061f6b1a46c521c53eef0580b04f485ad62bad",
        "signature": "0x88fe84889608a8b2424bddae2047d2ee4b42f72c4d8201d69e732d7c3bfa1bcb00f930979770b7d00071673fde8f205108dabe8d83ec49aa6de1b7869966b555be80a159e6ad11e273c4e0234038cfa525923044d6a89a4924fdc178f333568b"
      },
      "builder_registration": {
        "message": {
          "fee_recipient": "0x86B8145c98e5BD25BA722645b15eD65f024a87EC",
          "gas_limit": 30000000,
          "timestamp": 1616508000,
          "pubkey": "0xb51336c31c4f0cc365d6c7b5d8ff1b4b7d4cf7c70163f9fd51a2badc854f5e29823fa11e3d7749d207807867149508d6"
        },
        "signature": "0x851e4f196b7e7bda6429b94cceb92d480f53fa9753e1d6c830ff2706acb8cd866d81d5533db7dcfac1dc9d00a16e5e4801d33f36bdf1c2a2003e1c586466109e7851c79179b2c46d69c53c4a59e361d2727186a7e72bbd11debad1f2fae6f97d"
      },
      "partial_deposit_data": {
        "pubkey": "0xb51336c31c4f0cc365d6c7b5d8ff1b4b7d4cf7c70163f9fd51a2badc854f5e29823fa11e3d7749d207807867149508d6",
        "withdrawal_credentials": "0x01000000000000000000000086b8145c98e5bd25ba722645b15ed65f024a87ec",
        "amount": "32000000000",
        "deposit_data_root": "5e58a5d8f1e53479343cb6188f061f6b1a46c521c53eef0580b04f485ad62bad",
        "signature": "0x88fe84889608a8b2424bddae2047d2ee4b42f72c4d8201d69e732d7c3bfa1bcb00f930979770b7d00071673fde8f205108dabe8d83ec49aa6de1b7869966b555be80a159e6ad11e273c4e0234038cfa525923044d6a89a4924fdc178f333568b"
      }
    }
  ],
  "signature_aggregate": "0x85650c30ec29a3703934bf50a28da102975deda77e758579ea3dfe4136abf752",
  "lock_hash": "0xd2880980169ee4a0000f23feb8fad9a6c70f38312956fe67aa89e118f5b0e048",
  "node_signatures": [
    "0xe6e531be7bbf6cee37d80ab489ade6491469e10743d3c1496a3e66fe989eb4c100c260eaee4ef1aa08fdb79ea05bb8c12970dec1a296abe627ac25a2515373b301"
  ]
}

Response

The cluster lock object (new publish or idempotent retry for an existing lock_hash).

distributed_validatorsDistributedValidator[] required
signature_aggregatestring required
lock_hashstring required
node_signaturesstring[] required
definition_storedboolean required

true: cluster_definition is the exact definition this lock was created with (covered by lock_hash). false: this lock was stored without its exact cluster definition; lock_hash cannot be re-verified until the lock file is posted again.

is_currentboolean required

true: this is the current lock for its validators and config_hash. Several locks can share validator keys or a config_hash (re-split or DKG re-run); the current one is the lock whose Charon nodes reported most recently to Obol monitoring, or, when none of them has reported, the most recently created. It can change when another lock is posted for the same keys or when a sibling starts or stops reporting. GET /lock/configHash/{configHash} does not use this rule: it returns the most recently created lock, which can be is_current false.

superseded_bystring nullable required

lock_hash of the current lock that shares validator keys or the config_hash with this one, when this lock is not current; null when it is current.

Example response

{
  "cluster_definition": {
    "name": "My Obol Cluster",
    "uuid": "0194FDC2-FA2F-FCC0-41D3-FF12045B73C8",
    "version": "v1.8.0",
    "num_validators": 5,
    "threshold": 3,
    "dkg_algorithm": "default",
    "fork_version": "0x00001020",
    "config_hash": "0x2204ba6c238ed2d6a8ff951d4513db993c8d6f8860468391342649bf735a87d7",
    "timestamp": "2022-07-19T18:19:58+02:00",
    "deposit_amounts": [
      "8000000000",
      "16000000000",
      "8000000000"
    ],
    "definition_hash": "0xb656f5a4a5537b5817d6bcf735d043f17f5aff568b1a7ec9102a9f687bd4510c",
    "fee_recipient_address": "0x000000000000000000000000000000000000dead",
    "withdrawal_address": "0x000000000000000000000000000000000000dead",
    "consensus_protocol": "qbft",
    "target_gas_limit": 36000000,
    "compounding": true
  },
  "signature_aggregate": "0x85650c30ec29a3703934bf50a28da102975deda77e758579ea3dfe4136abf752",
  "lock_hash": "0xd2880980169ee4a0000f23feb8fad9a6c70f38312956fe67aa89e118f5b0e048",
  "definition_stored": true,
  "is_current": true
}

Changes

    • info

      added the media type application/json for the response with the status

    • info

      added the media type application/json for the response with the status

    • info

      added the media type application/json for the response with the status

    • info

      added the media type application/json for the response with the status

    • info

      added the media type application/json for the response with the status

    • info

      added the media type application/json for the response with the status

    • info

      added the non-success response with the status

    • info

      added the required property //// to the response with the status

    • info

      added the required property //// to the response with the status

    • info

      added the required property //// to the response with the status