ERPC - Geliştirilmiş Solana RPC

Dayanıklı Nonce Fan-out for SWQoS

Arka plan ve kullanım senaryo

In Solana İşlem gönderiyor, slot ilerlemesi, lider yerleştirme ve a-path sürekli olarak lideri en hızlı ulaşan değişimi gerçekleştiriyor. Bu, herhangi bir şeye özel değil. RPC Sağlayıcı veya hizmet göndermek; yapısal bir özelliktir Solana‘s execution model.
ERPC's SWQoS endpoint, Stake-weighted Quality of Service (Stake-weighted Quality of Service) dayalı liderler tarafından tahsis edilen öncelikli şerite enjekte edilen bir yol sunar.SWQoS) Bu öncelikli bant genişliği, dışsal olmayan şeritten yaklaşık 5× ve öncelikli ücret değerlendirmeden önce uygulanır.
Bu nedenle, bu nedenle, SWQoS endpoint, işlem göndermek için önemli bir seçenektir, ancak tek bir uç noktası her zaman en hızlı değildir. Aynı slot içinde bile geçici yol farklılıkları veya yük skew başka bir hızlı uç noktasının liderlik etmesine izin verebilir.
Bu özellikler göz önüne alındığında, aynı işlemi paralel olarak birden çok hızlı yollara göndermek ve ilk işlenmiş işlenmiş olanın tek bir rotaya güvenmek yerine etkili olabilir.
Ancak, aynı işlem birden fazla uç noktaya gönderilirken, sadece bir kez daha fazla kontrol olmadan gerçekleştireceğini garanti edemezsiniz. Bu kontrol olmadan Fan-out, iki uygulama veya kırık yeniden deneme kontrolüne yol açabilir.
Solana Bu mekanizma olarak Dayanıklı Nonce'ye göre, aynı imzalı işlemi tek bir zamana sınırlamak için birden fazla rotada göndermenize olanak sağlar.
Bu sayfa, fan-out işlemlerinin nasıl bir araya getirileceğini açıklıyor ERPC's SWQoS Diğer hızlı uç nokta ile RPC endpoints, Dayanıklı Nonce ile gönderilen işlem varsayılır.

Kapsam ve ön koşullar

Bu kılavuz, web3.js ile bir Dayanıklı Nonce hesabı oluşturmak ve onu işlem gönderme ve fan-out işlemleri için kullanmak kapsar.
Anlamaları Önlemler:
  • Dayanıklı Nonce işlemleri için, nonce değerini kullanma recentBlockhash ve yer nonceAdvance İlk öğretim olarak
  • Bir kez Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once Once nonceAdvance Uygulamalar, nonce daha sonra talimatları başarısız olsa bile tüketilebilir. Aynı çiğTx'i tekrar tekrarlayamazsınız.
  • Nonce hesabı oluşturma bir zaman kurulumudur ve genellikle yeniden kullanılabilir

Adım 1: Nonce otoritesini hazırlayın ve bağlantı kurun

Hiçbir otorite, hiçbir şeyin ilerletebileceği bir Keymate.
typescript
import {
  Connection,
  Keypair,
  SystemProgram,
  NONCE_ACCOUNT_LENGTH,
} from '@solana/web3.js'

const connection = new Connection(
  'https://<primary-rpc-endpoint>',
  'confirmed',
)

const nonceAuthority = Keypair.fromSecretKey(/* secret key */)
  • Hiçbir otorite idam edebilir nonceAdvance
  • Bu ücret ödemeci veya ayrı bir anahtar ayrımcı olabilir

2. Adım: Bir düğüm hesabı Keymate

Bir nonce hesabı ** Sistem Hesabı**.
typescript
const nonceAccount = Keypair.generate()
Bu Keymate için kullanılır:
  • Nonce değerini (göçümün yerine getirmek) recentBlockhash)
  • Sadece yaratım zamanında oturum açma
  • Daha sonra Güvenli depolama; günlük gönderi için gerekli değildir

Adım 3: Kirayı minimum hesaplayın

Nonce hesapları kiraya vermemelidir. Sert kod değerleri almayın; onları onlardan getir RPC.
typescript
const lamports =
  await connection.getMinimumBalanceForRentExemption(
    NONCE_ACCOUNT_LENGTH,
  )

Adım 4: Nonce hesabı oluşturun ve başlayın

createAccount + nonceInisalize tek bir işlemde oluşturun.
typescript
import { Transaction } from '@solana/web3.js'

const tx = new Transaction()

tx.add(
  SystemProgram.createAccount({
    fromPubkey: nonceAuthority.publicKey,
    newAccountPubkey: nonceAccount.publicKey,
    lamports,
    space: NONCE_ACCOUNT_LENGTH,
    programId: SystemProgram.programId,
  }),
  SystemProgram.nonceInitialize({
    noncePubkey: nonceAccount.publicKey,
    authorizedPubkey: nonceAuthority.publicKey,
  }),
)

// fee payer is the nonce authority
tx.feePayer = nonceAuthority.publicKey

// use a normal blockhash for initialization
const { blockhash, lastValidBlockHeight } =
  await connection.getLatestBlockhash('confirmed')

tx.recentBlockhash = blockhash

// sign with both the new account and the authority
tx.sign(nonceAccount, nonceAuthority)

const signature = await connection.sendRawTransaction(tx.serialize())
await connection.confirmTransaction(
  { signature, blockhash, lastValidBlockHeight },
  'confirmed',
)
Bunu kullanın nonceAccount.publicKey Sonraki gönderir.

Adım 5: Her gönderiden önce hiç bir şey Fetch

Her işlem için, mevcut nonce değeri getir.
typescript
import { NonceAccount } from '@solana/web3.js'

const { value, context } =
  await connection.getAccountInfoAndContext(
    nonceAccount.publicKey,
    'confirmed',
  )

if (!value) {
  throw new Error('Nonce account not found')
}

const nonce = NonceAccount.fromAccountData(value.data).nonce
const minContextSlot = context.slot
  • Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use Use nonce as recentBlockhash
  • context.slot Onaylamada kullanılır

Adım 6: Dayanıklı Nonce işlemi oluşturun

Dayanıklı Nonce işlemleri aşağıdaki koşulları yerine getirmeli:
  • recentBlockhash = nonce
  • İlk öğretim, ilk öğretimdir. nonceAdvance
typescript
import {
  TransactionMessage,
  VersionedTransaction,
} from '@solana/web3.js'

const instructions = [
  SystemProgram.nonceAdvance({
    noncePubkey: nonceAccount.publicKey,
    authorizedPubkey: nonceAuthority.publicKey,
  }),
  // add your real instructions after this
]

const message = new TransactionMessage({
  payerKey: nonceAuthority.publicKey,
  recentBlockhash: nonce,
  instructions,
}).compileToV0Message()

const tx = new VersionedTransaction(message)
tx.sign([nonceAuthority /* + other signers */])

const rawTx = tx.serialize()
Notlar:
  • ComputeBudget talimatları kullanıyorsanız, ** sonra gelmeliler. nonceAdvance
  • If nonceAdvance İlk değil, işlem reddedilecektir

Adım 7: Birden fazla RPC'ye Fan out

Aynı çiğTx'i aynı anda gönderin.
typescript
const endpoints = [
  'https://<erpc-swqos-fra>',
  'https://<backup-rpc-1>',
  'https://<backup-rpc-2>',
]

const results = await Promise.allSettled(
  endpoints.map((url) =>
    new Connection(url, 'confirmed').sendRawTransaction(rawTx, {
      skipPreflight: true,
      minContextSlot,
    }),
  ),
)

const success = results.find(
  (r): r is PromiseFulfilledResult<string> =>
    r.status === 'fulfilled',
)

if (!success) {
  throw new Error('All sends failed')
}

const signature = success.value
  • İmza uç noktalarında aynıdır
  • Başarılı bir gönderi ** değil ** bir onay

Adım 8: Dayanıklı Nonce ile Onay

Dayanıklı Nonce ile, onaydaki nonce bilgilerini içerir.
typescript
await connection.confirmTransaction(
  {
    signature,
    nonceAccountPubkey: nonceAccount.publicKey,
    nonceValue: nonce,
    minContextSlot,
  },
  'confirmed',
)
Onay başarılı olursa:
  • Hiçbir şey ilerlemektedir
  • Diğer RPC'lere gönderilen Copies geri döndü InvalidNonce

Sonraki gönderi gönderir

  • Onaydan sonra, taze bir düğüm getir
  • Aynı hamTx veya nonce değeri yeniden kullanmayın
  • Paralel akışlar için, ayrı nonce hesaplarını kullanın
Bir sonraki işlem için, güncel nonce toplayın ve işlemi aynı adımları kullanarak inşa edin.