Skip to content

Commit

Permalink
Add QuorumSignInfo and merge CertifiedTransaction with other Tran…
Browse files Browse the repository at this point in the history
…saction types (#1686)

* Add QuorumSignInfo

* Add cached digest to Tx envelope

* Merge CertifiedTransaction

* Rename QuorumSignInfo
  • Loading branch information
lxfind committed May 1, 2022
1 parent 94dc273 commit 8bb5bbf
Show file tree
Hide file tree
Showing 19 changed files with 269 additions and 262 deletions.
83 changes: 38 additions & 45 deletions sui/open_rpc/spec/openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@
"description": "",
"required": true,
"schema": {
"$ref": "#/components/schemas/CertifiedTransaction"
"$ref": "#/components/schemas/TransactionEnvelope_for_AuthorityQuorumSignInfo"
}
}
},
Expand Down Expand Up @@ -616,6 +616,37 @@
"AccountAddress": {
"$ref": "#/components/schemas/Hex"
},
"AuthorityQuorumSignInfo": {
"description": "Represents at least a quorum (could be more) of authority signatures.",
"type": "object",
"required": [
"epoch",
"signatures"
],
"properties": {
"epoch": {
"type": "integer",
"format": "uint64",
"minimum": 0.0
},
"signatures": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"$ref": "#/components/schemas/PublicKeyBytes"
},
{
"$ref": "#/components/schemas/AuthoritySignature"
}
],
"maxItems": 2,
"minItems": 2
}
}
}
},
"AuthoritySignature": {
"description": "A signature emitted by an authority. It's useful to decouple this from user signatures, as their set of supported schemes will probably diverge",
"allOf": [
Expand Down Expand Up @@ -685,41 +716,6 @@
}
]
},
"CertifiedTransaction": {
"description": "An transaction signed by a quorum of authorities\n\nNote: the signature set of this data structure is not necessarily unique in the system, i.e. there can be several valid certificates per transaction.\n\nAs a consequence, we check this struct does not implement Hash or Eq, see the note below.",
"type": "object",
"required": [
"epoch",
"signatures",
"transaction"
],
"properties": {
"epoch": {
"type": "integer",
"format": "uint64",
"minimum": 0.0
},
"signatures": {
"type": "array",
"items": {
"type": "array",
"items": [
{
"$ref": "#/components/schemas/PublicKeyBytes"
},
{
"$ref": "#/components/schemas/AuthoritySignature"
}
],
"maxItems": 2,
"minItems": 2
}
},
"transaction": {
"$ref": "#/components/schemas/TransactionEnvelope_for_EmptySignInfo"
}
}
},
"Data": {
"oneOf": [
{
Expand Down Expand Up @@ -750,9 +746,6 @@
}
]
},
"EmptySignInfo": {
"type": "object"
},
"Event": {
"description": "User-defined event emitted by executing Move code. Executing a transaction produces an ordered log of these",
"type": "object",
Expand Down Expand Up @@ -918,7 +911,7 @@
"description": "Certificate of the transaction",
"allOf": [
{
"$ref": "#/components/schemas/CertifiedTransaction"
"$ref": "#/components/schemas/TransactionEnvelope_for_AuthorityQuorumSignInfo"
}
]
},
Expand Down Expand Up @@ -1425,7 +1418,7 @@
"description": "Certificate of the transaction",
"allOf": [
{
"$ref": "#/components/schemas/CertifiedTransaction"
"$ref": "#/components/schemas/TransactionEnvelope_for_AuthorityQuorumSignInfo"
}
]
},
Expand Down Expand Up @@ -1586,7 +1579,7 @@
"description": "Certificate of the transaction",
"allOf": [
{
"$ref": "#/components/schemas/CertifiedTransaction"
"$ref": "#/components/schemas/TransactionEnvelope_for_AuthorityQuorumSignInfo"
}
]
},
Expand Down Expand Up @@ -1910,7 +1903,7 @@
}
}
},
"TransactionEnvelope_for_EmptySignInfo": {
"TransactionEnvelope_for_AuthorityQuorumSignInfo": {
"description": "A transaction signed by a client, optionally signed by an authority (depending on `S`). `S` indicates the authority signing state. It can be either empty or signed. We make the authority signature templated so that `TransactionEnvelope<S>` can be used universally in the transactions storage in `SuiDataStore`, shared by both authorities and non-authorities: authorities store signed transactions, while non-authorities store unsigned transactions.",
"type": "object",
"required": [
Expand All @@ -1923,7 +1916,7 @@
"description": "authority signature information, if available, is signed by an authority, applied on `data`.",
"allOf": [
{
"$ref": "#/components/schemas/EmptySignInfo"
"$ref": "#/components/schemas/AuthorityQuorumSignInfo"
}
]
},
Expand Down Expand Up @@ -1985,7 +1978,7 @@
"type": "array",
"items": [
{
"$ref": "#/components/schemas/CertifiedTransaction"
"$ref": "#/components/schemas/TransactionEnvelope_for_AuthorityQuorumSignInfo"
},
{
"$ref": "#/components/schemas/TransactionEffects"
Expand Down
6 changes: 3 additions & 3 deletions sui/src/benchmark/transaction_creator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ fn make_serialized_cert(
) -> Vec<u8> {
// Make certificate
let mut certificate = CertifiedTransaction::new(tx);
certificate.epoch = committee.epoch();
certificate.auth_sign_info.epoch = committee.epoch();
for i in 0..committee.quorum_threshold() {
let (pubx, secx) = keys.get(i).unwrap();
let sig = AuthoritySignature::new(&certificate.transaction.data, secx);
certificate.signatures.push((*pubx, sig));
let sig = AuthoritySignature::new(&certificate.data, secx);
certificate.auth_sign_info.signatures.push((*pubx, sig));
}

let serialized_certificate = serialize_cert(&certificate);
Expand Down
37 changes: 16 additions & 21 deletions sui_core/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl AuthorityState {
#[instrument(level = "trace", skip_all)]
async fn check_locks(
&self,
transaction: &Transaction,
transaction: &TransactionData,
gas_object: Object,
gas_status: &mut SuiGasStatus<'_>,
) -> Result<Vec<(InputObjectKind, Object)>, SuiError> {
Expand Down Expand Up @@ -184,8 +184,8 @@ impl AuthorityState {
async fn handle_transaction_impl(
&self,
transaction: Transaction,
transaction_digest: TransactionDigest,
) -> Result<TransactionInfoResponse, SuiError> {
let transaction_digest = *transaction.digest();
// Ensure an idempotent answer.
if self._database.transaction_exists(&transaction_digest)? {
let transaction_info = self.make_transaction_info(&transaction_digest).await?;
Expand All @@ -200,7 +200,7 @@ impl AuthorityState {
.await?;

let all_objects: Vec<_> = self
.check_locks(&transaction, gas_object, &mut gas_status)
.check_locks(&transaction.data, gas_object, &mut gas_status)
.await?;
if transaction.contains_shared_object() {
// It's important that we do this here to make sure there is enough
Expand All @@ -216,7 +216,7 @@ impl AuthorityState {
// The call to self.set_transaction_lock checks the lock is not conflicting,
// and returns ConflictingTransaction error in case there is a lock on a different
// existing transaction.
self.set_transaction_lock(&owned_objects, transaction_digest, signed_transaction)
self.set_transaction_lock(&owned_objects, signed_transaction)
.await?;

// Return the signed Transaction or maybe a cert.
Expand All @@ -230,11 +230,9 @@ impl AuthorityState {
) -> Result<TransactionInfoResponse, SuiError> {
// Check the sender's signature.
transaction.check_signature()?;
let transaction_digest = transaction.digest();
let transaction_digest = *transaction.digest();

let response = self
.handle_transaction_impl(transaction, transaction_digest)
.await;
let response = self.handle_transaction_impl(transaction).await;
match response {
Ok(r) => Ok(r),
// If we see an error, it is possible that a certificate has already been processed.
Expand Down Expand Up @@ -334,17 +332,16 @@ impl AuthorityState {
) -> Result<TransactionInfoResponse, SuiError> {
let certificate = confirmation_transaction.certificate;
let transaction_digest = *certificate.digest();
let transaction = &certificate.transaction;

let (gas_object, mut gas_status) = self
.check_gas(
transaction.gas_payment_object_ref().0,
transaction.data.gas_budget,
certificate.gas_payment_object_ref().0,
certificate.data.gas_budget,
)
.await?;

let objects_by_kind = self
.check_locks(transaction, gas_object, &mut gas_status)
.check_locks(&certificate.data, gas_object, &mut gas_status)
.await?;

// At this point we need to check if any shared objects need locks,
Expand Down Expand Up @@ -380,7 +377,7 @@ impl AuthorityState {
let effects = execution_engine::execute_transaction_to_effects(
shared_object_refs,
&mut temporary_store,
transaction.clone(),
certificate.data.clone(),
transaction_digest,
transaction_dependencies,
&self.move_vm,
Expand Down Expand Up @@ -410,20 +407,19 @@ impl AuthorityState {
last_consensus_index: ExecutionIndices,
) -> SuiResult<()> {
// Ensure it is a shared object certificate
if !certificate.transaction.contains_shared_object() {
if !certificate.contains_shared_object() {
log::debug!(
"Transaction without shared object has been sequenced: {:?}",
certificate.transaction
certificate
);
return Ok(());
}

// Ensure it is the first time we see this certificate.
let transaction_digest = *certificate.digest();
if self._database.sequenced(
&transaction_digest,
certificate.transaction.shared_input_objects(),
)?[0]
if self
._database
.sequenced(&transaction_digest, certificate.shared_input_objects())?[0]
.is_some()
{
return Ok(());
Expand Down Expand Up @@ -750,11 +746,10 @@ impl AuthorityState {
pub async fn set_transaction_lock(
&self,
mutable_input_objects: &[ObjectRef],
tx_digest: TransactionDigest,
signed_transaction: SignedTransaction,
) -> Result<(), SuiError> {
self._database
.set_transaction_lock(mutable_input_objects, tx_digest, signed_transaction)
.set_transaction_lock(mutable_input_objects, signed_transaction)
}

/// Update state and signals that a new transactions has been processed
Expand Down
15 changes: 6 additions & 9 deletions sui_core/src/authority/authority_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,9 +459,9 @@ impl<const ALL_OBJ_VER: bool, S: Eq + Serialize + for<'de> Deserialize<'de>>
pub fn set_transaction_lock(
&self,
owned_input_objects: &[ObjectRef],
tx_digest: TransactionDigest,
transaction: TransactionEnvelope<S>,
) -> Result<(), SuiError> {
let tx_digest = *transaction.digest();
let lock_batch = self
.transaction_lock
.batch()
Expand Down Expand Up @@ -544,11 +544,8 @@ impl<const ALL_OBJ_VER: bool, S: Eq + Serialize + for<'de> Deserialize<'de>>
)?;

// Cleanup the lock of the shared objects.
let write_batch = self.remove_shared_objects_locks(
write_batch,
transaction_digest,
&certificate.transaction,
)?;
let write_batch =
self.remove_shared_objects_locks(write_batch, transaction_digest, certificate)?;

// Safe to unwrap since the "true" flag ensures we get a sequence value back.
self.batch_update_objects(
Expand Down Expand Up @@ -800,7 +797,7 @@ impl<const ALL_OBJ_VER: bool, S: Eq + Serialize + for<'de> Deserialize<'de>>
&self,
mut write_batch: DBBatch,
transaction_digest: &TransactionDigest,
transaction: &Transaction,
transaction: &CertifiedTransaction,
) -> SuiResult<DBBatch> {
let mut sequenced_to_delete = Vec::new();
let mut schedule_to_delete = Vec::new();
Expand All @@ -827,10 +824,10 @@ impl<const ALL_OBJ_VER: bool, S: Eq + Serialize + for<'de> Deserialize<'de>>
let certificate_to_write = std::iter::once((transaction_digest, &certificate));

// Make an iterator to update the locks of the transaction's shared objects.
let ids = certificate.transaction.shared_input_objects();
let ids = certificate.shared_input_objects();
let versions = self.schedule.multi_get(ids)?;

let ids = certificate.transaction.shared_input_objects();
let ids = certificate.shared_input_objects();
let (sequenced_to_write, schedule_to_write): (Vec<_>, Vec<_>) = ids
.zip(versions.iter())
.map(|(id, v)| {
Expand Down
Loading

1 comment on commit 8bb5bbf

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bench results

�[0m�[0m�[1m�[32m Finished�[0m release [optimized] target(s) in 0.35s
�[0m�[0m�[1m�[32m Running�[0m target/release/bench microbench throughput
�[2m2022-05-01T02:53:59.412429Z�[0m �[32m INFO�[0m �[2msui::benchmark�[0m�[2m:�[0m benchmark : Benchmark { committee_size: 1, send_timeout_us: 40000000, recv_timeout_us: 40000000, buffer_size: 650000, tcp_connections: 0, db_cpus: 1, use_move: false, batch_size: 2000, running_mode: LocalSingleValidatorThread, working_dir: None, bench_type: MicroBenchmark { host: "127.0.0.1", port: 9555, type_: Throughput { num_transactions: 100000 } } }
�[2m2022-05-01T02:53:59.412884Z�[0m �[32m INFO�[0m �[2msui::benchmark::validator_preparer�[0m�[2m:�[0m authority address hex: 974B62DE5727B140F633F932F9CE0A852274C3EC
�[2m2022-05-01T02:53:59.412963Z�[0m �[32m INFO�[0m �[2msui::benchmark::validator_preparer�[0m�[2m:�[0m Open database on path: "/tmp/DB_9A3F2C0195FC383D929A26E84735F7977F6ED38E"
�[2m2022-05-01T02:54:00.504020Z�[0m �[32m INFO�[0m �[2msui::benchmark::validator_preparer�[0m�[2m:�[0m Spawning a validator thread...
�[2m2022-05-01T02:54:00.504851Z�[0m �[32m INFO�[0m �[2msui_network::transport�[0m�[2m:�[0m Attempting to spawn server and bind to address... �[3maddress�[0m�[2m=�[0m127.0.0.1:9555
�[2m2022-05-01T02:54:00.504886Z�[0m �[32m INFO�[0m �[2msui_network::transport�[0m�[2m:�[0m Listening to TCP traffic on 127.0.0.1:9555
Throughout: 70916.8053681185 tps

Please sign in to comment.