transact-sys
SystemService::TransactionSys
struct SystemService::TransactionSys {
const psibase::AccountNumber service; // "transact-sys"
const uint64_t serviceFlags; // Flags this service must run with
init(...); // Only called once during chain initialization
startBlock(...); // Called by native code at the beginning of each block
runAs(...); // Run `action` using `action.sender's` authority
getTransaction(...); // Get the currently executing transaction
currentBlock(...); // Get the current block header
headBlock(...); // Get the head block header
headBlockTime(...); // Get the head block time
};
All transactions enter the chain through this service.
This privileged service dispatches top-level actions to other services, checks TAPoS, detects duplicate transactions, and checks authorizations using SystemService::AuthInterface.
Other services use it to get information about the chain, current block, and head block. They also use it to call actions using other accounts' authorities via runAs.
SystemService::TransactionSys::init
void SystemService::TransactionSys::init();
Only called once during chain initialization.
This enables the auth checking system. Before this point, TransactionSys
allows all transactions to execute without auth checks. After this point,
TransactionSys uses AuthInterface::checkAuthSys to authenticate
top-level actions and uses of runAs.
SystemService::TransactionSys::startBlock
void SystemService::TransactionSys::startBlock();
Called by native code at the beginning of each block.
SystemService::TransactionSys::runAs
std::vector<char> SystemService::TransactionSys::runAs(
psibase::Action action,
std::vector<ServiceMethod> allowedActions
);
Run action using action.sender's authority.
Also adds allowedActions to the list of actions that action.service
may perform on action.sender's behalf, for as long as this call to
runAs is in the call stack. Use "" for service in
allowedActions to allow use of any service (danger!). Use "" for
method to allow any method.
Returns the action's return value, if any.
This will succeed if any of the following are true:
getSender() == action.sender's authServicegetSender() == action.sender. Requiresaction.sender's authServiceto approve with flagAuthInterface::runAsRequesterReq(normally succeeds).- An existing
runAsis currently on the call stack,getSender()matchesaction.serviceon that earlier call, andactionmatchesallowedActionsfrom that same earlier call. Requiresaction.sender's authServiceto approve with flagAuthInterface::runAsMatchedReqifallowedActionsis empty (normally succeeds), orAuthInterface::runAsMatchedExpandedReqif not empty (normally fails). - All other cases, requires
action.sender's authServiceto approve with flagAuthInterface::runAsOtherReq(normally fails).
SystemService::TransactionSys::getTransaction
psibase::Transaction SystemService::TransactionSys::getTransaction() const;
Get the currently executing transaction.
SystemService::TransactionSys::currentBlock
psibase::BlockHeader SystemService::TransactionSys::currentBlock() const;
Get the current block header.
SystemService::TransactionSys::headBlock
psibase::BlockHeader SystemService::TransactionSys::headBlock() const;
Get the head block header.
This is not the currently executing block. See currentBlock.
SystemService::TransactionSys::headBlockTime
psibase::TimePointSec SystemService::TransactionSys::headBlockTime() const;
Get the head block time.
This is not the currently executing block time. TODO: remove
SystemService::ServiceMethod
struct SystemService::ServiceMethod {
psibase::AccountNumber service;
psibase::MethodNumber method;
};
Identify a service and method.
An empty service or method indicates a wildcard.
SystemService::AuthInterface
struct SystemService::AuthInterface {
const uint32_t readOnlyFlag; // See header
const uint32_t firstAuthFlag; // See header
const uint32_t requestMask; // Bits which identify kind of request
const uint32_t topActionReq; // Top-level action
const uint32_t runAsRequesterReq; // See header
const uint32_t runAsMatchedReq; // See header
const uint32_t runAsMatchedExpandedReq; // See header
const uint32_t runAsOtherReq; // See header
checkAuthSys(...); // Authenticate a top-level action or a `runAs` action
};
Authenticate actions.
TransactionSys calls into auth services using this interface
to authenticate senders of top-level actions and uses of
TransactionSys::runAs. Any service may become an auth
service by implementing AuthInterface. Any account may
select any service to be its authenticator. Be careful;
this allows that service to act on the account's behalf and
that service to authorize other accounts and services to
act on the account's behalf. It can also can lock out that
account. See AuthEcSys for a canonical example of
implementing this interface.
This interface can't authenticate non-top-level actions other
than TransactionSys::runAs actions. Most services shouldn't
call or implement AuthInterface; use getSender().
Auth services shouldn't inherit from this struct. Instead, they should define methods with matching signatures.
SystemService::AuthInterface::checkAuthSys
void SystemService::AuthInterface::checkAuthSys(
uint32_t flags,
psibase::AccountNumber requester,
psibase::Action action,
std::vector<ServiceMethod> allowedActions,
std::vector<psibase::Claim> claims
);
Authenticate a top-level action or a runAs action.
flags: One of the Req (request) constants, or'ed with 0 or more of the flag constantsrequester:""if this is a top-level action, or the sender of therunAsaction. This is often different fromaction.sender.action: Action to authenticateallowedActions: Argument fromrunAsclaims: Claims in transaction (e.g. public keys). Empty ifrunAs