// Copyright (C) 2019 Storj Labs, Inc. // See LICENSE for copying information. syntax = "proto3"; option go_package = "storj.io/common/pb"; package orders; import "gogo.proto"; import "google/protobuf/timestamp.proto"; import "node.proto"; // PieceAction is an enumeration of all possible executed actions on storage node. enum PieceAction { INVALID = 0; PUT = 1; GET = 2; GET_AUDIT = 3; GET_REPAIR = 4; PUT_REPAIR = 5; DELETE = 6; PUT_GRACEFUL_EXIT = 7; } // OrderLimit is provided by satellite to execute specific action on storage node within some limits. message OrderLimit { // unique serial to avoid replay attacks bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false]; // satellite who issued this order limit allowing orderer to do the specified action bytes satellite_id = 2 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; // uplink who requested or whom behalf the order limit to do an action bytes deprecated_uplink_id = 3 [(gogoproto.customtype) = "NodeID"]; // public key that will be used to sign orders and piece hash bytes uplink_public_key = 13 [(gogoproto.customtype) = "PiecePublicKey", (gogoproto.nullable) = false]; // storage node who can re claimthe order limit specified by serial bytes storage_node_id = 4 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; // piece which is allowed to be touched bytes piece_id = 5 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; // limit in bytes how much can be changed int64 limit = 6; PieceAction action = 7; google.protobuf.Timestamp piece_expiration = 8 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp order_expiration = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp order_creation = 12 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; bytes satellite_signature = 10; // satellites aren't necessarily discoverable in kademlia. this allows // a storage node to find a satellite and handshake with it to get its key. node.NodeAddress satellite_address = 11; } // OrderLimitSigning provides OrderLimit signing serialization. // // It is never used for sending across the network, it is // used in signing to ensure that nullable=false fields get handled properly. // Its purpose is to solidify the format of how we serialize for // signing, to handle some backwards compatibility considerations. message OrderLimitSigning { // unique serial to avoid replay attacks bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false]; // satellite who issued this order limit allowing orderer to do the specified action bytes satellite_id = 2 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; // uplink who requested or whom behalf the order limit to do an action bytes deprecated_uplink_id = 3 [(gogoproto.customtype) = "NodeID"]; // public key that will be used to sign orders and piece hash bytes uplink_public_key = 13 [(gogoproto.customtype) = "PiecePublicKey"]; // storage node who can re claimthe order limit specified by serial bytes storage_node_id = 4 [(gogoproto.customtype) = "NodeID", (gogoproto.nullable) = false]; // piece which is allowed to be touched bytes piece_id = 5 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; // limit in bytes how much can be changed int64 limit = 6; PieceAction action = 7; google.protobuf.Timestamp piece_expiration = 8 [(gogoproto.stdtime) = true]; google.protobuf.Timestamp order_expiration = 9 [(gogoproto.stdtime) = true]; google.protobuf.Timestamp order_creation = 12 [(gogoproto.stdtime) = true]; bytes satellite_signature = 10; // this allows a storage node to find a satellite and handshake with it to get its key. node.NodeAddress satellite_address = 11; } // Order is a one step of fullfilling Amount number of bytes from an OrderLimit with SerialNumber. message Order { // serial of the order limit that was signed bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false]; // amount to be signed for int64 amount = 2; // signature bytes uplink_signature = 3; } // OrderSigning provides Order signing format. // // It is never used for sending across the network, it is // used in signing to ensure that nullable=false fields get handled properly. // Its purpose is to solidify the format of how we serialize for // signing, to handle some backwards compatibility considerations. message OrderSigning { // serial of the order limit that was signed bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false]; // amount to be signed for int64 amount = 2; // signature bytes uplink_signature = 3; } message PieceHash { // piece id bytes piece_id = 1 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; // hash of the piece that was/is uploaded bytes hash = 2; // size of uploaded piece int64 piece_size = 4; // timestamp when upload occurred google.protobuf.Timestamp timestamp = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; // signature either satellite or storage node bytes signature = 3; } // PieceHashSigning provides piece hash signing format. // // It is never used for sending across the network, it is // used in signing to ensure that nullable=false fields get handled properly. // Its purpose is to solidify the format of how we serialize for // signing, to handle some backwards compatibility considerations. message PieceHashSigning { // piece id bytes piece_id = 1 [(gogoproto.customtype) = "PieceID", (gogoproto.nullable) = false]; // hash of the piece that was/is uploaded bytes hash = 2; // size of uploaded piece int64 piece_size = 4; // timestamp when upload occurred google.protobuf.Timestamp timestamp = 5 [(gogoproto.stdtime) = true]; // signature either satellite or storage node bytes signature = 3; } service Orders { rpc Settlement(stream SettlementRequest) returns (stream SettlementResponse) {} } // Expected order of messages from storagenode: // go repeated // SettlementRequest -> (async) // go repeated // <- SettlementResponse message SettlementRequest { OrderLimit limit = 1; Order order = 2; } message SettlementResponse { enum Status { INVALID = 0; ACCEPTED = 1; REJECTED = 2; } bytes serial_number = 1 [(gogoproto.customtype) = "SerialNumber", (gogoproto.nullable) = false]; Status status = 2; }